summaryrefslogtreecommitdiffstats
path: root/service
diff options
context:
space:
mode:
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/WifiAutoJoinController.java59
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkScoreCache.java74
2 files changed, 96 insertions, 37 deletions
diff --git a/service/java/com/android/server/wifi/WifiAutoJoinController.java b/service/java/com/android/server/wifi/WifiAutoJoinController.java
index e30b1c789..d2ae76a43 100644
--- a/service/java/com/android/server/wifi/WifiAutoJoinController.java
+++ b/service/java/com/android/server/wifi/WifiAutoJoinController.java
@@ -22,6 +22,8 @@ import android.net.NetworkScoreManager;
import android.net.WifiKey;
import android.net.wifi.*;
import android.net.wifi.WifiConfiguration.KeyMgmt;
+import android.os.SystemClock;
+import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
@@ -75,6 +77,9 @@ public class WifiAutoJoinController {
// Lose some temporary blacklisting after 30 minutes
private final static long loseBlackListSoftMilli = 1000 * 60 * 30;
+ /** @see android.provider.Settings.Global#WIFI_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS */
+ private static final long DEFAULT_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS = 1000 * 60; // 1 minute
+
public static final int AUTO_JOIN_IDLE = 0;
public static final int AUTO_JOIN_ROAMING = 1;
public static final int AUTO_JOIN_EXTENDED_ROAMING = 2;
@@ -1169,6 +1174,53 @@ public class WifiAutoJoinController {
!result.capabilities.contains("EAP");
}
+ private boolean haveRecentlySeenScoredBssid(WifiConfiguration config) {
+ long ephemeralOutOfRangeTimeoutMs = Settings.Global.getLong(
+ mContext.getContentResolver(),
+ Settings.Global.WIFI_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS,
+ DEFAULT_EPHEMERAL_OUT_OF_RANGE_TIMEOUT_MS);
+
+ // Check whether the currently selected network has a score curve. If
+ // ephemeralOutOfRangeTimeoutMs is <= 0, then this is all we check, and we stop here.
+ // Otherwise, we stop here if the currently selected network has a score. If it doesn't, we
+ // keep going - it could be that another BSSID is in range (has been seen recently) which
+ // has a score, even if the one we're immediately connected to doesn't.
+ ScanResult currentScanResult = mWifiStateMachine.getCurrentScanResult();
+ boolean currentNetworkHasScoreCurve = mNetworkScoreCache.hasScoreCurve(currentScanResult);
+ if (ephemeralOutOfRangeTimeoutMs <= 0 || currentNetworkHasScoreCurve) {
+ if (DBG) {
+ if (currentNetworkHasScoreCurve) {
+ logDbg("Current network has a score curve, keeping network: "
+ + currentScanResult);
+ } else {
+ logDbg("Current network has no score curve, giving up: " + config.SSID);
+ }
+ }
+ return currentNetworkHasScoreCurve;
+ }
+
+ if (config.scanResultCache == null || config.scanResultCache.isEmpty()) {
+ return false;
+ }
+
+ long currentTimeMs = System.currentTimeMillis();
+ for (ScanResult result : config.scanResultCache.values()) {
+ if (currentTimeMs > result.seen
+ && currentTimeMs - result.seen < ephemeralOutOfRangeTimeoutMs
+ && mNetworkScoreCache.hasScoreCurve(result)) {
+ if (DBG) {
+ logDbg("Found scored BSSID, keeping network: " + result.BSSID);
+ }
+ return true;
+ }
+ }
+
+ if (DBG) {
+ logDbg("No recently scored BSSID found, giving up connection: " + config.SSID);
+ }
+ return false;
+ }
+
/**
* attemptAutoJoin() function implements the core of the a network switching algorithm
* Return false if no acceptable networks were found.
@@ -1277,10 +1329,11 @@ public class WifiAutoJoinController {
mWifiStateMachine.disconnectCommand();
return false;
} else if (currentConfiguration.ephemeral && (!mAllowUntrustedConnections ||
- !mNetworkScoreCache.isScoredNetwork(currentConfiguration.lastSeen()))) {
+ !haveRecentlySeenScoredBssid(currentConfiguration))) {
// The current connection is untrusted (the framework added it), but we're either
- // no longer allowed to connect to such networks, or the score has been nullified
- // since we connected. Drop the current connection and perform the rest of autojoin.
+ // no longer allowed to connect to such networks, the score has been nullified
+ // since we connected, or the scored BSSID has gone out of range.
+ // Drop the current connection and perform the rest of autojoin.
logDbg("attemptAutoJoin() disconnecting from unwanted ephemeral network");
mWifiStateMachine.disconnectCommand();
return false;
diff --git a/service/java/com/android/server/wifi/WifiNetworkScoreCache.java b/service/java/com/android/server/wifi/WifiNetworkScoreCache.java
index 0a6852788..0a7df0b0e 100644
--- a/service/java/com/android/server/wifi/WifiNetworkScoreCache.java
+++ b/service/java/com/android/server/wifi/WifiNetworkScoreCache.java
@@ -73,37 +73,38 @@ public class WifiNetworkScoreCache extends INetworkScoreCache.Stub
}
}
+ /**
+ * Returns whether there is any score info for the given ScanResult.
+ *
+ * This includes null-score info, so it should only be used when determining whether to request
+ * scores from the network scorer.
+ */
public boolean isScoredNetwork(ScanResult result) {
- String key = buildNetworkKey(result);
- if (key == null) return false;
+ return getScoredNetwork(result) != null;
+ }
- //find it
- synchronized(mNetworkCache) {
- ScoredNetwork network = mNetworkCache.get(key);
- if (network != null) {
- return true;
- }
- }
- return false;
+ /**
+ * Returns whether there is a non-null score curve for the given ScanResult.
+ *
+ * A null score curve has special meaning - we should never connect to an ephemeral network if
+ * the score curve is null.
+ */
+ public boolean hasScoreCurve(ScanResult result) {
+ ScoredNetwork network = getScoredNetwork(result);
+ return network != null && network.rssiCurve != null;
}
public int getNetworkScore(ScanResult result) {
int score = INVALID_NETWORK_SCORE;
- String key = buildNetworkKey(result);
- if (key == null) return score;
-
- //find it
- synchronized(mNetworkCache) {
- ScoredNetwork network = mNetworkCache.get(key);
- if (network != null && network.rssiCurve != null) {
- score = network.rssiCurve.lookupScore(result.level);
- if (DBG) {
- Log.e(TAG, "getNetworkScore found scored network " + key
- + " score " + Integer.toString(score)
- + " RSSI " + result.level);
- }
+ ScoredNetwork network = getScoredNetwork(result);
+ if (network != null && network.rssiCurve != null) {
+ score = network.rssiCurve.lookupScore(result.level);
+ if (DBG) {
+ Log.e(TAG, "getNetworkScore found scored network " + network.networkKey
+ + " score " + Integer.toString(score)
+ + " RSSI " + result.level);
}
}
return score;
@@ -113,23 +114,28 @@ public class WifiNetworkScoreCache extends INetworkScoreCache.Stub
int score = INVALID_NETWORK_SCORE;
+ ScoredNetwork network = getScoredNetwork(result);
+ if (network != null && network.rssiCurve != null) {
+ score = network.rssiCurve.lookupScore(result.level, isActiveNetwork);
+ if (DBG) {
+ Log.e(TAG, "getNetworkScore found scored network " + network.networkKey
+ + " score " + Integer.toString(score)
+ + " RSSI " + result.level
+ + " isActiveNetwork " + isActiveNetwork);
+ }
+ }
+ return score;
+ }
+
+ private ScoredNetwork getScoredNetwork(ScanResult result) {
String key = buildNetworkKey(result);
- if (key == null) return score;
+ if (key == null) return null;
//find it
synchronized(mNetworkCache) {
ScoredNetwork network = mNetworkCache.get(key);
- if (network != null && network.rssiCurve != null) {
- score = network.rssiCurve.lookupScore(result.level, isActiveNetwork);
- if (DBG) {
- Log.e(TAG, "getNetworkScore found scored network " + key
- + " score " + Integer.toString(score)
- + " RSSI " + result.level
- + " isActiveNetwork " + isActiveNetwork);
- }
- }
+ return network;
}
- return score;
}
private String buildNetworkKey(ScoredNetwork network) {