diff options
author | Randy Pan <zpan@google.com> | 2017-02-24 15:08:35 -0800 |
---|---|---|
committer | Randy Pan <zpan@google.com> | 2017-03-21 16:11:22 -0700 |
commit | 167b90b5e002698378728a54a417a08c317d29dc (patch) | |
tree | 3a2fbe45da70fae0e0e3f8d16de0e3d4057473b3 /service | |
parent | 168fba718720b54cf0a88cfad7f96948925fb1e3 (diff) |
Move BSSID blacklist to WifiConnectivityManager
Now the BSSID blacklist is managed by WifiConnectivityManager and
passed to WifiNetworkSelector for scan results filtration.
Bug: 35642214
Test: runtests.sh and manual tests
Change-Id: I7afb5e66be471f3582075adb687a7d85ba49a80b
Diffstat (limited to 'service')
-rw-r--r-- | service/java/com/android/server/wifi/WifiConnectivityManager.java | 121 | ||||
-rw-r--r-- | service/java/com/android/server/wifi/WifiNetworkSelector.java | 109 |
2 files changed, 132 insertions, 98 deletions
diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java index 4ae3a96a2..86b9782a4 100644 --- a/service/java/com/android/server/wifi/WifiConnectivityManager.java +++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java @@ -39,9 +39,12 @@ import com.android.server.wifi.util.ScanResultUtil; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -162,6 +165,24 @@ public class WifiConnectivityManager { private int mSecureBonus; private int mBand5GHzBonus; + // BSSID blacklist + @VisibleForTesting + public static final int BSSID_BLACKLIST_THRESHOLD = 3; + @VisibleForTesting + public static final int BSSID_BLACKLIST_EXPIRE_TIME_MS = 5 * 60 * 1000; + private static class BssidBlacklistStatus { + // Number of times this BSSID has been rejected for association. + public int counter; + public boolean isBlacklisted; + public long blacklistedTimeStamp = RESET_TIME_STAMP; + } + private Map<String, BssidBlacklistStatus> mBssidBlacklist = + new HashMap<>(); + + // Association failure reason codes + @VisibleForTesting + public static final int REASON_CODE_AP_UNABLE_TO_HANDLE_NEW_STA = 17; + // A helper to log debugging information in the local log buffer, which can // be retrieved in bugreport. private void localLog(String log) { @@ -221,6 +242,9 @@ public class WifiConnectivityManager { * false - if no candidate is selected by WifiNetworkSelector */ private boolean handleScanResults(List<ScanDetail> scanDetails, String listenerName) { + // Check if any blacklisted BSSIDs can be freed. + refreshBssidBlacklist(); + if (mStateMachine.isLinkDebouncing() || mStateMachine.isSupplicantTransientState()) { localLog(listenerName + " onResults: No network selection because linkDebouncing is " + mStateMachine.isLinkDebouncing() + " and supplicantTransient is " @@ -231,7 +255,7 @@ public class WifiConnectivityManager { localLog(listenerName + " onResults: start network selection"); WifiConfiguration candidate = - mNetworkSelector.selectNetwork(scanDetails, mWifiInfo, + mNetworkSelector.selectNetwork(scanDetails, buildBssidBlacklist(), mWifiInfo, mStateMachine.isConnected(), mStateMachine.isDisconnected(), mUntrustedConnectionAllowed); mWifiLastResortWatchdog.updateAvailableNetworks( @@ -987,23 +1011,110 @@ public class WifiConnectivityManager { } /** + * Update the BSSID blacklist when a BSSID is enabled or disabled + * + * @param bssid the bssid to be enabled/disabled + * @param enable -- true enable the bssid + * -- false disable the bssid + * @param reasonCode enable/disable reason code + * @return true if blacklist is updated; false otherwise + */ + private boolean updateBssidBlacklist(String bssid, boolean enable, int reasonCode) { + // Remove the bssid from blacklist when it is enabled. + if (enable) { + return mBssidBlacklist.remove(bssid) != null; + } + + // Update the bssid's blacklist status when it is disabled because of + // assocation rejection. + BssidBlacklistStatus status = mBssidBlacklist.get(bssid); + if (status == null) { + // First time for this BSSID + status = new BssidBlacklistStatus(); + mBssidBlacklist.put(bssid, status); + } + + status.blacklistedTimeStamp = mClock.getElapsedSinceBootMillis(); + status.counter++; + if (!status.isBlacklisted) { + if (status.counter >= BSSID_BLACKLIST_THRESHOLD + || reasonCode == REASON_CODE_AP_UNABLE_TO_HANDLE_NEW_STA) { + status.isBlacklisted = true; + return true; + } + } + return false; + } + + /** * Track whether a BSSID should be enabled or disabled for WifiNetworkSelector + * + * @param bssid the bssid to be enabled/disabled + * @param enable -- true enable the bssid + * -- false disable the bssid + * @param reasonCode enable/disable reason code + * @return true if blacklist is updated; false otherwise */ public boolean trackBssid(String bssid, boolean enable, int reasonCode) { localLog("trackBssid: " + (enable ? "enable " : "disable ") + bssid + " reason code " + reasonCode); - boolean ret = mNetworkSelector - .enableBssidForNetworkSelection(bssid, enable, reasonCode); + if (bssid == null) { + return false; + } - if (ret && !enable) { + boolean updated = updateBssidBlacklist(bssid, enable, reasonCode); + + if (updated && !enable) { // Disabling a BSSID can happen when the AP candidate to connect to has // no capacity for new stations. We start another scan immediately so that // WifiNetworkSelector can give us another candidate to connect to. startConnectivityScan(SCAN_IMMEDIATELY); } - return ret; + return updated; + } + + /** + * Check whether a bssid is disabled + */ + @VisibleForTesting + public boolean isBssidDisabled(String bssid) { + BssidBlacklistStatus status = mBssidBlacklist.get(bssid); + return status == null ? false : status.isBlacklisted; + } + + /** + * Compile and return a hashset of the blacklisted BSSIDs + */ + private HashSet<String> buildBssidBlacklist() { + HashSet<String> blacklistedBssids = new HashSet<String>(); + for (String bssid : mBssidBlacklist.keySet()) { + if (isBssidDisabled(bssid)) { + blacklistedBssids.add(bssid); + } + } + + return blacklistedBssids; + } + + /** + * Refresh the BSSID blacklist + * + * Go through the BSSID blacklist and check if a BSSID has been blacklisted for + * BSSID_BLACKLIST_EXPIRE_TIME_MS. If yes, re-enable it. + */ + private void refreshBssidBlacklist() { + Iterator<BssidBlacklistStatus> iter = mBssidBlacklist.values().iterator(); + Long currentTimeStamp = mClock.getElapsedSinceBootMillis(); + + while (iter.hasNext()) { + BssidBlacklistStatus status = iter.next(); + if (status.isBlacklisted && ((currentTimeStamp - status.blacklistedTimeStamp) + >= BSSID_BLACKLIST_EXPIRE_TIME_MS)) { + iter.remove(); + } + } } /** diff --git a/service/java/com/android/server/wifi/WifiNetworkSelector.java b/service/java/com/android/server/wifi/WifiNetworkSelector.java index 956fe629c..5b3bc24ed 100644 --- a/service/java/com/android/server/wifi/WifiNetworkSelector.java +++ b/service/java/com/android/server/wifi/WifiNetworkSelector.java @@ -34,10 +34,8 @@ import com.android.internal.annotations.VisibleForTesting; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; +import java.util.HashSet; import java.util.List; -import java.util.Map; /** * This class looks at all the connectivity scan results then @@ -50,24 +48,8 @@ public class WifiNetworkSelector { @VisibleForTesting public static final int MINIMUM_NETWORK_SELECTION_INTERVAL_MS = 10 * 1000; - // Constants for BSSID blacklist. - public static final int BSSID_BLACKLIST_THRESHOLD = 3; - public static final int BSSID_BLACKLIST_EXPIRE_TIME_MS = 5 * 60 * 1000; - - // Association success/failure reason codes - @VisibleForTesting - public static final int REASON_CODE_AP_UNABLE_TO_HANDLE_NEW_STA = 17; - private WifiConfigManager mWifiConfigManager; private Clock mClock; - private static class BssidBlacklistStatus { - // Number of times this BSSID has been rejected for association. - public int counter; - public boolean isBlacklisted; - public long blacklistedTimeStamp = INVALID_TIME_STAMP; - } - private Map<String, BssidBlacklistStatus> mBssidBlacklist = - new HashMap<>(); private final LocalLog mLocalLog = new LocalLog(ActivityManager.isLowRamDeviceStatic() ? 256 : 512); @@ -258,8 +240,8 @@ public class WifiNetworkSelector { return (network.SSID + ":" + network.networkId); } - private List<ScanDetail> filterScanResults(List<ScanDetail> scanDetails, boolean isConnected, - String currentBssid) { + private List<ScanDetail> filterScanResults(List<ScanDetail> scanDetails, + HashSet<String> bssidBlacklist, boolean isConnected, String currentBssid) { ArrayList<NetworkKey> unscoredNetworks = new ArrayList<NetworkKey>(); List<ScanDetail> validScanDetails = new ArrayList<ScanDetail>(); StringBuffer noValidSsid = new StringBuffer(); @@ -282,7 +264,7 @@ public class WifiNetworkSelector { final String scanId = toScanId(scanResult); - if (isBssidDisabled(scanResult.BSSID)) { + if (bssidBlacklist.contains(scanResult.BSSID)) { blacklistedBssid.append(scanId).append(" / "); continue; } @@ -433,75 +415,19 @@ public class WifiNetworkSelector { } /** - * Enable/disable a BSSID for Network Selection - * When an association rejection event is obtained, Network Selector will disable this - * BSSID but supplicant still can try to connect to this bssid. If supplicant connect to it - * successfully later, this bssid can be re-enabled. - * - * @param bssid the bssid to be enabled / disabled - * @param enable -- true enable a bssid if it has been disabled - * -- false disable a bssid - * @param reasonCode enable/disable reason code - */ - public boolean enableBssidForNetworkSelection(String bssid, boolean enable, int reasonCode) { - if (enable) { - return (mBssidBlacklist.remove(bssid) != null); - } else { - if (bssid != null) { - BssidBlacklistStatus status = mBssidBlacklist.get(bssid); - if (status == null) { - // First time for this BSSID - status = new BssidBlacklistStatus(); - mBssidBlacklist.put(bssid, status); - } - - if (!status.isBlacklisted) { - status.counter++; - if (status.counter >= BSSID_BLACKLIST_THRESHOLD - || reasonCode == REASON_CODE_AP_UNABLE_TO_HANDLE_NEW_STA) { - status.isBlacklisted = true; - status.blacklistedTimeStamp = mClock.getElapsedSinceBootMillis(); - return true; - } - } - } - } - return false; - } - - /** - * Update the BSSID blacklist - * - * Go through the BSSID blacklist and check when a BSSID was blocked. If it - * has been blacklisted for BSSID_BLACKLIST_EXPIRE_TIME_MS, then re-enable it. - */ - private void updateBssidBlacklist() { - Iterator<BssidBlacklistStatus> iter = mBssidBlacklist.values().iterator(); - while (iter.hasNext()) { - BssidBlacklistStatus status = iter.next(); - if (status != null && status.isBlacklisted) { - if (mClock.getElapsedSinceBootMillis() - status.blacklistedTimeStamp - >= BSSID_BLACKLIST_EXPIRE_TIME_MS) { - iter.remove(); - } - } - } - } - - /** - * Check whether a bssid is disabled - * @param bssid -- the bssid to check - */ - private boolean isBssidDisabled(String bssid) { - BssidBlacklistStatus status = mBssidBlacklist.get(bssid); - return status == null ? false : status.isBlacklisted; - } - - /** + * Select the best network from the ones in range. * + * @param scanDetails List of ScanDetail for all the APs in range + * @param bssidBlacklist Blacklisted BSSIDs + * @param wifiInfo Currently connected network + * @param connected True if the device is connected + * @param disconnected True if the device is disconnected + * @param untrustedNetworkAllowed True if untrusted networks are allowed for connection + * @return Configuration of the selected network, or Null if nothing */ @Nullable - public WifiConfiguration selectNetwork(List<ScanDetail> scanDetails, WifiInfo wifiInfo, + public WifiConfiguration selectNetwork(List<ScanDetail> scanDetails, + HashSet<String> bssidBlacklist, WifiInfo wifiInfo, boolean connected, boolean disconnected, boolean untrustedNetworkAllowed) { mConnectableNetworks.clear(); if (scanDetails.size() == 0) { @@ -528,12 +454,9 @@ public class WifiNetworkSelector { } } - // Check if any BSSID can be freed from the blacklist. - updateBssidBlacklist(); - // Filter out unwanted networks. - List<ScanDetail> filteredScanDetails = filterScanResults(scanDetails, connected, - currentBssid); + List<ScanDetail> filteredScanDetails = filterScanResults(scanDetails, bssidBlacklist, + connected, currentBssid); if (filteredScanDetails.size() == 0) { return null; } |