summaryrefslogtreecommitdiffstats
path: root/service
diff options
context:
space:
mode:
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/WifiAutoJoinController.java94
-rw-r--r--service/java/com/android/server/wifi/WifiConfigStore.java3
-rw-r--r--service/java/com/android/server/wifi/WifiMonitor.java4
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkScoreCache.java74
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachine.java29
-rw-r--r--service/java/com/android/server/wifi/WifiWatchdogStateMachine.java11
6 files changed, 143 insertions, 72 deletions
diff --git a/service/java/com/android/server/wifi/WifiAutoJoinController.java b/service/java/com/android/server/wifi/WifiAutoJoinController.java
index e30b1c789..af1fc1bcd 100644
--- a/service/java/com/android/server/wifi/WifiAutoJoinController.java
+++ b/service/java/com/android/server/wifi/WifiAutoJoinController.java
@@ -22,6 +22,9 @@ 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.os.Process;
import android.text.TextUtils;
import android.util.Log;
@@ -75,6 +78,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;
@@ -607,7 +613,7 @@ public class WifiAutoJoinController {
bRssiBoost5 = rssiBoostFrom5GHzRssi(b.visibility.rssi5, b.configKey() + "->");
// Select which band to use for a
- if (a.visibility.rssi5 + aRssiBoost5 > b.visibility.rssi24) {
+ if (a.visibility.rssi5 + aRssiBoost5 > a.visibility.rssi24) {
// Prefer a's 5GHz
aPrefers5GHz = true;
}
@@ -647,8 +653,21 @@ public class WifiAutoJoinController {
}
if (VDBG) {
logDbg(" " + a.configKey() + " is5=" + aPrefers5GHz + " score=" + aScore
- + b.configKey() + " is5=" + bPrefers5GHz + " score=" + bScore);
+ + " " + b.configKey() + " is5=" + bPrefers5GHz + " score=" + bScore);
+ }
+
+ // Debug only, record RSSI comparison parameters
+ if (a.visibility != null) {
+ a.visibility.score = aScore;
+ a.visibility.currentNetworkBoost = aRssiBoost;
+ a.visibility.bandPreferenceBoost = aRssiBoost5;
+ }
+ if (b.visibility != null) {
+ b.visibility.score = bScore;
+ b.visibility.currentNetworkBoost = bRssiBoost;
+ b.visibility.bandPreferenceBoost = bRssiBoost5;
}
+
// Compare a and b
// If a score is higher then a > b and the order is descending (negative)
// If b score is higher then a < b and the order is ascending (positive)
@@ -693,10 +712,10 @@ public class WifiAutoJoinController {
if (VDBG) {
logDbg(" compareWifiConfigurationsRSSI: " + a.configKey()
- + " " + Integer.toString(astatus.rssi24)
+ + " rssi=" + Integer.toString(astatus.rssi24)
+ "," + Integer.toString(astatus.rssi5)
+ " boost=" + Integer.toString(aRssiBoost)
- + " " + b.configKey() + " "
+ + " " + b.configKey() + " rssi="
+ Integer.toString(bstatus.rssi24) + ","
+ Integer.toString(bstatus.rssi5)
+ " boost=" + Integer.toString(bRssiBoost)
@@ -839,6 +858,10 @@ public class WifiAutoJoinController {
+ " due to user choice of " + choice
+ " order -> " + Integer.toString(order));
}
+ if (a.visibility != null) {
+ a.visibility.lastChoiceBoost = choice;
+ a.visibility.lastChoiceConfig = b.configKey();
+ }
}
choice = getConnectChoice(b, a);
@@ -850,6 +873,10 @@ public class WifiAutoJoinController {
+ a.configKey() + " due to user choice of " + choice
+ " order ->" + Integer.toString(order));
}
+ if (b.visibility != null) {
+ b.visibility.lastChoiceBoost = choice;
+ b.visibility.lastChoiceConfig = a.configKey();
+ }
}
}
@@ -937,7 +964,7 @@ public class WifiAutoJoinController {
boost = 50;
}
if (VDBG && dbg != null) {
- logDbg(" " + dbg + ": rssi5 " + rssi + " boost " + boost);
+ logDbg(" " + dbg + ": rssi5 " + rssi + " 5GHz-boost " + boost);
}
return boost;
}
@@ -1169,6 +1196,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,12 +1351,14 @@ 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();
+ mWifiStateMachine.disconnectCommand(Process.WIFI_UID,
+ mAllowUntrustedConnections ? 1 : 0);
return false;
} else {
mCurrentConfigurationKey = currentConfiguration.configKey();
diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java
index ebdf40efa..ab29bcfc2 100644
--- a/service/java/com/android/server/wifi/WifiConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiConfigStore.java
@@ -1440,9 +1440,8 @@ public class WifiConfigStore extends IpConfigStore {
if (config.SSID != null) {
csum.update(config.SSID.getBytes(), 0, config.SSID.getBytes().length);
long d = csum.getValue();
- loge(" got CRC SSID " + config.SSID + " -> " + d);
if (mDeletedSSIDs.contains(d)) {
- loge(" was deleted");
+ loge(" got CRC for SSID " + config.SSID + " -> " + d + ", was deleted");
}
}
diff --git a/service/java/com/android/server/wifi/WifiMonitor.java b/service/java/com/android/server/wifi/WifiMonitor.java
index d1933da70..b807a92c0 100644
--- a/service/java/com/android/server/wifi/WifiMonitor.java
+++ b/service/java/com/android/server/wifi/WifiMonitor.java
@@ -973,8 +973,6 @@ public class WifiMonitor {
Matcher match = mTargetBSSIDPattern.matcher(eventStr);
if (match.find()) {
BSSID = match.group(1);
- } else {
- Log.d(TAG, "didn't find BSSID " + eventStr);
}
mStateMachine.sendMessage(WifiStateMachine.CMD_TARGET_BSSID, eventLogCounter, 0, BSSID);
}
@@ -984,8 +982,6 @@ public class WifiMonitor {
Matcher match = mAssociatedPattern.matcher(eventStr);
if (match.find()) {
BSSID = match.group(1);
- } else {
- Log.d(TAG, "handleAssociatedBSSIDEvent: didn't find BSSID " + eventStr);
}
mStateMachine.sendMessage(WifiStateMachine.CMD_ASSOCIATED_BSSID, eventLogCounter, 0, BSSID);
}
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) {
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index c2eff961c..87e0c3af5 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -2094,6 +2094,10 @@ public class WifiStateMachine extends StateMachine {
sendMessage(CMD_DISCONNECT);
}
+ public void disconnectCommand(int uid, int reason) {
+ sendMessage(CMD_DISCONNECT, uid, reason);
+ }
+
/**
* Initiate a reconnection to AP
*/
@@ -2758,10 +2762,7 @@ public class WifiStateMachine extends StateMachine {
if (config != null) {
sb.append(" ").append(config.configKey());
if (config.visibility != null) {
- sb.append(" [").append(config.visibility.num24);
- sb.append(" ,").append(config.visibility.rssi24);
- sb.append(" ;").append(config.visibility.num5);
- sb.append(" ,").append(config.visibility.rssi5).append("]");
+ sb.append(" ").append(config.visibility.toString());
}
}
if (mTargetRoamBSSID != null) {
@@ -2771,12 +2772,9 @@ public class WifiStateMachine extends StateMachine {
sb.append(printTime());
config = getCurrentWifiConfiguration();
if (config != null) {
- sb.append(" ").append(config.configKey());
+ sb.append(config.configKey());
if (config.visibility != null) {
- sb.append(" [").append(config.visibility.num24);
- sb.append(" ,").append(config.visibility.rssi24);
- sb.append(" ;").append(config.visibility.num5);
- sb.append(" ,").append(config.visibility.rssi5).append("]");
+ sb.append(" ").append(config.visibility.toString());
}
}
break;
@@ -3438,6 +3436,7 @@ public class WifiStateMachine extends StateMachine {
}
boolean attemptAutoJoin = true;
SupplicantState state = mWifiInfo.getSupplicantState();
+ String selection = mWifiConfigStore.getLastSelectedConfiguration();
if (getCurrentState() == mRoamingState
|| getCurrentState() == mObtainingIpState
|| getCurrentState() == mScanModeState
@@ -3449,13 +3448,14 @@ public class WifiStateMachine extends StateMachine {
|| state == SupplicantState.AUTHENTICATING
|| state == SupplicantState.FOUR_WAY_HANDSHAKE
|| state == SupplicantState.GROUP_HANDSHAKE
- || mConnectionRequests == 0) {
+ || (/* keep autojoin enabled if user has manually selected a wifi network,
+ so as to make sure we reliably remain connected to this network */
+ mConnectionRequests == 0 && selection == null)) {
// Dont attempt auto-joining again while we are already attempting to join
// and/or obtaining Ip address
attemptAutoJoin = false;
}
if (DBG) {
- String selection = mWifiConfigStore.getLastSelectedConfiguration();
if (selection == null) {
selection = "<none>";
}
@@ -7009,9 +7009,9 @@ public class WifiStateMachine extends StateMachine {
if (message.arg1 == SCAN_ONLY_WITH_WIFI_OFF_MODE) {
noteWifiDisabledWhileAssociated();
}
- mWifiConfigStore.
- setLastSelectedConfiguration(WifiConfiguration.INVALID_NETWORK_ID);
}
+ mWifiConfigStore.
+ setLastSelectedConfiguration(WifiConfiguration.INVALID_NETWORK_ID);
break;
case CMD_SET_COUNTRY_CODE:
messageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED;
@@ -7934,9 +7934,10 @@ public class WifiStateMachine extends StateMachine {
mWifiP2pChannel.sendMessage(CMD_DISABLE_P2P_REQ);
setWifiState(WIFI_STATE_DISABLED);
}
-
transitionTo(mScanModeState);
}
+ mWifiConfigStore.
+ setLastSelectedConfiguration(WifiConfiguration.INVALID_NETWORK_ID);
break;
/* Ignore network disconnect */
case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
diff --git a/service/java/com/android/server/wifi/WifiWatchdogStateMachine.java b/service/java/com/android/server/wifi/WifiWatchdogStateMachine.java
index 181e043d2..0ef18e6ae 100644
--- a/service/java/com/android/server/wifi/WifiWatchdogStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiWatchdogStateMachine.java
@@ -435,15 +435,8 @@ public class WifiWatchdogStateMachine extends StateMachine {
private void updateSettings() {
if (DBG) logd("Updating secure settings");
- // disable poor network avoidance
- if (sWifiOnly) {
- logd("Disabling poor network avoidance for wi-fi only device");
- mPoorNetworkDetectionEnabled = false;
- } else {
- mPoorNetworkDetectionEnabled = getSettingsGlobalBoolean(mContentResolver,
- Settings.Global.WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED,
- WifiManager.DEFAULT_POOR_NETWORK_AVOIDANCE_ENABLED);
- }
+ // Unconditionally disable poor network avoidance, since this mechanism is obsolete
+ mPoorNetworkDetectionEnabled = false;
}
/**