Loading packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java +71 −61 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ import androidx.annotation.GuardedBy; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import com.android.internal.util.CollectionUtils; import com.android.settingslib.R; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; Loading Loading @@ -566,9 +567,6 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro AccessPoint accessPoint = getCachedOrCreate(entry.getValue(), cachedAccessPoints); if (mLastInfo != null && mLastNetworkInfo != null) { accessPoint.update(connectionConfig, mLastInfo, mLastNetworkInfo); } // Update the matching config if there is one, to populate saved network info accessPoint.update(configsByKey.get(entry.getKey())); Loading @@ -578,68 +576,20 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro List<ScanResult> cachedScanResults = new ArrayList<>(mScanResultCache.values()); // Add a unique Passpoint R1 AccessPoint for each Passpoint profile's FQDN. List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> passpointConfigsAndScans = mWifiManager.getAllMatchingWifiConfigs(cachedScanResults); Set<String> seenFQDNs = new ArraySet<>(); for (Pair<WifiConfiguration, Map<Integer, List<ScanResult>>> pairing : passpointConfigsAndScans) { WifiConfiguration config = pairing.first; List<ScanResult> scanResults = new ArrayList<>(); List<ScanResult> homeScans = pairing.second.get(WifiManager.PASSPOINT_HOME_NETWORK); List<ScanResult> roamingScans = pairing.second.get(WifiManager.PASSPOINT_ROAMING_NETWORK); if (homeScans == null) { homeScans = new ArrayList<>(); } if (roamingScans == null) { roamingScans = new ArrayList<>(); } // TODO(b/118705403): Differentiate home network vs roaming network for summary info if (!homeScans.isEmpty()) { scanResults.addAll(homeScans); } else { scanResults.addAll(roamingScans); } if (seenFQDNs.add(config.FQDN)) { int bestRssi = Integer.MIN_VALUE; for (ScanResult result : scanResults) { if (result.level >= bestRssi) { bestRssi = result.level; config.SSID = AccessPoint.convertToQuotedString(result.SSID); } } // Add a unique Passpoint AccessPoint for each Passpoint profile's FQDN. accessPoints.addAll(updatePasspointAccessPoints( mWifiManager.getAllMatchingWifiConfigs(cachedScanResults), cachedAccessPoints)); AccessPoint accessPoint = getCachedOrCreatePasspoint(scanResults, cachedAccessPoints, config); accessPoint.update(connectionConfig, mLastInfo, mLastNetworkInfo); accessPoints.add(accessPoint); } } // Add OSU Provider AccessPoints accessPoints.addAll(updateOsuAccessPoints( mWifiManager.getMatchingOsuProviders(cachedScanResults), cachedAccessPoints)); // Add Passpoint OSU Provider AccessPoints Map<OsuProvider, List<ScanResult>> providersAndScans = mWifiManager.getMatchingOsuProviders(cachedScanResults); Set<OsuProvider> alreadyProvisioned = mWifiManager .getMatchingPasspointConfigsForOsuProviders( providersAndScans.keySet()).keySet(); for (OsuProvider provider : providersAndScans.keySet()) { if (!alreadyProvisioned.contains(provider)) { AccessPoint accessPointOsu = getCachedOrCreateOsu(providersAndScans.get(provider), cachedAccessPoints, provider); accessPointOsu.update(connectionConfig, mLastInfo, mLastNetworkInfo); accessPoints.add(accessPointOsu); if (mLastInfo != null && mLastNetworkInfo != null) { for (AccessPoint ap : accessPoints) { ap.update(connectionConfig, mLastInfo, mLastNetworkInfo); } } // If there were no scan results, create an AP for the currently connected network (if // it exists). if (accessPoints.isEmpty() && connectionConfig != null) { Loading Loading @@ -686,7 +636,67 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro } @VisibleForTesting AccessPoint getCachedOrCreate( List<AccessPoint> updatePasspointAccessPoints( List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> passpointConfigsAndScans, List<AccessPoint> accessPointCache) { List<AccessPoint> accessPoints = new ArrayList<>(); Set<String> seenFQDNs = new ArraySet<>(); for (Pair<WifiConfiguration, Map<Integer, List<ScanResult>>> pairing : passpointConfigsAndScans) { WifiConfiguration config = pairing.first; if (seenFQDNs.add(config.FQDN)) { List<ScanResult> apScanResults = new ArrayList<>(); List<ScanResult> homeScans = pairing.second.get(WifiManager.PASSPOINT_HOME_NETWORK); List<ScanResult> roamingScans = pairing.second.get(WifiManager.PASSPOINT_ROAMING_NETWORK); // TODO(b/118705403): Differentiate home network vs roaming network for summary info if (!CollectionUtils.isEmpty(homeScans)) { apScanResults.addAll(homeScans); } else if (!CollectionUtils.isEmpty(roamingScans)) { apScanResults.addAll(roamingScans); } int bestRssi = Integer.MIN_VALUE; for (ScanResult result : apScanResults) { if (result.level >= bestRssi) { bestRssi = result.level; config.SSID = AccessPoint.convertToQuotedString(result.SSID); } } AccessPoint accessPoint = getCachedOrCreatePasspoint(apScanResults, accessPointCache, config); accessPoints.add(accessPoint); } } return accessPoints; } @VisibleForTesting List<AccessPoint> updateOsuAccessPoints( Map<OsuProvider, List<ScanResult>> providersAndScans, List<AccessPoint> accessPointCache) { List<AccessPoint> accessPoints = new ArrayList<>(); Set<OsuProvider> alreadyProvisioned = mWifiManager .getMatchingPasspointConfigsForOsuProviders( providersAndScans.keySet()).keySet(); for (OsuProvider provider : providersAndScans.keySet()) { if (!alreadyProvisioned.contains(provider)) { AccessPoint accessPointOsu = getCachedOrCreateOsu(providersAndScans.get(provider), accessPointCache, provider); accessPoints.add(accessPointOsu); } } return accessPoints; } private AccessPoint getCachedOrCreate( List<ScanResult> scanResults, List<AccessPoint> cache) { AccessPoint accessPoint = getCachedByKey(cache, AccessPoint.getKey(scanResults.get(0))); Loading packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java +235 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading @@ -48,11 +49,15 @@ import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.net.wifi.WifiNetworkScoreCache; import android.net.wifi.WifiSsid; import android.net.wifi.hotspot2.OsuProvider; import android.net.wifi.hotspot2.PasspointConfiguration; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.SystemClock; import android.provider.Settings; import android.util.ArraySet; import android.util.Pair; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; Loading @@ -74,7 +79,10 @@ import org.mockito.stubbing.Answer; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; Loading @@ -94,6 +102,8 @@ public class WifiTrackerTest { private static final int RSSI_1 = -30; private static final byte SCORE_1 = 10; private static final int BADGE_1 = AccessPoint.Speed.MODERATE; private static final String FQDN_1 = "fqdn1"; private static final String PROVIDER_FRIENDLY_NAME_1 = "providerFriendlyName1"; private static final String SSID_2 = "ssid2"; private static final String BSSID_2 = "AA:AA:AA:AA:AA:AA"; Loading @@ -102,6 +112,8 @@ public class WifiTrackerTest { private static final int RSSI_2 = -30; private static final byte SCORE_2 = 15; private static final int BADGE_2 = AccessPoint.Speed.FAST; private static final String FQDN_2 = "fqdn2"; private static final String PROVIDER_FRIENDLY_NAME_2 = "providerFriendlyName2"; private static final String SSID_3 = "ssid3"; private static final String BSSID_3 = "CC:00:00:00:00:00"; Loading Loading @@ -271,6 +283,61 @@ public class WifiTrackerTest { 0 /* microsecond timestamp */); } private static WifiConfiguration buildPasspointConfiguration(String fqdn, String friendlyName) { WifiConfiguration config = spy(new WifiConfiguration()); config.FQDN = fqdn; config.providerFriendlyName = friendlyName; when(config.isPasspoint()).thenReturn(true); return config; } private List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> createPasspointMatchingWifiConfigsWithDuplicates() { List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> matchingList = new ArrayList<>(); Map<Integer, List<ScanResult>> mapping = new HashMap<>(); mapping.put(WifiManager.PASSPOINT_HOME_NETWORK, Arrays.asList(buildScanResult1())); WifiConfiguration passpointConfig1 = buildPasspointConfiguration(FQDN_1, PROVIDER_FRIENDLY_NAME_1); WifiConfiguration passpointConfig2 = buildPasspointConfiguration(FQDN_2, PROVIDER_FRIENDLY_NAME_2); matchingList.add(new Pair(passpointConfig1, mapping)); matchingList.add(new Pair(passpointConfig1, mapping)); matchingList.add(new Pair(passpointConfig2, mapping)); matchingList.add(new Pair(passpointConfig2, mapping)); return matchingList; } private List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> createPasspointMatchingWifiConfigWithScanResults( List<ScanResult> homeList, List<ScanResult> roamingList) { List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> matchingList = new ArrayList<>(); Map<Integer, List<ScanResult>> mapping = new HashMap<>(); if (homeList != null) { mapping.put(WifiManager.PASSPOINT_HOME_NETWORK, homeList); } if (roamingList != null) { mapping.put(WifiManager.PASSPOINT_ROAMING_NETWORK, roamingList); } matchingList.add(new Pair(buildPasspointConfiguration(FQDN_1, PROVIDER_FRIENDLY_NAME_1), mapping)); return matchingList; } private static OsuProvider buildOsuProvider(String friendlyName) { Map<String, String> friendlyNames = new HashMap<>(); friendlyNames.put("en", friendlyName); return new OsuProvider(null, friendlyNames, null, null, null, null, null); } private WifiTracker createTrackerWithImmediateBroadcastsAndInjectInitialScanResults( Intent ... intents) throws InterruptedException { Loading Loading @@ -926,4 +993,172 @@ public class WifiTrackerTest { 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. */ @Test public void updatePasspointAccessPoints_returnedAccessPointsArePasspoint() { WifiTracker tracker = createMockedWifiTracker(); List<AccessPoint> passpointAccessPoints = tracker.updatePasspointAccessPoints( createPasspointMatchingWifiConfigsWithDuplicates(), new ArrayList<>()); assertTrue(passpointAccessPoints.size() != 0); for (AccessPoint ap : passpointAccessPoints) { assertTrue(ap.isPasspoint()); } } /** * Verifies that updatePasspointAccessPoints will return the same amount of AccessPoints as * unique WifiConfigurations, even if duplicate FQDNs exist. */ @Test public void updatePasspointAccessPoints_ignoresDuplicateFQDNs() { WifiTracker tracker = createMockedWifiTracker(); // Process matching list of four configs with two duplicate FQDNs. List<AccessPoint> passpointAccessPoints = tracker.updatePasspointAccessPoints( createPasspointMatchingWifiConfigsWithDuplicates(), new ArrayList<>()); // Should have 2 APs with unique FQDNs, ignoring the 2 duplicate FQDNs. assertThat(passpointAccessPoints).hasSize(2); Set<String> fqdns = new ArraySet<>(Arrays.asList(FQDN_1, FQDN_2)); assertTrue(fqdns.remove(passpointAccessPoints.get(0).getConfig().FQDN)); assertTrue(fqdns.remove(passpointAccessPoints.get(1).getConfig().FQDN)); } /** * Verifies that updatePasspointAccessPoints will return matching cached APs and update their * scan results instead of creating new APs. */ @Test public void updatePasspointAccessPoints_usesCachedAccessPoints() { WifiTracker tracker = createMockedWifiTracker(); ScanResult result = buildScanResult1(); List<AccessPoint> passpointAccessPointsFirstUpdate = tracker.updatePasspointAccessPoints( createPasspointMatchingWifiConfigWithScanResults(Arrays.asList(result), null), new ArrayList<>()); List<AccessPoint> cachedAccessPoints = new ArrayList<>(passpointAccessPointsFirstUpdate); int prevRssi = result.level; int newRssi = prevRssi + 10; result.level = newRssi; List<AccessPoint> passpointAccessPointsSecondUpdate = tracker.updatePasspointAccessPoints( createPasspointMatchingWifiConfigWithScanResults(Arrays.asList(result), null), cachedAccessPoints); // Verify second update AP is the same object as the first update AP assertThat(passpointAccessPointsFirstUpdate.get(0)) .isSameAs(passpointAccessPointsSecondUpdate.get(0)); // Verify second update AP has the average of the first and second update RSSIs assertThat(passpointAccessPointsSecondUpdate.get(0).getRssi()) .isEqualTo((prevRssi + newRssi) / 2); } /** * Verifies that updateOsuAccessPoints will only return AccessPoints whose * isOsuProvider() evaluates as true. */ @Test public void updateOsuAccessPoints_returnedAccessPointsAreOsuProviders() { WifiTracker tracker = createMockedWifiTracker(); Map<OsuProvider, List<ScanResult>> providersAndScans = new HashMap<>(); providersAndScans.put( buildOsuProvider(PROVIDER_FRIENDLY_NAME_1), Arrays.asList(buildScanResult1())); providersAndScans.put( buildOsuProvider(PROVIDER_FRIENDLY_NAME_2), Arrays.asList(buildScanResult2())); List<AccessPoint> osuAccessPoints = tracker.updateOsuAccessPoints( providersAndScans, new ArrayList<>()); assertThat(osuAccessPoints).hasSize(2); for (AccessPoint ap: osuAccessPoints) { assertThat(ap.isOsuProvider()).isTrue(); } } /** * Verifies that updateOsuAccessPoints will not return Osu AccessPoints for already provisioned * networks */ @Test public void updateOsuAccessPoints_doesNotReturnAlreadyProvisionedOsuAccessPoints() { WifiTracker tracker = createMockedWifiTracker(); // Start with two Osu Providers Map<OsuProvider, List<ScanResult>> providersAndScans = new HashMap<>(); providersAndScans.put( buildOsuProvider(PROVIDER_FRIENDLY_NAME_1), Arrays.asList(buildScanResult1())); providersAndScans.put( buildOsuProvider(PROVIDER_FRIENDLY_NAME_2), Arrays.asList(buildScanResult2())); // First update List<AccessPoint> osuAccessPoints = tracker.updateOsuAccessPoints( providersAndScans, new ArrayList<>()); // Make sure both Osu Providers' APs are returned assertThat(osuAccessPoints).hasSize(2); List<String> friendlyNames = Arrays.asList( osuAccessPoints.get(0).getTitle(), osuAccessPoints.get(1).getTitle()); assertThat(friendlyNames) .containsExactly(PROVIDER_FRIENDLY_NAME_1, PROVIDER_FRIENDLY_NAME_2); // Simulate Osu Provider 1 being provisioned Map<OsuProvider, PasspointConfiguration> matchingPasspointConfigForOsuProvider = new HashMap<>(); matchingPasspointConfigForOsuProvider.put(buildOsuProvider(PROVIDER_FRIENDLY_NAME_1), null); when(mockWifiManager.getMatchingPasspointConfigsForOsuProviders(any())).thenReturn( matchingPasspointConfigForOsuProvider); // Second update osuAccessPoints = tracker.updateOsuAccessPoints( providersAndScans, new ArrayList<>()); // Returned AP should only be for Osu Provider 2 assertThat(osuAccessPoints).hasSize(1); assertThat(osuAccessPoints.get(0).getTitle()).isEqualTo(PROVIDER_FRIENDLY_NAME_2); } /** * Verifies that updateOsuAccessPoints will return matching cached APs and update their * scan results instead of creating new APs. */ @Test public void updateOsuAccessPoints_usesCachedAccessPoints() { WifiTracker tracker = createMockedWifiTracker(); ScanResult result = buildScanResult1(); Map<OsuProvider, List<ScanResult>> providersAndScans = new HashMap<>(); providersAndScans.put( buildOsuProvider(PROVIDER_FRIENDLY_NAME_1), Arrays.asList(result)); List<AccessPoint> osuAccessPointsFirstUpdate = tracker.updateOsuAccessPoints( providersAndScans, new ArrayList<>()); List<AccessPoint> cachedAccessPoints = new ArrayList<>(osuAccessPointsFirstUpdate); // New RSSI for second update int prevRssi = result.level; int newRssi = prevRssi + 10; result.level = newRssi; List<AccessPoint> osuAccessPointsSecondUpdate = tracker.updateOsuAccessPoints( providersAndScans, cachedAccessPoints); // Verify second update AP is the same object as the first update AP assertTrue(osuAccessPointsFirstUpdate.get(0) == osuAccessPointsSecondUpdate.get(0)); // Verify second update AP has the average of the first and second update RSSIs assertThat(osuAccessPointsSecondUpdate.get(0).getRssi()) .isEqualTo((prevRssi + newRssi) / 2); } } Loading
packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java +71 −61 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ import androidx.annotation.GuardedBy; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import com.android.internal.util.CollectionUtils; import com.android.settingslib.R; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; Loading Loading @@ -566,9 +567,6 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro AccessPoint accessPoint = getCachedOrCreate(entry.getValue(), cachedAccessPoints); if (mLastInfo != null && mLastNetworkInfo != null) { accessPoint.update(connectionConfig, mLastInfo, mLastNetworkInfo); } // Update the matching config if there is one, to populate saved network info accessPoint.update(configsByKey.get(entry.getKey())); Loading @@ -578,68 +576,20 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro List<ScanResult> cachedScanResults = new ArrayList<>(mScanResultCache.values()); // Add a unique Passpoint R1 AccessPoint for each Passpoint profile's FQDN. List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> passpointConfigsAndScans = mWifiManager.getAllMatchingWifiConfigs(cachedScanResults); Set<String> seenFQDNs = new ArraySet<>(); for (Pair<WifiConfiguration, Map<Integer, List<ScanResult>>> pairing : passpointConfigsAndScans) { WifiConfiguration config = pairing.first; List<ScanResult> scanResults = new ArrayList<>(); List<ScanResult> homeScans = pairing.second.get(WifiManager.PASSPOINT_HOME_NETWORK); List<ScanResult> roamingScans = pairing.second.get(WifiManager.PASSPOINT_ROAMING_NETWORK); if (homeScans == null) { homeScans = new ArrayList<>(); } if (roamingScans == null) { roamingScans = new ArrayList<>(); } // TODO(b/118705403): Differentiate home network vs roaming network for summary info if (!homeScans.isEmpty()) { scanResults.addAll(homeScans); } else { scanResults.addAll(roamingScans); } if (seenFQDNs.add(config.FQDN)) { int bestRssi = Integer.MIN_VALUE; for (ScanResult result : scanResults) { if (result.level >= bestRssi) { bestRssi = result.level; config.SSID = AccessPoint.convertToQuotedString(result.SSID); } } // Add a unique Passpoint AccessPoint for each Passpoint profile's FQDN. accessPoints.addAll(updatePasspointAccessPoints( mWifiManager.getAllMatchingWifiConfigs(cachedScanResults), cachedAccessPoints)); AccessPoint accessPoint = getCachedOrCreatePasspoint(scanResults, cachedAccessPoints, config); accessPoint.update(connectionConfig, mLastInfo, mLastNetworkInfo); accessPoints.add(accessPoint); } } // Add OSU Provider AccessPoints accessPoints.addAll(updateOsuAccessPoints( mWifiManager.getMatchingOsuProviders(cachedScanResults), cachedAccessPoints)); // Add Passpoint OSU Provider AccessPoints Map<OsuProvider, List<ScanResult>> providersAndScans = mWifiManager.getMatchingOsuProviders(cachedScanResults); Set<OsuProvider> alreadyProvisioned = mWifiManager .getMatchingPasspointConfigsForOsuProviders( providersAndScans.keySet()).keySet(); for (OsuProvider provider : providersAndScans.keySet()) { if (!alreadyProvisioned.contains(provider)) { AccessPoint accessPointOsu = getCachedOrCreateOsu(providersAndScans.get(provider), cachedAccessPoints, provider); accessPointOsu.update(connectionConfig, mLastInfo, mLastNetworkInfo); accessPoints.add(accessPointOsu); if (mLastInfo != null && mLastNetworkInfo != null) { for (AccessPoint ap : accessPoints) { ap.update(connectionConfig, mLastInfo, mLastNetworkInfo); } } // If there were no scan results, create an AP for the currently connected network (if // it exists). if (accessPoints.isEmpty() && connectionConfig != null) { Loading Loading @@ -686,7 +636,67 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro } @VisibleForTesting AccessPoint getCachedOrCreate( List<AccessPoint> updatePasspointAccessPoints( List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> passpointConfigsAndScans, List<AccessPoint> accessPointCache) { List<AccessPoint> accessPoints = new ArrayList<>(); Set<String> seenFQDNs = new ArraySet<>(); for (Pair<WifiConfiguration, Map<Integer, List<ScanResult>>> pairing : passpointConfigsAndScans) { WifiConfiguration config = pairing.first; if (seenFQDNs.add(config.FQDN)) { List<ScanResult> apScanResults = new ArrayList<>(); List<ScanResult> homeScans = pairing.second.get(WifiManager.PASSPOINT_HOME_NETWORK); List<ScanResult> roamingScans = pairing.second.get(WifiManager.PASSPOINT_ROAMING_NETWORK); // TODO(b/118705403): Differentiate home network vs roaming network for summary info if (!CollectionUtils.isEmpty(homeScans)) { apScanResults.addAll(homeScans); } else if (!CollectionUtils.isEmpty(roamingScans)) { apScanResults.addAll(roamingScans); } int bestRssi = Integer.MIN_VALUE; for (ScanResult result : apScanResults) { if (result.level >= bestRssi) { bestRssi = result.level; config.SSID = AccessPoint.convertToQuotedString(result.SSID); } } AccessPoint accessPoint = getCachedOrCreatePasspoint(apScanResults, accessPointCache, config); accessPoints.add(accessPoint); } } return accessPoints; } @VisibleForTesting List<AccessPoint> updateOsuAccessPoints( Map<OsuProvider, List<ScanResult>> providersAndScans, List<AccessPoint> accessPointCache) { List<AccessPoint> accessPoints = new ArrayList<>(); Set<OsuProvider> alreadyProvisioned = mWifiManager .getMatchingPasspointConfigsForOsuProviders( providersAndScans.keySet()).keySet(); for (OsuProvider provider : providersAndScans.keySet()) { if (!alreadyProvisioned.contains(provider)) { AccessPoint accessPointOsu = getCachedOrCreateOsu(providersAndScans.get(provider), accessPointCache, provider); accessPoints.add(accessPointOsu); } } return accessPoints; } private AccessPoint getCachedOrCreate( List<ScanResult> scanResults, List<AccessPoint> cache) { AccessPoint accessPoint = getCachedByKey(cache, AccessPoint.getKey(scanResults.get(0))); Loading
packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java +235 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading @@ -48,11 +49,15 @@ import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.net.wifi.WifiNetworkScoreCache; import android.net.wifi.WifiSsid; import android.net.wifi.hotspot2.OsuProvider; import android.net.wifi.hotspot2.PasspointConfiguration; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.SystemClock; import android.provider.Settings; import android.util.ArraySet; import android.util.Pair; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; Loading @@ -74,7 +79,10 @@ import org.mockito.stubbing.Answer; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; Loading @@ -94,6 +102,8 @@ public class WifiTrackerTest { private static final int RSSI_1 = -30; private static final byte SCORE_1 = 10; private static final int BADGE_1 = AccessPoint.Speed.MODERATE; private static final String FQDN_1 = "fqdn1"; private static final String PROVIDER_FRIENDLY_NAME_1 = "providerFriendlyName1"; private static final String SSID_2 = "ssid2"; private static final String BSSID_2 = "AA:AA:AA:AA:AA:AA"; Loading @@ -102,6 +112,8 @@ public class WifiTrackerTest { private static final int RSSI_2 = -30; private static final byte SCORE_2 = 15; private static final int BADGE_2 = AccessPoint.Speed.FAST; private static final String FQDN_2 = "fqdn2"; private static final String PROVIDER_FRIENDLY_NAME_2 = "providerFriendlyName2"; private static final String SSID_3 = "ssid3"; private static final String BSSID_3 = "CC:00:00:00:00:00"; Loading Loading @@ -271,6 +283,61 @@ public class WifiTrackerTest { 0 /* microsecond timestamp */); } private static WifiConfiguration buildPasspointConfiguration(String fqdn, String friendlyName) { WifiConfiguration config = spy(new WifiConfiguration()); config.FQDN = fqdn; config.providerFriendlyName = friendlyName; when(config.isPasspoint()).thenReturn(true); return config; } private List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> createPasspointMatchingWifiConfigsWithDuplicates() { List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> matchingList = new ArrayList<>(); Map<Integer, List<ScanResult>> mapping = new HashMap<>(); mapping.put(WifiManager.PASSPOINT_HOME_NETWORK, Arrays.asList(buildScanResult1())); WifiConfiguration passpointConfig1 = buildPasspointConfiguration(FQDN_1, PROVIDER_FRIENDLY_NAME_1); WifiConfiguration passpointConfig2 = buildPasspointConfiguration(FQDN_2, PROVIDER_FRIENDLY_NAME_2); matchingList.add(new Pair(passpointConfig1, mapping)); matchingList.add(new Pair(passpointConfig1, mapping)); matchingList.add(new Pair(passpointConfig2, mapping)); matchingList.add(new Pair(passpointConfig2, mapping)); return matchingList; } private List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> createPasspointMatchingWifiConfigWithScanResults( List<ScanResult> homeList, List<ScanResult> roamingList) { List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> matchingList = new ArrayList<>(); Map<Integer, List<ScanResult>> mapping = new HashMap<>(); if (homeList != null) { mapping.put(WifiManager.PASSPOINT_HOME_NETWORK, homeList); } if (roamingList != null) { mapping.put(WifiManager.PASSPOINT_ROAMING_NETWORK, roamingList); } matchingList.add(new Pair(buildPasspointConfiguration(FQDN_1, PROVIDER_FRIENDLY_NAME_1), mapping)); return matchingList; } private static OsuProvider buildOsuProvider(String friendlyName) { Map<String, String> friendlyNames = new HashMap<>(); friendlyNames.put("en", friendlyName); return new OsuProvider(null, friendlyNames, null, null, null, null, null); } private WifiTracker createTrackerWithImmediateBroadcastsAndInjectInitialScanResults( Intent ... intents) throws InterruptedException { Loading Loading @@ -926,4 +993,172 @@ public class WifiTrackerTest { 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. */ @Test public void updatePasspointAccessPoints_returnedAccessPointsArePasspoint() { WifiTracker tracker = createMockedWifiTracker(); List<AccessPoint> passpointAccessPoints = tracker.updatePasspointAccessPoints( createPasspointMatchingWifiConfigsWithDuplicates(), new ArrayList<>()); assertTrue(passpointAccessPoints.size() != 0); for (AccessPoint ap : passpointAccessPoints) { assertTrue(ap.isPasspoint()); } } /** * Verifies that updatePasspointAccessPoints will return the same amount of AccessPoints as * unique WifiConfigurations, even if duplicate FQDNs exist. */ @Test public void updatePasspointAccessPoints_ignoresDuplicateFQDNs() { WifiTracker tracker = createMockedWifiTracker(); // Process matching list of four configs with two duplicate FQDNs. List<AccessPoint> passpointAccessPoints = tracker.updatePasspointAccessPoints( createPasspointMatchingWifiConfigsWithDuplicates(), new ArrayList<>()); // Should have 2 APs with unique FQDNs, ignoring the 2 duplicate FQDNs. assertThat(passpointAccessPoints).hasSize(2); Set<String> fqdns = new ArraySet<>(Arrays.asList(FQDN_1, FQDN_2)); assertTrue(fqdns.remove(passpointAccessPoints.get(0).getConfig().FQDN)); assertTrue(fqdns.remove(passpointAccessPoints.get(1).getConfig().FQDN)); } /** * Verifies that updatePasspointAccessPoints will return matching cached APs and update their * scan results instead of creating new APs. */ @Test public void updatePasspointAccessPoints_usesCachedAccessPoints() { WifiTracker tracker = createMockedWifiTracker(); ScanResult result = buildScanResult1(); List<AccessPoint> passpointAccessPointsFirstUpdate = tracker.updatePasspointAccessPoints( createPasspointMatchingWifiConfigWithScanResults(Arrays.asList(result), null), new ArrayList<>()); List<AccessPoint> cachedAccessPoints = new ArrayList<>(passpointAccessPointsFirstUpdate); int prevRssi = result.level; int newRssi = prevRssi + 10; result.level = newRssi; List<AccessPoint> passpointAccessPointsSecondUpdate = tracker.updatePasspointAccessPoints( createPasspointMatchingWifiConfigWithScanResults(Arrays.asList(result), null), cachedAccessPoints); // Verify second update AP is the same object as the first update AP assertThat(passpointAccessPointsFirstUpdate.get(0)) .isSameAs(passpointAccessPointsSecondUpdate.get(0)); // Verify second update AP has the average of the first and second update RSSIs assertThat(passpointAccessPointsSecondUpdate.get(0).getRssi()) .isEqualTo((prevRssi + newRssi) / 2); } /** * Verifies that updateOsuAccessPoints will only return AccessPoints whose * isOsuProvider() evaluates as true. */ @Test public void updateOsuAccessPoints_returnedAccessPointsAreOsuProviders() { WifiTracker tracker = createMockedWifiTracker(); Map<OsuProvider, List<ScanResult>> providersAndScans = new HashMap<>(); providersAndScans.put( buildOsuProvider(PROVIDER_FRIENDLY_NAME_1), Arrays.asList(buildScanResult1())); providersAndScans.put( buildOsuProvider(PROVIDER_FRIENDLY_NAME_2), Arrays.asList(buildScanResult2())); List<AccessPoint> osuAccessPoints = tracker.updateOsuAccessPoints( providersAndScans, new ArrayList<>()); assertThat(osuAccessPoints).hasSize(2); for (AccessPoint ap: osuAccessPoints) { assertThat(ap.isOsuProvider()).isTrue(); } } /** * Verifies that updateOsuAccessPoints will not return Osu AccessPoints for already provisioned * networks */ @Test public void updateOsuAccessPoints_doesNotReturnAlreadyProvisionedOsuAccessPoints() { WifiTracker tracker = createMockedWifiTracker(); // Start with two Osu Providers Map<OsuProvider, List<ScanResult>> providersAndScans = new HashMap<>(); providersAndScans.put( buildOsuProvider(PROVIDER_FRIENDLY_NAME_1), Arrays.asList(buildScanResult1())); providersAndScans.put( buildOsuProvider(PROVIDER_FRIENDLY_NAME_2), Arrays.asList(buildScanResult2())); // First update List<AccessPoint> osuAccessPoints = tracker.updateOsuAccessPoints( providersAndScans, new ArrayList<>()); // Make sure both Osu Providers' APs are returned assertThat(osuAccessPoints).hasSize(2); List<String> friendlyNames = Arrays.asList( osuAccessPoints.get(0).getTitle(), osuAccessPoints.get(1).getTitle()); assertThat(friendlyNames) .containsExactly(PROVIDER_FRIENDLY_NAME_1, PROVIDER_FRIENDLY_NAME_2); // Simulate Osu Provider 1 being provisioned Map<OsuProvider, PasspointConfiguration> matchingPasspointConfigForOsuProvider = new HashMap<>(); matchingPasspointConfigForOsuProvider.put(buildOsuProvider(PROVIDER_FRIENDLY_NAME_1), null); when(mockWifiManager.getMatchingPasspointConfigsForOsuProviders(any())).thenReturn( matchingPasspointConfigForOsuProvider); // Second update osuAccessPoints = tracker.updateOsuAccessPoints( providersAndScans, new ArrayList<>()); // Returned AP should only be for Osu Provider 2 assertThat(osuAccessPoints).hasSize(1); assertThat(osuAccessPoints.get(0).getTitle()).isEqualTo(PROVIDER_FRIENDLY_NAME_2); } /** * Verifies that updateOsuAccessPoints will return matching cached APs and update their * scan results instead of creating new APs. */ @Test public void updateOsuAccessPoints_usesCachedAccessPoints() { WifiTracker tracker = createMockedWifiTracker(); ScanResult result = buildScanResult1(); Map<OsuProvider, List<ScanResult>> providersAndScans = new HashMap<>(); providersAndScans.put( buildOsuProvider(PROVIDER_FRIENDLY_NAME_1), Arrays.asList(result)); List<AccessPoint> osuAccessPointsFirstUpdate = tracker.updateOsuAccessPoints( providersAndScans, new ArrayList<>()); List<AccessPoint> cachedAccessPoints = new ArrayList<>(osuAccessPointsFirstUpdate); // New RSSI for second update int prevRssi = result.level; int newRssi = prevRssi + 10; result.level = newRssi; List<AccessPoint> osuAccessPointsSecondUpdate = tracker.updateOsuAccessPoints( providersAndScans, cachedAccessPoints); // Verify second update AP is the same object as the first update AP assertTrue(osuAccessPointsFirstUpdate.get(0) == osuAccessPointsSecondUpdate.get(0)); // Verify second update AP has the average of the first and second update RSSIs assertThat(osuAccessPointsSecondUpdate.get(0).getRssi()) .isEqualTo((prevRssi + newRssi) / 2); } }