From 8fe3e3497daf08b71ffc8c33cb7b139df6667448 Mon Sep 17 00:00:00 2001 From: Glen Kuhne Date: Wed, 13 Apr 2016 17:09:18 -0700 Subject: WifiLastResortWatchdog failure counting Implemented watchdog methods and calls to them from WifiStateMachine to count association rejection, authentication failure & dhcp failures. This will allow the watchdog to determine when all available networks are failing, and Wifi Framework has no other options, however this Cl does not implement that logic. BUG=27855690 BUG=27856523 Change-Id: I416bfd0e0340823de5ca04f2d040bff7a751b677 --- .../server/wifi/WifiLastResortWatchdog.java | 309 ++++++++++++++++++--- .../com/android/server/wifi/WifiStateMachine.java | 24 ++ 2 files changed, 302 insertions(+), 31 deletions(-) (limited to 'service') diff --git a/service/java/com/android/server/wifi/WifiLastResortWatchdog.java b/service/java/com/android/server/wifi/WifiLastResortWatchdog.java index 36f0656a8..6c069ade9 100644 --- a/service/java/com/android/server/wifi/WifiLastResortWatchdog.java +++ b/service/java/com/android/server/wifi/WifiLastResortWatchdog.java @@ -27,55 +27,100 @@ import java.util.List; import java.util.Map; /** - * Intended Purpose/Behavior of the class upon completion: + * This Class is a Work-In-Progress, intended behavior is as follows: * Essentially this class automates a user toggling 'Airplane Mode' when WiFi "won't work". * IF each available saved network has failed connecting more times than the FAILURE_THRESHOLD * THEN Watchdog will restart Supplicant, wifi driver and return WifiStateMachine to InitialState. - * */ public class WifiLastResortWatchdog { private static final String TAG = "WifiLastResortWatchdog"; private static final boolean VDBG = false; + private static final boolean DBG = true; + /** + * Association Failure code + */ + public static final int FAILURE_CODE_ASSOCIATION = 1; + /** + * Authentication Failure code + */ + public static final int FAILURE_CODE_AUTHENTICATION = 2; + /** + * Dhcp Failure code + */ + public static final int FAILURE_CODE_DHCP = 3; + /** + * Maximum number of scan results received since we last saw a BSSID. + * If it is not seen before this limit is reached, the network is culled + */ + public static final int MAX_BSSID_AGE = 10; + /** + * BSSID used to increment failure counts against ALL bssids associated with a particular SSID + */ + public static final String BSSID_ANY = "any"; + /** + * Failure count that each available networks must meet to possibly trigger the Watchdog + */ + public static final int FAILURE_THRESHOLD = 7; /** * Cached WifiConfigurations of available networks seen within MAX_BSSID_AGE scan results * Key:BSSID, Value:Counters of failure types */ private Map mRecentAvailableNetworks = new HashMap<>(); - - // Maximum number of scan results received since we last saw a BSSID. - // If it is not seen before this limit is reached, the network is culled - public static final int MAX_BSSID_AGE = 10; + /** + * Map of SSID to , used to count failures & number of access points + * belonging to an SSID. + */ + private Map> mSsidFailureCount = + new HashMap<>(); /** * Refreshes recentAvailableNetworks with the latest available networks * Adds new networks, removes old ones that have timed out. Should be called after Wifi * framework decides what networks it is potentially connecting to. - * @param availableNetworkFailureCounts ScanDetail & Config list of potential connection + * @param availableNetworks ScanDetail & Config list of potential connection * candidates */ public void updateAvailableNetworks( - List> availableNetworkFailureCounts) { + List> availableNetworks) { + if (VDBG) Log.v(TAG, "updateAvailableNetworks: size = " + availableNetworks.size()); // Add new networks to mRecentAvailableNetworks - if (availableNetworkFailureCounts != null) { - for (Pair pair : availableNetworkFailureCounts) { - ScanResult scanResult = pair.first.getScanResult(); + if (availableNetworks != null) { + for (Pair pair : availableNetworks) { + final ScanDetail scanDetail = pair.first; + final WifiConfiguration config = pair.second; + ScanResult scanResult = scanDetail.getScanResult(); if (scanResult == null) continue; - String key = scanResult.BSSID; - + String bssid = scanResult.BSSID; + String ssid = "\"" + scanDetail.getSSID() + "\""; + if (VDBG) Log.v(TAG, " " + bssid + ": " + scanDetail.getSSID()); // Cache the scanResult & WifiConfig AvailableNetworkFailureCount availableNetworkFailureCount = - mRecentAvailableNetworks.get(key); - if (availableNetworkFailureCount != null) { - // We've already cached this, refresh timeout count & config - availableNetworkFailureCount.config = pair.second; - } else { + mRecentAvailableNetworks.get(bssid); + if (availableNetworkFailureCount == null) { // New network is available - availableNetworkFailureCount = new AvailableNetworkFailureCount(pair.second); - availableNetworkFailureCount.Ssid = pair.first.getSSID(); + availableNetworkFailureCount = new AvailableNetworkFailureCount(config); + availableNetworkFailureCount.ssid = ssid; + + // Count AP for this SSID + Pair ssidFailsAndApCount = + mSsidFailureCount.get(ssid); + if (ssidFailsAndApCount == null) { + // This is a new SSID, create new FailureCount for it and set AP count to 1 + ssidFailsAndApCount = Pair.create(new AvailableNetworkFailureCount(config), + 1); + } else { + final Integer numberOfAps = ssidFailsAndApCount.second; + // This is not a new SSID, increment the AP count for it + ssidFailsAndApCount = Pair.create(ssidFailsAndApCount.first, + numberOfAps + 1); + } + mSsidFailureCount.put(ssid, ssidFailsAndApCount); } - // If we saw a network, set its Age to -1 here, next incrementation will set it to 0 + // refresh config + availableNetworkFailureCount.config = config; + // If we saw a network, set its Age to -1 here, aging iteration will set it to 0 availableNetworkFailureCount.age = -1; - mRecentAvailableNetworks.put(key, availableNetworkFailureCount); + mRecentAvailableNetworks.put(bssid, availableNetworkFailureCount); } } @@ -87,12 +132,136 @@ public class WifiLastResortWatchdog { if (entry.getValue().age < MAX_BSSID_AGE - 1) { entry.getValue().age++; } else { + // Decrement this SSID : AP count + String ssid = entry.getValue().ssid; + Pair ssidFails = + mSsidFailureCount.get(ssid); + if (ssidFails != null) { + Integer apCount = ssidFails.second - 1; + if (apCount > 0) { + ssidFails = Pair.create(ssidFails.first, apCount); + mSsidFailureCount.put(ssid, ssidFails); + } else { + mSsidFailureCount.remove(ssid); + } + } else { + if (DBG) { + Log.d(TAG, "updateAvailableNetworks: SSID to AP count mismatch for " + + ssid); + } + } it.remove(); } } if (VDBG) Log.v(TAG, toString()); } + /** + * Increments the failure reason count for the given bssid. Performs a check to see if we have + * exceeded a failure threshold for all available networks, and executes the last resort restart + * @param bssid of the network that has failed connection, can be "any" + * @param reason Message id from WifiStateMachine for this failure + * @return true if watchdog triggers, returned for test visibility + */ + public boolean noteConnectionFailureAndTriggerIfNeeded(String ssid, String bssid, int reason) { + if (VDBG) { + Log.v(TAG, "noteConnectionFailureAndTriggerIfNeeded: [" + ssid + ", " + bssid + ", " + + reason + "]"); + } + // Update failure count for the failing network + updateFailureCountForNetwork(ssid, bssid, reason); + return false; + } + + /** + * Increments the failure reason count for the given network, in 'mSsidFailureCount' + * Failures are counted per SSID, either; by using the ssid string when the bssid is "any" + * or by looking up the ssid attached to a specific bssid + * An unused set of counts is also kept which is bssid specific, in 'mRecentAvailableNetworks' + * @param ssid of the network that has failed connection + * @param bssid of the network that has failed connection, can be "any" + * @param reason Message id from WifiStateMachine for this failure + */ + private void updateFailureCountForNetwork(String ssid, String bssid, int reason) { + if (VDBG) { + Log.v(TAG, "updateFailureCountForNetwork: [" + ssid + ", " + bssid + ", " + + reason + "]"); + } + if (BSSID_ANY.equals(bssid)) { + incrementSsidFailureCount(ssid, reason); + } else { + // Bssid count is actually unused except for logging purposes + // SSID count is incremented within the BSSID counting method + incrementBssidFailureCount(ssid, bssid, reason); + } + } + + /** + * Update the per-SSID failure count + * @param ssid the ssid to increment failure count for + * @param reason the failure type to increment count for + */ + private void incrementSsidFailureCount(String ssid, int reason) { + Pair ssidFails = mSsidFailureCount.get(ssid); + if (ssidFails == null) { + if (DBG) { + Log.v(TAG, "updateFailureCountForNetwork: No networks for ssid = " + ssid); + } + return; + } + AvailableNetworkFailureCount failureCount = ssidFails.first; + failureCount.incrementFailureCount(reason); + } + + /** + * Update the per-BSSID failure count + * @param bssid the bssid to increment failure count for + * @param reason the failure type to increment count for + */ + private void incrementBssidFailureCount(String ssid, String bssid, int reason) { + AvailableNetworkFailureCount availableNetworkFailureCount = + mRecentAvailableNetworks.get(bssid); + if (availableNetworkFailureCount == null) { + if (DBG) { + Log.d(TAG, "updateFailureCountForNetwork: Unable to find Network [" + ssid + + ", " + bssid + "]"); + } + return; + } + if (!availableNetworkFailureCount.ssid.equals(ssid)) { + if (DBG) { + Log.d(TAG, "updateFailureCountForNetwork: Failed connection attempt has" + + " wrong ssid. Failed [" + ssid + ", " + bssid + "], buffered [" + + availableNetworkFailureCount.ssid + ", " + bssid + "]"); + } + return; + } + if (availableNetworkFailureCount.config == null) { + if (VDBG) { + Log.v(TAG, "updateFailureCountForNetwork: network has no config [" + + ssid + ", " + bssid + "]"); + } + } + availableNetworkFailureCount.incrementFailureCount(reason); + incrementSsidFailureCount(ssid, reason); + } + + /** + * Clear failure counts for each network in recentAvailableNetworks + */ + private void clearAllFailureCounts() { + if (VDBG) Log.v(TAG, "clearAllFailureCounts."); + for (Map.Entry entry + : mRecentAvailableNetworks.entrySet()) { + final AvailableNetworkFailureCount failureCount = entry.getValue(); + entry.getValue().resetCounts(); + } + for (Map.Entry> entry + : mSsidFailureCount.entrySet()) { + final AvailableNetworkFailureCount failureCount = entry.getValue().first; + failureCount.resetCounts(); + } + } /** * Gets the buffer of recently available networks */ @@ -110,10 +279,67 @@ public class WifiLastResortWatchdog { : mRecentAvailableNetworks.entrySet()) { sb.append("\n " + entry.getKey() + ": " + entry.getValue()); } + sb.append("\nmSsidFailureCount:"); + for (Map.Entry> entry : + mSsidFailureCount.entrySet()) { + final AvailableNetworkFailureCount failureCount = entry.getValue().first; + final Integer apCount = entry.getValue().second; + sb.append("\n" + entry.getKey() + ": " + apCount + ", " + + failureCount.toString()); + } return sb.toString(); } - static class AvailableNetworkFailureCount { + /** + * @param bssid bssid to check the failures for + * @return true if any failure count is over FAILURE_THRESHOLD + */ + public boolean isOverFailureThreshold(String bssid) { + if ((getFailureCount(bssid, FAILURE_CODE_ASSOCIATION) >= FAILURE_THRESHOLD) + || (getFailureCount(bssid, FAILURE_CODE_AUTHENTICATION) >= FAILURE_THRESHOLD) + || (getFailureCount(bssid, FAILURE_CODE_DHCP) >= FAILURE_THRESHOLD)) { + return true; + } + return false; + } + + /** + * Get the failure count for a specific bssid. This actually checks the ssid attached to the + * BSSID and returns the SSID count + * @param reason failure reason to get count for + */ + public int getFailureCount(String bssid, int reason) { + AvailableNetworkFailureCount availableNetworkFailureCount = + mRecentAvailableNetworks.get(bssid); + if (availableNetworkFailureCount == null) { + return 0; + } + String ssid = availableNetworkFailureCount.ssid; + Pair ssidFails = mSsidFailureCount.get(ssid); + if (ssidFails == null) { + if (DBG) { + Log.d(TAG, "getFailureCount: Could not find SSID count for " + ssid); + } + return 0; + } + final AvailableNetworkFailureCount failCount = ssidFails.first; + switch (reason) { + case FAILURE_CODE_ASSOCIATION: + return failCount.associationRejection; + case FAILURE_CODE_AUTHENTICATION: + return failCount.authenticationFailure; + case FAILURE_CODE_DHCP: + return failCount.dhcpFailure; + default: + return 0; + } + } + + /** + * This class holds the failure counts for an 'available network' (one of the potential + * candidates for connection, as determined by framework). + */ + public static class AvailableNetworkFailureCount { /** * WifiConfiguration associated with this network. Can be null for Ephemeral networks */ @@ -121,17 +347,17 @@ public class WifiLastResortWatchdog { /** * SSID of the network (from ScanDetail) */ - public String Ssid = ""; + public String ssid = ""; /** - * Number of times network has failed for this reason + * Number of times network has failed due to Association Rejection */ public int associationRejection = 0; /** - * Number of times network has failed for this reason + * Number of times network has failed due to Authentication Failure or SSID_TEMP_DISABLED */ - public int authenticationRejection = 0; + public int authenticationFailure = 0; /** - * Number of times network has failed for this reason + * Number of times network has failed due to DHCP failure */ public int dhcpFailure = 0; /** @@ -143,18 +369,39 @@ public class WifiLastResortWatchdog { config = config; } + /** + * @param reason failure reason to increment count for + */ + public void incrementFailureCount(int reason) { + switch (reason) { + case FAILURE_CODE_ASSOCIATION: + associationRejection++; + break; + case FAILURE_CODE_AUTHENTICATION: + authenticationFailure++; + break; + case FAILURE_CODE_DHCP: + dhcpFailure++; + break; + default: //do nothing + } + } + + /** + * Set all failure counts for this network to 0 + */ void resetCounts() { associationRejection = 0; - authenticationRejection = 0; + authenticationFailure = 0; dhcpFailure = 0; } public String toString() { - return Ssid + ", HasEverConnected: " + ((config != null) + return ssid + ", HasEverConnected: " + ((config != null) ? config.getNetworkSelectionStatus().getHasEverConnected() : false) + ", Failures: {" + "Assoc: " + associationRejection - + ", Auth: " + authenticationRejection + + ", Auth: " + authenticationFailure + ", Dhcp: " + dhcpFailure + "}" + ", Age: " + age; diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 9ab7fd206..bd3cd1c30 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -1243,6 +1243,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss sendMessage(CMD_IPV4_PROVISIONING_SUCCESS, dhcpResults); } else { sendMessage(CMD_IPV4_PROVISIONING_FAILURE); + mWifiLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(getTargetSsid(), + mTargetRoamBSSID, + WifiLastResortWatchdog.FAILURE_CODE_DHCP); } } @@ -5343,6 +5346,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss reportConnectionAttemptEnd( WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_REJECTION, WifiMetricsProto.ConnectionEvent.HLF_NONE); + mWifiLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(getTargetSsid(), + bssid, + WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); break; case WifiMonitor.AUTHENTICATION_FAILURE_EVENT: mWifiLogger.captureBugReportData(WifiLogger.REPORT_REASON_AUTH_FAILURE); @@ -5356,6 +5362,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss reportConnectionAttemptEnd( WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE, WifiMetricsProto.ConnectionEvent.HLF_NONE); + mWifiLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(getTargetSsid(), + mTargetRoamBSSID, + WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); break; case WifiMonitor.SSID_TEMP_DISABLED: Log.e(TAG, "Supplicant SSID temporary disabled:" @@ -5367,6 +5376,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss reportConnectionAttemptEnd( WifiMetrics.ConnectionEvent.FAILURE_SSID_TEMP_DISABLED, WifiMetricsProto.ConnectionEvent.HLF_NONE); + mWifiLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(getTargetSsid(), + mTargetRoamBSSID, + WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); break; case WifiMonitor.SSID_REENABLED: Log.d(TAG, "Supplicant SSID reenable:" @@ -8326,4 +8338,16 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss } mContext.sendBroadcastAsUser(intent, UserHandle.ALL); } + + /** + * Gets the SSID from the WifiConfiguration pointed at by 'mTargetNetworkId' + * This should match the network config framework is attempting to connect to. + */ + private String getTargetSsid() { + WifiConfiguration currentConfig = mWifiConfigManager.getWifiConfiguration(mTargetNetworkId); + if (currentConfig != null) { + return currentConfig.SSID; + } + return null; + } } -- cgit v1.2.3 From 83f2b8087178705445e4d1618eaac832f9c633f4 Mon Sep 17 00:00:00 2001 From: Glen Kuhne Date: Tue, 19 Apr 2016 16:52:42 -0700 Subject: WifiLastResortWatchdog trigger logic Implemented trigger condition logic that is checked after a failure is counted. The condition takes into account: failure counts, wifi connected state, past connections to saved networks and whether the watchdog has fired since the wifi environment changed. Please note: This change only implements the logic for deciding when to trigger, not the trigger itself. BUG=27856709 Change-Id: I91ad6127a72ca24c72a5520348c4fff83f16b559 --- .../server/wifi/WifiLastResortWatchdog.java | 107 ++++++++++++++++++++- .../com/android/server/wifi/WifiStateMachine.java | 2 + 2 files changed, 104 insertions(+), 5 deletions(-) (limited to 'service') diff --git a/service/java/com/android/server/wifi/WifiLastResortWatchdog.java b/service/java/com/android/server/wifi/WifiLastResortWatchdog.java index 6c069ade9..adb8771ea 100644 --- a/service/java/com/android/server/wifi/WifiLastResortWatchdog.java +++ b/service/java/com/android/server/wifi/WifiLastResortWatchdog.java @@ -72,6 +72,11 @@ public class WifiLastResortWatchdog { */ private Map> mSsidFailureCount = new HashMap<>(); + // Tracks: if WifiStateMachine is in ConnectedState + private boolean mWifiIsConnected = false; + // Is Watchdog allowed to trigger now? Set to false after triggering. Set to true after + // successfully connecting or a new network (SSID) becomes available to connect to. + private boolean mWatchdogAllowedToTrigger = true; /** * Refreshes recentAvailableNetworks with the latest available networks @@ -108,6 +113,7 @@ public class WifiLastResortWatchdog { // This is a new SSID, create new FailureCount for it and set AP count to 1 ssidFailsAndApCount = Pair.create(new AvailableNetworkFailureCount(config), 1); + setWatchdogTriggerEnabled(true); } else { final Integer numberOfAps = ssidFailsAndApCount.second; // This is not a new SSID, increment the AP count for it @@ -170,7 +176,35 @@ public class WifiLastResortWatchdog { } // Update failure count for the failing network updateFailureCountForNetwork(ssid, bssid, reason); - return false; + + // Have we met conditions to trigger the Watchdog Wifi restart? + boolean isRestartNeeded = checkTriggerCondition(); + if (isRestartNeeded) { + // Stop the watchdog from triggering until re-enabled + setWatchdogTriggerEnabled(false); + restartWifiStack(); + // increment various watchdog trigger count stats + incrementWifiMetricsTriggerCounts(); + clearAllFailureCounts(); + } + return isRestartNeeded; + } + + /** + * Handles transitions entering and exiting WifiStateMachine ConnectedState + * Used to track wifistate, and perform watchdog count reseting + * @param isEntering true if called from ConnectedState.enter(), false for exit() + */ + public void connectedStateTransition(boolean isEntering) { + if (VDBG) Log.v(TAG, "connectedStateTransition: isEntering = " + isEntering); + mWifiIsConnected = isEntering; + if (isEntering) { + // We connected to something! Reset failure counts for everything + clearAllFailureCounts(); + // If the watchdog trigger was disabled (it triggered), connecting means we did + // something right, re-enable it so it can fire again. + setWatchdogTriggerEnabled(true); + } } /** @@ -246,6 +280,58 @@ public class WifiLastResortWatchdog { incrementSsidFailureCount(ssid, reason); } + /** + * Check trigger condition: For all available networks, have we met a failure threshold for each + * of them, and have previously connected to at-least one of the available networks + * @return is the trigger condition true + */ + private boolean checkTriggerCondition() { + if (VDBG) Log.v(TAG, "checkTriggerCondition:"); + // Don't check Watchdog trigger if wifi is in a connected state + // (This should not occur, but we want to protect against any race conditions) + if (mWifiIsConnected) return false; + // Don't check Watchdog trigger if trigger is not enabled + if (!mWatchdogAllowedToTrigger) return false; + + boolean atleastOneNetworkHasEverConnected = false; + for (Map.Entry entry + : mRecentAvailableNetworks.entrySet()) { + if (entry.getValue().config != null + && entry.getValue().config.getNetworkSelectionStatus().getHasEverConnected()) { + atleastOneNetworkHasEverConnected = true; + } + if (!isOverFailureThreshold(entry.getKey())) { + // This available network is not over failure threshold, meaning we still have a + // network to try connecting to + return false; + } + } + // We have met the failure count for every available network & there is at-least one network + // we have previously connected to present. + if (VDBG) { + Log.v(TAG, "checkTriggerCondition: return = " + atleastOneNetworkHasEverConnected); + } + return atleastOneNetworkHasEverConnected; + } + + /** + * Restart Supplicant, Driver & return WifiStateMachine to InitialState + */ + private void restartWifiStack() { + if (VDBG) Log.v(TAG, "restartWifiStack."); + Log.i(TAG, "Triggered."); + if (DBG) Log.d(TAG, toString()); + // + } + + /** + * Update WifiMetrics with various Watchdog stats (trigger counts, tracked network count) + */ + private void incrementWifiMetricsTriggerCounts() { + if (VDBG) Log.v(TAG, "incrementWifiMetricsTriggerCounts."); + // + } + /** * Clear failure counts for each network in recentAvailableNetworks */ @@ -269,23 +355,34 @@ public class WifiLastResortWatchdog { return mRecentAvailableNetworks; } + /** + * Activates or deactivates the Watchdog trigger. Counting and network buffering still occurs + * @param enable true to enable the Watchdog trigger, false to disable it + */ + private void setWatchdogTriggerEnabled(boolean enable) { + if (VDBG) Log.v(TAG, "setWatchdogTriggerEnabled: enable = " + enable); + mWatchdogAllowedToTrigger = enable; + } + /** * Prints all networks & counts within mRecentAvailableNetworks to string */ public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("WifiLastResortWatchdog: " + mRecentAvailableNetworks.size() + " networks..."); + sb.append("mWatchdogAllowedToTrigger: ").append(mWatchdogAllowedToTrigger); + sb.append("\nmWifiIsConnected: ").append(mWifiIsConnected); + sb.append("\nmRecentAvailableNetworks: ").append(mRecentAvailableNetworks.size()); for (Map.Entry entry : mRecentAvailableNetworks.entrySet()) { - sb.append("\n " + entry.getKey() + ": " + entry.getValue()); + sb.append("\n ").append(entry.getKey()).append(": ").append(entry.getValue()); } sb.append("\nmSsidFailureCount:"); for (Map.Entry> entry : mSsidFailureCount.entrySet()) { final AvailableNetworkFailureCount failureCount = entry.getValue().first; final Integer apCount = entry.getValue().second; - sb.append("\n" + entry.getKey() + ": " + apCount + ", " - + failureCount.toString()); + sb.append("\n").append(entry.getKey()).append(": ").append(apCount).append(", ") + .append(failureCount.toString()); } return sb.toString(); } diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index bd3cd1c30..3af04208b 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -7187,6 +7187,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss mLastDriverRoamAttempt = 0; mTargetNetworkId = WifiConfiguration.INVALID_NETWORK_ID; + mWifiLastResortWatchdog.connectedStateTransition(true); } @Override public boolean processMessage(Message message) { @@ -7451,6 +7452,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss mLastDriverRoamAttempt = 0; mWhiteListedSsids = null; + mWifiLastResortWatchdog.connectedStateTransition(false); } } -- cgit v1.2.3