diff options
Diffstat (limited to 'service')
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; } /** |