From fecef5b1be05409a5ac666611b8bfdefe7d34a27 Mon Sep 17 00:00:00 2001 From: Nate Jiang Date: Thu, 2 Apr 2020 20:18:36 -0700 Subject: Add in memory timestamp for channel inside score card Use the timestamp to age out channel for initial partial scan and PNO scan. The timestamp is elapsed time since boot. Bug: 153115968 Test: atest com.android.servre.wifi Change-Id: Icd1c84ae1c3518f501466377a8f6e4e532f83332 --- .../server/wifi/WifiConnectivityManager.java | 24 ++++++++++++++-------- .../com/android/server/wifi/WifiScoreCard.java | 23 +++++++++++++++++---- 2 files changed, 34 insertions(+), 13 deletions(-) (limited to 'service') diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java index bf774688e..7178a0a5c 100644 --- a/service/java/com/android/server/wifi/WifiConnectivityManager.java +++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java @@ -114,13 +114,15 @@ public class WifiConnectivityManager { // to prevent caveat from things like PNO scan. private static final int WATCHDOG_INTERVAL_MS = 20 * 60 * 1000; // 20 minutes // Restricted channel list age out value. - private static final int CHANNEL_LIST_AGE_MS = 60 * 60 * 1000; // 1 hour + private static final long CHANNEL_LIST_AGE_MS = 60 * 60 * 1000; // 1 hour // This is the time interval for the connection attempt rate calculation. Connection attempt // timestamps beyond this interval is evicted from the list. public static final int MAX_CONNECTION_ATTEMPTS_TIME_INTERVAL_MS = 4 * 60 * 1000; // 4 mins // Max number of connection attempts in the above time interval. public static final int MAX_CONNECTION_ATTEMPTS_RATE = 6; private static final int TEMP_BSSID_BLOCK_DURATION = 10 * 1000; // 10 seconds + // Maximum age of frequencies last seen to be included in pno scans. (30 days) + private static final long MAX_PNO_SCAN_FREQUENCY_AGE_MS = (long) 1000 * 3600 * 24 * 30; // ClientModeImpl has a bunch of states. From the // WifiConnectivityManager's perspective it only cares // if it is in Connected state, Disconnected state or in @@ -975,7 +977,7 @@ public class WifiConnectivityManager { R.integer.config_wifiInitialPartialScanChannelCacheAgeMins); int maxCount = mContext.getResources().getInteger( R.integer.config_wifiInitialPartialScanChannelMaxCount); - freqs = fetchChannelSetForPartialScan(maxCount); + freqs = fetchChannelSetForPartialScan(maxCount, ageInMillis); } else { freqs = fetchChannelSetForNetworkForPartialScan(config.networkId); } @@ -999,14 +1001,16 @@ public class WifiConnectivityManager { * @param channelSet Target set for adding channel to. * @param config Network for query channel from WifiScoreCard * @param maxCount Size limit of the set. If equals to 0, means no limit. + * @param ageInMillis Only consider channel info whose timestamps are younger than this value. * @return True if all available channels for this network are added, otherwise false. */ private boolean addChannelFromWifiScoreCard(@NonNull Set channelSet, - @NonNull WifiConfiguration config, int maxCount) { + @NonNull WifiConfiguration config, int maxCount, long ageInMillis) { WifiScoreCard.PerNetwork network = mWifiScoreCard.lookupNetwork(config.SSID); - List channelList = network.getFrequencies(); - for (Integer channel : channelList) { + for (Integer channel : network.getFrequencies(ageInMillis)) { if (maxCount > 0 && channelSet.size() >= maxCount) { + localLog("addChannelFromWifiScoreCard: size limit reached for network:" + + config.SSID); return false; } channelSet.add(channel); @@ -1031,7 +1035,8 @@ public class WifiConnectivityManager { channelSet.add(mWifiInfo.getFrequency()); } // Then get channels for the network. - addChannelFromWifiScoreCard(channelSet, config, maxNumActiveChannelsForPartialScans); + addChannelFromWifiScoreCard(channelSet, config, maxNumActiveChannelsForPartialScans, + CHANNEL_LIST_AGE_MS); return channelSet; } @@ -1039,7 +1044,7 @@ public class WifiConnectivityManager { * Fetch channel set for all saved and suggestion non-passpoint network for partial scan. */ @VisibleForTesting - public Set fetchChannelSetForPartialScan(int maxCount) { + public Set fetchChannelSetForPartialScan(int maxCount, long ageInMillis) { List networks = getAllScanOptimizationNetworks(); if (networks.isEmpty()) { return null; @@ -1051,7 +1056,7 @@ public class WifiConnectivityManager { Set channelSet = new HashSet<>(); for (WifiConfiguration config : networks) { - if (!addChannelFromWifiScoreCard(channelSet, config, maxCount)) { + if (!addChannelFromWifiScoreCard(channelSet, config, maxCount, ageInMillis)) { return channelSet; } } @@ -1430,7 +1435,8 @@ public class WifiConnectivityManager { continue; } Set channelList = new HashSet<>(); - addChannelFromWifiScoreCard(channelList, config, 0); + addChannelFromWifiScoreCard(channelList, config, 0, + MAX_PNO_SCAN_FREQUENCY_AGE_MS); pnoNetwork.frequencies = channelList.stream().mapToInt(Integer::intValue).toArray(); localLog("retrievePnoNetworkList " + pnoNetwork.ssid + ":" + Arrays.toString(pnoNetwork.frequencies)); diff --git a/service/java/com/android/server/wifi/WifiScoreCard.java b/service/java/com/android/server/wifi/WifiScoreCard.java index 4f12470e0..fdf7a678b 100644 --- a/service/java/com/android/server/wifi/WifiScoreCard.java +++ b/service/java/com/android/server/wifi/WifiScoreCard.java @@ -40,6 +40,7 @@ import android.util.ArrayMap; import android.util.Base64; import android.util.Log; import android.util.Pair; +import android.util.SparseLongArray; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; @@ -68,6 +69,7 @@ import java.lang.annotation.RetentionPolicy; import java.nio.ByteBuffer; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -803,6 +805,8 @@ public class WifiScoreCard { private NetworkConnectionStats mStatsCurrBuild; private NetworkConnectionStats mStatsPrevBuild; private LruList mFrequencyList; + // In memory keep frequency with timestamp last time available, the elapsed time since boot. + private SparseLongArray mFreqTimestamp; PerNetwork(String ssid) { super(computeHashLong(ssid, MacAddress.fromString(DEFAULT_MAC_ADDRESS), mL2KeySeed)); @@ -812,7 +816,8 @@ public class WifiScoreCard { mRecentStats = new NetworkConnectionStats(); mStatsCurrBuild = new NetworkConnectionStats(); mStatsPrevBuild = new NetworkConnectionStats(); - mFrequencyList = new LruList(MAX_FREQUENCIES_PER_SSID); + mFrequencyList = new LruList<>(MAX_FREQUENCIES_PER_SSID); + mFreqTimestamp = new SparseLongArray(); } void updateEventStats(Event event, int rssi, int txSpeed, int failureReason) { @@ -923,10 +928,19 @@ public class WifiScoreCard { /** * Retrieve the list of frequencies seen for this network, with the most recent first. - * @return + * @param ageInMills Max age to filter the channels. + * @return a list of frequencies */ - List getFrequencies() { - return mFrequencyList.getEntries(); + List getFrequencies(Long ageInMills) { + List results = new ArrayList<>(); + Long nowInMills = mClock.getElapsedSinceBootMillis(); + for (Integer freq : mFrequencyList.getEntries()) { + if (nowInMills - mFreqTimestamp.get(freq, 0L) > ageInMills) { + continue; + } + results.add(freq); + } + return results; } /** @@ -935,6 +949,7 @@ public class WifiScoreCard { */ void addFrequency(int frequency) { mFrequencyList.add(frequency); + mFreqTimestamp.put(frequency, mClock.getElapsedSinceBootMillis()); } /** -- cgit v1.2.3