summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/java/com/android/server/wifi/WifiConfigManager.java60
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java65
2 files changed, 123 insertions, 2 deletions
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index 4b622bf31..1fdabfa07 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -61,6 +61,7 @@ import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Collection;
@@ -212,6 +213,12 @@ public class WifiConfigManager {
* Maximum age of scan results that can be used for averaging out RSSI value.
*/
private static final int SCAN_RESULT_MAXIMUM_AGE_MS = 40000;
+
+ /**
+ * Maximum age of frequencies last seen to be included in pno scans. (30 days)
+ */
+ @VisibleForTesting
+ public static final long MAX_PNO_SCAN_FREQUENCY_AGE_MS = (long) 1000 * 3600 * 24 * 30;
/**
* General sorting algorithm of all networks for scanning purposes:
* Place the configurations in descending order of their |numAssociation| values. If networks
@@ -278,6 +285,7 @@ public class WifiConfigManager {
* Number of channels to scan for during partial scans initiated while connected.
*/
private final int mMaxNumActiveChannelsForPartialScans;
+
/**
* Verbose logging flag. Toggled by developer options.
*/
@@ -374,7 +382,6 @@ public class WifiConfigManager {
R.bool.config_wifi_only_link_same_credential_configurations);
mMaxNumActiveChannelsForPartialScans = mContext.getResources().getInteger(
R.integer.config_wifi_framework_associated_partial_scan_max_num_active_channels);
-
try {
mSystemUiUid = mContext.getPackageManager().getPackageUidAsUser(SYSUI_PACKAGE_NAME,
PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
@@ -2358,6 +2365,42 @@ public class WifiConfigManager {
}
/**
+ * Retrieve a set of channels on which AP's for the provided network was seen using the
+ * internal ScanResult's cache {@link #mScanDetailCaches}. This is used to reduced the list
+ * of frequencies for pno scans.
+ *
+ * @param networkId network ID corresponding to the network.
+ * @param ageInMillis only consider scan details whose timestamps are earlier than this.
+ * @return Set containing the frequencies on which this network was found, null if the network
+ * was not found or there are no associated scan details in the cache.
+ */
+ private Set<Integer> fetchChannelSetForNetworkForPnoScan(int networkId, long ageInMillis) {
+ WifiConfiguration config = getInternalConfiguredNetwork(networkId);
+ if (config == null) {
+ return null;
+ }
+ ScanDetailCache scanDetailCache = getScanDetailCacheForNetwork(networkId);
+ if (scanDetailCache == null) {
+ return null;
+ }
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, new StringBuilder("fetchChannelSetForNetworkForPnoScan ageInMillis ")
+ .append(ageInMillis)
+ .append(" for ")
+ .append(config.configKey())
+ .append(" bssids " + scanDetailCache.size())
+ .toString());
+ }
+ Set<Integer> channelSet = new HashSet<>();
+ long nowInMillis = mClock.getWallClockMillis();
+
+ // Add channels for the network to the output.
+ addToChannelSetForNetworkFromScanDetailCache(channelSet, scanDetailCache, nowInMillis,
+ ageInMillis, Integer.MAX_VALUE);
+ return channelSet;
+ }
+
+ /**
* Retrieves a list of all the saved networks before enabling disconnected/connected PNO.
*
* PNO network list sent to the firmware has limited size. If there are a lot of saved
@@ -2384,7 +2427,20 @@ public class WifiConfigManager {
Collections.sort(networks, sScanListComparator);
// The most frequently connected network has the highest priority now.
for (WifiConfiguration config : networks) {
- pnoList.add(WifiConfigurationUtil.createPnoNetwork(config));
+ WifiScanner.PnoSettings.PnoNetwork pnoNetwork =
+ WifiConfigurationUtil.createPnoNetwork(config);
+ Set<Integer> channelSet = fetchChannelSetForNetworkForPnoScan(config.networkId,
+ MAX_PNO_SCAN_FREQUENCY_AGE_MS);
+ if (channelSet != null) {
+ pnoNetwork.frequencies = channelSet.stream()
+ .mapToInt(Integer::intValue)
+ .toArray();
+ }
+ pnoList.add(pnoNetwork);
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "retrievePnoNetworkList " + pnoNetwork.ssid + ":"
+ + Arrays.toString(pnoNetwork.frequencies));
+ }
}
return pnoList;
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
index 40f9f459d..05d79ed65 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -97,6 +97,10 @@ public class WifiConfigManagerTest {
private static final int TEST_STATIC_PROXY_PORT_2 = 3000;
private static final String TEST_STATIC_PROXY_EXCLUSION_LIST_2 = "";
private static final String TEST_PAC_PROXY_LOCATION_2 = "http://blah";
+ private static final int TEST_RSSI = -50;
+ private static final int TEST_FREQUENCY_1 = 2412;
+ private static final int TEST_FREQUENCY_2 = 5180;
+ private static final int TEST_FREQUENCY_3 = 5240;
@Mock private Context mContext;
@Mock private Clock mClock;
@@ -1597,6 +1601,67 @@ public class WifiConfigManagerTest {
}
/**
+ * Verifies frequencies are populated correctly for pno networks.
+ * {@link WifiConfigManager#retrievePnoNetworkList()}.
+ */
+ @Test
+ public void testRetrievePnoListFrequencies() {
+ // Create and add 3 networks.
+ WifiConfiguration network1 = WifiConfigurationTestUtil.createEapNetwork();
+ WifiConfiguration network2 = WifiConfigurationTestUtil.createPskNetwork();
+ verifyAddNetworkToWifiConfigManager(network1);
+ verifyAddNetworkToWifiConfigManager(network2);
+
+ // Enable all of them.
+ assertTrue(mWifiConfigManager.enableNetwork(network1.networkId, false, TEST_CREATOR_UID));
+ assertTrue(mWifiConfigManager.enableNetwork(network2.networkId, false, TEST_CREATOR_UID));
+ assertTrue(mWifiConfigManager.updateNetworkAfterConnect(network1.networkId));
+
+ // Retrieve the Pno network list & verify the order of the networks returned.
+ // Frequencies should be empty since no scan results have been received yet.
+ List<WifiScanner.PnoSettings.PnoNetwork> pnoNetworks =
+ mWifiConfigManager.retrievePnoNetworkList();
+ assertEquals(2, pnoNetworks.size());
+ assertEquals(network1.SSID, pnoNetworks.get(0).ssid);
+ assertEquals(network2.SSID, pnoNetworks.get(1).ssid);
+ assertTrue("frequencies should be empty", pnoNetworks.get(0).frequencies.length == 0);
+ assertTrue("frequencies should be empty", pnoNetworks.get(1).frequencies.length == 0);
+
+ // Add frequencies to |network1|
+ ScanDetail scanDetail1 = createScanDetailForNetwork(network1, TEST_BSSID + "1",
+ TEST_RSSI, TEST_FREQUENCY_1);
+ ScanDetail scanDetail2 = createScanDetailForNetwork(network1, TEST_BSSID + "2",
+ TEST_RSSI, TEST_FREQUENCY_1);
+ ScanDetail scanDetail3 = createScanDetailForNetwork(network1, TEST_BSSID + "3",
+ TEST_RSSI, TEST_FREQUENCY_2);
+ ScanDetail scanDetail4 = createScanDetailForNetwork(network1, TEST_BSSID + "4",
+ TEST_RSSI, TEST_FREQUENCY_3);
+
+ // Set last seen timestamps so that when retrieving the frequencies for |network1|
+ // |TEST_FREQUENCY_2| gets included but |TEST_FREQUENCY_3| gets excluded.
+ scanDetail3.getScanResult().seen =
+ mClock.getWallClockMillis() - WifiConfigManager.MAX_PNO_SCAN_FREQUENCY_AGE_MS + 1;
+ scanDetail4.getScanResult().seen =
+ mClock.getWallClockMillis() - WifiConfigManager.MAX_PNO_SCAN_FREQUENCY_AGE_MS;
+ mWifiConfigManager.getConfiguredNetworkForScanDetailAndCache(scanDetail1);
+ mWifiConfigManager.getConfiguredNetworkForScanDetailAndCache(scanDetail2);
+ mWifiConfigManager.getConfiguredNetworkForScanDetailAndCache(scanDetail3);
+ mWifiConfigManager.getConfiguredNetworkForScanDetailAndCache(scanDetail4);
+
+ // Verify the frequencies are correct for |network1| and |TEST_FREQUENCY_3| is not in the
+ // list because it's older than the max age.
+ pnoNetworks = mWifiConfigManager.retrievePnoNetworkList();
+ assertEquals(2, pnoNetworks.size());
+ assertEquals(network1.SSID, pnoNetworks.get(0).ssid);
+ assertEquals(network2.SSID, pnoNetworks.get(1).ssid);
+ assertEquals(2, pnoNetworks.get(0).frequencies.length);
+ Arrays.sort(pnoNetworks.get(0).frequencies);
+ assertEquals(TEST_FREQUENCY_1, pnoNetworks.get(0).frequencies[0]);
+ assertEquals(TEST_FREQUENCY_2, pnoNetworks.get(0).frequencies[1]);
+ assertTrue("frequencies should be empty", pnoNetworks.get(1).frequencies.length == 0);
+ }
+
+ /**
* Verifies that the list of PNO networks does not contain ephemeral or passpoint networks
* {@link WifiConfigManager#retrievePnoNetworkList()}.
*/