merge in lmp-mr1-nova-release history after reset to lmp-mr1-dev
diff --git a/service/java/com/android/server/wifi/WifiAutoJoinController.java b/service/java/com/android/server/wifi/WifiAutoJoinController.java
index b86f776..c7da179 100644
--- a/service/java/com/android/server/wifi/WifiAutoJoinController.java
+++ b/service/java/com/android/server/wifi/WifiAutoJoinController.java
@@ -1520,6 +1520,29 @@
             if (config.visibility == null) {
                 continue;
             }
+
+            if (config.lastRoamingFailure != 0
+                    && currentConfiguration != null
+                    && (lastSelectedConfiguration == null
+                    || !config.configKey().equals(lastSelectedConfiguration))) {
+                // Apply blacklisting for roaming to this config if:
+                //   - the target config had a recent roaming failure
+                //   - we are currently associated
+                //   - the target config is not the last selected
+                if (now > config.lastRoamingFailure
+                        && (now - config.lastRoamingFailure)
+                        < config.roamingFailureBlackListTimeMilli) {
+                    if (DBG) {
+                        logDbg("compareNetwork not switching to " + config.configKey()
+                                + " from current " + currentConfiguration.configKey()
+                                + " because it is blacklisted due to roam failure, "
+                                + " blacklist remain time = "
+                                + (now - config.lastRoamingFailure) + " ms");
+                    }
+                    continue;
+                }
+            }
+
             int boost = config.autoJoinUseAggressiveJoinAttemptThreshold + weakRssiBailCount;
             if ((config.visibility.rssi5 + boost)
                         < mWifiConfigStore.thresholdInitialAutoJoinAttemptMin5RSSI
diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java
index f347d56..94752d3 100644
--- a/service/java/com/android/server/wifi/WifiConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiConfigStore.java
@@ -342,6 +342,10 @@
 
     public int associatedPartialScanPeriodMilli;
 
+    // Sane value for roam blacklisting (not switching to a network if already associated)
+    // 2 days
+    public int networkSwitchingBlackListPeriodMilli = 2 * 24 * 60 * 60 * 1000;
+
     public int bandPreferenceBoostFactor5 = 5; // Boost by 5 dB per dB above threshold
     public int bandPreferencePenaltyFactor5 = 2; // Penalize by 2 dB per dB below threshold
     public int bandPreferencePenaltyThreshold5 = WifiConfiguration.G_BAND_PREFERENCE_RSSI_THRESHOLD;
@@ -548,6 +552,9 @@
 
         scanResultRssiLevelPatchUp = mContext.getResources().getInteger(
                 R.integer.config_wifi_framework_scan_result_rssi_level_patchup_value);
+
+        networkSwitchingBlackListPeriodMilli = mContext.getResources().getInteger(
+                R.integer.config_wifi_network_switching_blacklist_time);
     }
 
     void enableVerboseLogging(int verbose) {
@@ -928,6 +935,19 @@
         }
     }
 
+    void noteRoamingFailure(WifiConfiguration config, int reason) {
+        if (config == null) return;
+        config.lastRoamingFailure = System.currentTimeMillis();
+        config.roamingFailureBlackListTimeMilli
+                = 2 * (config.roamingFailureBlackListTimeMilli + 1000);
+        if (config.roamingFailureBlackListTimeMilli
+                > networkSwitchingBlackListPeriodMilli) {
+            config.roamingFailureBlackListTimeMilli =
+                    networkSwitchingBlackListPeriodMilli;
+        }
+        config.lastRoamingFailureReason = reason;
+    }
+
     void saveWifiConfigBSSID(WifiConfiguration config) {
         // Sanity check the config is valid
         if (config == null || (config.networkId == INVALID_NETWORK_ID &&
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 2311e34..fb9e9fd 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -7470,8 +7470,15 @@
         @Override
         public boolean processMessage(Message message) {
             logStateAndMessage(message, getClass().getSimpleName());
-
+            WifiConfiguration config;
             switch (message.what) {
+                case CMD_IP_CONFIGURATION_LOST:
+                    config = getCurrentWifiConfiguration();
+                    if (config != null) {
+                        mWifiConfigStore.noteRoamingFailure(config,
+                                WifiConfiguration.ROAMING_FAILURE_IP_CONFIG);
+                    }
+                    return NOT_HANDLED;
                case WifiWatchdogStateMachine.POOR_LINK_DETECTED:
                     if (DBG) log("Roaming and Watchdog reports poor link -> ignore");
                     return HANDLED;
@@ -7557,6 +7564,11 @@
                             + " isRoaming=" + isRoaming()
                             + " roam=" + Integer.toString(mAutoRoaming));
                     if (message.arg1 == mLastNetworkId) {
+                        config = getCurrentWifiConfiguration();
+                        if (config != null) {
+                            mWifiConfigStore.noteRoamingFailure(config,
+                                    WifiConfiguration.ROAMING_FAILURE_AUTH_FAILURE);
+                        }
                         handleNetworkDisconnect();
                         transitionTo(mDisconnectingState);
                     }