From 02c42a3e85f8098e8f1a762623699a8ed8ea3f64 Mon Sep 17 00:00:00 2001 From: Nate Jiang Date: Wed, 1 Apr 2020 16:54:48 -0700 Subject: Add suggestion network into partial scan list Add suggestion non-passpoint networks into partial scan list, and get channel info from ScoreCard. Bug: 148172745 Bug: 148216622 Test: atest com.android.server.wifi Change-Id: Id18d6f776a40fdf29bd8815657531d905351da24 --- .../com/android/server/wifi/WifiConfigManager.java | 162 --------------------- .../server/wifi/WifiConnectivityManager.java | 106 +++++++++++--- .../java/com/android/server/wifi/WifiInjector.java | 2 +- .../server/wifi/WifiNetworkSuggestionsManager.java | 2 +- service/res/values/config.xml | 2 +- 5 files changed, 91 insertions(+), 183 deletions(-) (limited to 'service') diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java index 4e4f51d60..087320177 100644 --- a/service/java/com/android/server/wifi/WifiConfigManager.java +++ b/service/java/com/android/server/wifi/WifiConfigManager.java @@ -71,7 +71,6 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -2600,167 +2599,6 @@ public class WifiConfigManager { } } - /** - * Helper method to fetch list of channels for a network from the associated ScanResult's cache - * and add it to the provided channel as long as the size of the set is less than - * |maxChannelSetSize|. - * - * @param channelSet Channel set holding all the channels for the network. - * @param scanDetailCache ScanDetailCache entry associated with the network. - * @param nowInMillis current timestamp to be used for age comparison. - * @param ageInMillis only consider scan details whose timestamps are earlier than this - * value. - * @param maxChannelSetSize Maximum number of channels to be added to the set. - * @return false if the list is full, true otherwise. - */ - private boolean addToChannelSetForNetworkFromScanDetailCache( - Set channelSet, ScanDetailCache scanDetailCache, - long nowInMillis, long ageInMillis, int maxChannelSetSize) { - if (scanDetailCache != null && scanDetailCache.size() > 0) { - for (ScanDetail scanDetail : scanDetailCache.values()) { - ScanResult result = scanDetail.getScanResult(); - boolean valid = (nowInMillis - result.seen) < ageInMillis; - if (mVerboseLoggingEnabled) { - Log.v(TAG, "fetchChannelSetForNetwork has " + result.BSSID + " freq " - + result.frequency + " age " + (nowInMillis - result.seen) - + " ?=" + valid); - } - if (valid) { - channelSet.add(result.frequency); - } - if (channelSet.size() >= maxChannelSetSize) { - return false; - } - } - } - return true; - } - - /** - * Retrieves a list of channels for partial single scans - * - * @param ageInMillis only consider scan details whose timestamps are more recent than this. - * @param maxCount maximum number of channels in the set - * @return Set containing the frequeincies which were used for connection recently. - */ - public Set fetchChannelSetForPartialScan(long ageInMillis, int maxCount) { - List networks = getConfiguredNetworks(); - - // Remove any permanently or temporarily disabled networks. - Iterator iter = networks.iterator(); - while (iter.hasNext()) { - WifiConfiguration config = iter.next(); - if (config.ephemeral || config.isPasspoint() - || config.getNetworkSelectionStatus().isNetworkPermanentlyDisabled() - || config.getNetworkSelectionStatus().isNetworkTemporaryDisabled()) { - iter.remove(); - } - } - - if (networks.isEmpty()) { - return null; - } - - // Sort the networks with the most frequent ones at the front of the network list. - Collections.sort(networks, mScanListComparator); - - Set channelSet = new HashSet<>(); - long nowInMillis = mClock.getWallClockMillis(); - - for (WifiConfiguration config : networks) { - ScanDetailCache scanDetailCache = getScanDetailCacheForNetwork(config.networkId); - if (scanDetailCache == null) { - continue; - } - - // Add channels for the network to the output, and exit when it reaches max size - if (!addToChannelSetForNetworkFromScanDetailCache(channelSet, scanDetailCache, - nowInMillis, ageInMillis, maxCount)) { - break; - } - } - - return channelSet; - } - - /** - * 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 for initiating partial - * scans for the currently connected network. - * - * @param networkId network ID corresponding to the network. - * @param ageInMillis only consider scan details whose timestamps are earlier than this value. - * @param homeChannelFreq frequency of the currently connected network. - * @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. - */ - public Set fetchChannelSetForNetworkForPartialScan(int networkId, long ageInMillis, - int homeChannelFreq) { - WifiConfiguration config = getInternalConfiguredNetwork(networkId); - if (config == null) { - return null; - } - ScanDetailCache scanDetailCache = getScanDetailCacheForNetwork(networkId); - if (scanDetailCache == null && config.linkedConfigurations == null) { - Log.i(TAG, "No scan detail and linked configs associated with networkId " + networkId); - return null; - } - final int maxNumActiveChannelsForPartialScans = mContext.getResources().getInteger( - R.integer.config_wifi_framework_associated_partial_scan_max_num_active_channels); - if (mVerboseLoggingEnabled) { - StringBuilder dbg = new StringBuilder(); - dbg.append("fetchChannelSetForNetworkForPartialScan ageInMillis ") - .append(ageInMillis) - .append(" for ") - .append(config.getKey()) - .append(" max ") - .append(maxNumActiveChannelsForPartialScans); - if (scanDetailCache != null) { - dbg.append(" bssids " + scanDetailCache.size()); - } - if (config.linkedConfigurations != null) { - dbg.append(" linked " + config.linkedConfigurations.size()); - } - Log.v(TAG, dbg.toString()); - } - Set channelSet = new HashSet<>(); - - // First add the currently connected network channel. - if (homeChannelFreq > 0) { - channelSet.add(homeChannelFreq); - if (channelSet.size() >= maxNumActiveChannelsForPartialScans) { - return channelSet; - } - } - - long nowInMillis = mClock.getWallClockMillis(); - - // Then get channels for the network. - if (!addToChannelSetForNetworkFromScanDetailCache( - channelSet, scanDetailCache, nowInMillis, ageInMillis, - maxNumActiveChannelsForPartialScans)) { - return channelSet; - } - - // Lastly get channels for linked networks. - if (config.linkedConfigurations != null) { - for (String configKey : config.linkedConfigurations.keySet()) { - WifiConfiguration linkedConfig = getInternalConfiguredNetwork(configKey); - if (linkedConfig == null) { - continue; - } - ScanDetailCache linkedScanDetailCache = - getScanDetailCacheForNetwork(linkedConfig.networkId); - if (!addToChannelSetForNetworkFromScanDetailCache( - channelSet, linkedScanDetailCache, nowInMillis, ageInMillis, - maxNumActiveChannelsForPartialScans)) { - break; - } - } - } - return channelSet; - } - /** * Retrieves a list of all the saved hidden networks for scans * diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java index 712dbcd7f..9a21068e8 100644 --- a/service/java/com/android/server/wifi/WifiConnectivityManager.java +++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java @@ -159,6 +159,7 @@ public class WifiConnectivityManager { private final LinkedList mConnectionAttemptTimeStamps; private final BssidBlocklistMonitor mBssidBlocklistMonitor; private WifiScanner mScanner; + private WifiScoreCard mWifiScoreCard; private boolean mDbg = false; private boolean mWifiEnabled = false; @@ -744,7 +745,7 @@ public class WifiConnectivityManager { WifiNetworkSelector networkSelector, WifiConnectivityHelper connectivityHelper, WifiLastResortWatchdog wifiLastResortWatchdog, OpenNetworkNotifier openNetworkNotifier, WifiMetrics wifiMetrics, Handler handler, - Clock clock, LocalLog localLog) { + Clock clock, LocalLog localLog, WifiScoreCard scoreCard) { mContext = context; mStateMachine = stateMachine; mWifiInjector = injector; @@ -768,6 +769,7 @@ public class WifiConnectivityManager { mBssidBlocklistMonitor = mWifiInjector.getBssidBlocklistMonitor(); mWifiChannelUtilization = mWifiInjector.getWifiChannelUtilizationScan(); mNetworkSelector.setWifiChannelUtilization(mWifiChannelUtilization); + mWifiScoreCard = scoreCard; } /** Initialize single scanning schedules, and validate them */ @@ -953,10 +955,9 @@ public class WifiConnectivityManager { R.integer.config_wifiInitialPartialScanChannelCacheAgeMins); int maxCount = mContext.getResources().getInteger( R.integer.config_wifiInitialPartialScanChannelMaxCount); - freqs = mConfigManager.fetchChannelSetForPartialScan(ageInMillis, maxCount); + freqs = fetchChannelSetForPartialScan(maxCount); } else { - freqs = mConfigManager.fetchChannelSetForNetworkForPartialScan( - config.networkId, CHANNEL_LIST_AGE_MS, mWifiInfo.getFrequency()); + freqs = fetchChannelSetForNetworkForPartialScan(config.networkId); } if (freqs != null && freqs.size() != 0) { @@ -972,6 +973,72 @@ public class WifiConnectivityManager { } } + /** + * Add the channels into the channel set with a size limit. + * If maxCount equals to 0, will add all available channels into the set. + * @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. + * @return True if all available channels for this network are added, otherwise false. + */ + private boolean addChannelFromWifiScoreCard(@NonNull Set channelSet, + @NonNull WifiConfiguration config, int maxCount) { + WifiScoreCard.PerNetwork network = mWifiScoreCard.lookupNetwork(config.SSID); + List channelList = network.getFrequencies(); + for (Integer channel : channelList) { + if (maxCount > 0 && channelSet.size() >= maxCount) { + return false; + } + channelSet.add(channel); + } + return true; + } + + /** + * Fetch channel set for target network. + */ + @VisibleForTesting + public Set fetchChannelSetForNetworkForPartialScan(int networkId) { + WifiConfiguration config = mConfigManager.getConfiguredNetwork(networkId); + if (config == null) { + return null; + } + final int maxNumActiveChannelsForPartialScans = mContext.getResources().getInteger( + R.integer.config_wifi_framework_associated_partial_scan_max_num_active_channels); + Set channelSet = new HashSet<>(); + // First add the currently connected network channel. + if (mWifiInfo.getFrequency() > 0) { + channelSet.add(mWifiInfo.getFrequency()); + } + // Then get channels for the network. + addChannelFromWifiScoreCard(channelSet, config, maxNumActiveChannelsForPartialScans); + return channelSet; + } + + /** + * Fetch channel set for all saved and suggestion non-passpoint network for partial scan. + */ + @VisibleForTesting + public Set fetchChannelSetForPartialScan(int maxCount) { + List networks = getAllScanOptimizationNetworks(); + if (networks.isEmpty()) { + return null; + } + + // Sort the networks with the most frequent ones at the front of the network list. + Collections.sort(networks, mConfigManager.getScanListComparator()); + + Set channelSet = new HashSet<>(); + + for (WifiConfiguration config : networks) { + if (!addChannelFromWifiScoreCard(channelSet, config, maxCount)) { + return channelSet; + } + } + + return channelSet; + } + // Watchdog timer handler private void watchdogHandler() { // Schedule the next timer and start a single scan if we are in disconnected state. @@ -1287,26 +1354,29 @@ public class WifiConnectivityManager { mWifiMetrics.logPnoScanStart(); } - /** - * Retrieve the PnoNetworks from Saved and suggestion non-passpoint network. - */ - @VisibleForTesting - public List retrievePnoNetworkList() { + private @NonNull List getAllScanOptimizationNetworks() { List networks = mConfigManager.getSavedNetworks(-1); networks.addAll(mWifiInjector.getWifiNetworkSuggestionsManager() - .getAllPnoAvailableSuggestionNetworks()); + .getAllScanOptimizationSuggestionNetworks()); // remove all auto-join disabled or network selection disabled network. networks.removeIf(config -> !config.allowAutojoin || !config.getNetworkSelectionStatus().isNetworkEnabled()); + return networks; + } + + /** + * Retrieve the PnoNetworks from Saved and suggestion non-passpoint network. + */ + @VisibleForTesting + public List retrievePnoNetworkList() { + List networks = getAllScanOptimizationNetworks(); + if (networks.isEmpty()) { return Collections.EMPTY_LIST; } Collections.sort(networks, mConfigManager.getScanListComparator()); - - WifiScoreCard scoreCard = null; - if (mContext.getResources().getBoolean(R.bool.config_wifiPnoFrequencyCullingEnabled)) { - scoreCard = mWifiInjector.getWifiScoreCard(); - } + boolean pnoFrequencyCullingEnabled = mContext.getResources() + .getBoolean(R.bool.config_wifiPnoFrequencyCullingEnabled); List pnoList = new ArrayList<>(); Set pnoSet = new HashSet<>(); @@ -1318,11 +1388,11 @@ public class WifiConnectivityManager { } pnoList.add(pnoNetwork); pnoSet.add(pnoNetwork); - if (scoreCard == null) { + if (!pnoFrequencyCullingEnabled) { continue; } - WifiScoreCard.PerNetwork network = scoreCard.lookupNetwork(config.SSID); - List channelList = network.getFrequencies(); + Set channelList = new HashSet<>(); + addChannelFromWifiScoreCard(channelList, config, 0); 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/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java index 6daca9066..5a3e32653 100644 --- a/service/java/com/android/server/wifi/WifiInjector.java +++ b/service/java/com/android/server/wifi/WifiInjector.java @@ -622,7 +622,7 @@ public class WifiInjector { mWifiNetworkSelector, mWifiConnectivityHelper, mWifiLastResortWatchdog, mOpenNetworkNotifier, mWifiMetrics, new Handler(mWifiHandlerThread.getLooper()), - mClock, mConnectivityLocalLog); + mClock, mConnectivityLocalLog, mWifiScoreCard); } /** diff --git a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java index 19c9da156..bf2a5aaa1 100644 --- a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java +++ b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java @@ -1208,7 +1208,7 @@ public class WifiNetworkSuggestionsManager { /** * Get all user approved, non-passpoint networks from suggestion. */ - public List getAllPnoAvailableSuggestionNetworks() { + public List getAllScanOptimizationSuggestionNetworks() { List networks = new ArrayList<>(); for (PerAppInfo info : mActiveNetworkSuggestionsPerApp.values()) { if (!info.hasUserApproved && info.carrierId == TelephonyManager.UNKNOWN_CARRIER_ID) { diff --git a/service/res/values/config.xml b/service/res/values/config.xml index b5037b74a..4d351b105 100644 --- a/service/res/values/config.xml +++ b/service/res/values/config.xml @@ -159,7 +159,7 @@ false - + 10