merge in lmp-mr1-release history after reset to cfa3bfefdaebf6213a067fa2fc6e377b4f25605a
diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java
index 05f4295..c4d022f 100644
--- a/service/java/com/android/server/wifi/WifiConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiConfigStore.java
@@ -2472,7 +2472,7 @@
     private void readIpAndProxyConfigurations() {
         SparseArray<IpConfiguration> networks = super.readIpAndProxyConfigurations(ipConfigFile);
 
-        if (networks.size() == 0) {
+        if (networks == null || networks.size() == 0) {
             // IpConfigStore.readIpAndProxyConfigurations has already logged an error.
             return;
         }
@@ -3075,6 +3075,11 @@
                             }
                             link.linkedConfigurations.put(config.configKey(), Integer.valueOf(1));
                             config.linkedConfigurations.put(link.configKey(), Integer.valueOf(1));
+
+                            // Carry over the Ip configuration
+                            if (link.getIpConfiguration() != null) {
+                                config.setIpConfiguration(link.getIpConfiguration());
+                            }
                         } else {
                             config = null;
                         }
diff --git a/service/java/com/android/server/wifi/WifiMonitor.java b/service/java/com/android/server/wifi/WifiMonitor.java
index d739d29..0e6c8a5 100644
--- a/service/java/com/android/server/wifi/WifiMonitor.java
+++ b/service/java/com/android/server/wifi/WifiMonitor.java
@@ -666,12 +666,25 @@
             } else {
                 if (DBG) Log.d(TAG, "Sending to all monitors because there's no matching iface");
                 boolean done = false;
+                boolean isMonitoring = false;
+                boolean isTerminating = false;
+                if (eventStr.startsWith(EVENT_PREFIX_STR)
+                        && eventStr.contains(TERMINATING_STR)) {
+                    isTerminating = true;
+                }
                 for (WifiMonitor monitor : mIfaceMap.values()) {
-                    if (monitor.mMonitoring && monitor.dispatchEvent(eventStr, iface)) {
-                        done = true;
+                    if (monitor.mMonitoring) {
+                        isMonitoring = true;
+                        if (monitor.dispatchEvent(eventStr, iface)) {
+                            done = true;
+                        }
                     }
                 }
 
+                if (!isMonitoring && isTerminating) {
+                    done = true;
+                }
+
                 if (done) {
                     mConnected = false;
                 }
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 9eb7ef4..ac7261e 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -398,6 +398,7 @@
     private AsyncChannel mWifiP2pChannel;
     private AsyncChannel mWifiApConfigChannel;
 
+    private int mConnectionRequests = 0;
     private WifiNetworkFactory mNetworkFactory;
     private WifiNetworkAgent mNetworkAgent;
 
@@ -2326,6 +2327,7 @@
         pw.println("mEnableBackgroundScan " + mEnableBackgroundScan);
         pw.println("mLastSetCountryCode " + mLastSetCountryCode);
         pw.println("mPersistedCountryCode " + mPersistedCountryCode);
+        mNetworkFactory.dump(fd, pw, args);
         pw.println();
         mWifiConfigStore.dump(fd, pw, args);
     }
@@ -2345,6 +2347,16 @@
     }
 
     /**
+     * helper, prints the milli time since boot wi and w/o suspended time
+     */
+    String printTime() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(" rt=").append(SystemClock.uptimeMillis());
+        sb.append("/").append(SystemClock.elapsedRealtime());
+        return sb.toString();
+    }
+
+    /**
      * Return the additional string to be logged by LogRec, default
      *
      * @param msg that was processed
@@ -2353,7 +2365,6 @@
     protected String getLogRecString(Message msg) {
         WifiConfiguration config;
         Long now;
-        long milli;
         String report;
         StringBuilder sb = new StringBuilder();
         if (mScreenOn) {
@@ -2410,12 +2421,11 @@
                 }
                 break;
             case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
-                milli = SystemClock.elapsedRealtime();
                 sb.append(" ");
                 sb.append(Integer.toString(msg.arg1));
                 sb.append(" ");
                 sb.append(Integer.toString(msg.arg2));
-                sb.append(" rt=").append(milli).append(" ");
+                sb.append(printTime());
                 StateChangeResult stateChangeResult = (StateChangeResult) msg.obj;
                 if (stateChangeResult != null) {
                     sb.append(stateChangeResult.toString());
@@ -2483,8 +2493,7 @@
                     sb.append(bssid);
                 }
                 sb.append(" blacklist=" + Boolean.toString(didBlackListBSSID));
-                milli = SystemClock.elapsedRealtime();
-                sb.append(" rt=").append(milli);
+                sb.append(printTime());
                 break;
             case WifiMonitor.SCAN_RESULTS_EVENT:
                 sb.append(" ");
@@ -2525,8 +2534,7 @@
                 if (config != null) {
                     sb.append(" ").append(config.configKey());
                 }
-                milli = SystemClock.elapsedRealtime();
-                sb.append(" rt=").append(milli);
+                sb.append(printTime());
                 break;
             case CMD_TARGET_BSSID:
             case CMD_ASSOCIATED_BSSID:
@@ -2541,8 +2549,7 @@
                     sb.append(" Target=").append(mTargetRoamBSSID);
                 }
                 sb.append(" roam=").append(Integer.toString(mAutoRoaming));
-                milli = SystemClock.elapsedRealtime();
-                sb.append(" rt=").append(milli);
+                sb.append(printTime());
                 break;
             case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
                 if (msg.obj != null) {
@@ -2560,8 +2567,7 @@
                 if (linkDebouncing) {
                     sb.append(" debounce");
                 }
-                milli = SystemClock.elapsedRealtime();
-                sb.append(" rt=").append(milli);
+                sb.append(printTime());
                 break;
             case WifiMonitor.SSID_TEMP_DISABLED:
             case WifiMonitor.SSID_REENABLED:
@@ -2593,8 +2599,7 @@
                         sb.append(" bssid=").append(mWifiInfo.getBSSID());
                     }
                 }
-                milli = SystemClock.elapsedRealtime();
-                sb.append(" rt=").append(milli);
+                sb.append(printTime());
                 break;
             case CMD_RSSI_POLL:
             case CMD_UNWANTED_NETWORK:
@@ -2645,8 +2650,7 @@
                     sb.append(" ").append(mTargetRoamBSSID);
                 }
                 sb.append(" roam=").append(Integer.toString(mAutoRoaming));
-                milli = SystemClock.elapsedRealtime();
-                sb.append(" rt=").append(milli);
+                sb.append(printTime());
                 config = getCurrentWifiConfiguration();
                 if (config != null) {
                     sb.append(" ").append(config.configKey());
@@ -2681,8 +2685,7 @@
                 }
                 sb.append(" roam=").append(Integer.toString(mAutoRoaming));
                 sb.append(" fail count=").append(Integer.toString(mRoamFailCount));
-                milli = SystemClock.elapsedRealtime();
-                sb.append(" rt=").append(milli);
+                sb.append(printTime());
                 break;
             case CMD_ADD_OR_UPDATE_NETWORK:
                 sb.append(" ");
@@ -2818,8 +2821,7 @@
                     sb.append(",").append(mWifiInfo.txBad);
                     sb.append(",").append(mWifiInfo.txRetries);
                 }
-                milli = SystemClock.elapsedRealtime();
-                sb.append(" rt=").append(milli);
+                sb.append(printTime());
                 sb.append(String.format(" bcn=%d", mRunningBeaconCount));
                 break;
             case CMD_UPDATE_LINKPROPERTIES:
@@ -3325,7 +3327,8 @@
                 || state == SupplicantState.ASSOCIATING
                 || state == SupplicantState.AUTHENTICATING
                 || state == SupplicantState.FOUR_WAY_HANDSHAKE
-                || state == SupplicantState.GROUP_HANDSHAKE) {
+                || state == SupplicantState.GROUP_HANDSHAKE
+                || mConnectionRequests == 0) {
             // Dont attempt auto-joining again while we are already attempting to join
             // and/or obtaining Ip address
             attemptAutoJoin = false;
@@ -3790,17 +3793,8 @@
     }
 
     private boolean isProvisioned(LinkProperties lp) {
-        // LinkProperties#isProvisioned returns true even if all we have is an IPv4 address and no
-        // connectivity. This turns out not to be very useful, because we can't distinguish it from
-        // a state where we have an IPv4 address assigned to the interface but are still running
-        // DHCP.
-        // TODO: Fix LinkProperties and remove this function.
-        if (mWifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
-            return lp.hasIPv4Address();
-        } else {
-            return (lp.hasIPv4Address() && lp.hasIPv4DefaultRoute() && lp.hasIPv4DnsServer()) ||
-                   (lp.hasGlobalIPv6Address() && lp.hasIPv6DefaultRoute() && lp.hasIPv6DnsServer());
-        }
+        return lp.isProvisioned() ||
+               (mWifiConfigStore.isUsingStaticIp(mLastNetworkId) && lp.hasIPv4Address());
     }
 
     /**
@@ -4488,6 +4482,7 @@
 
         @Override
         protected void needNetworkFor(NetworkRequest networkRequest, int score) {
+            ++mConnectionRequests;
             if (!networkRequest.networkCapabilities.hasCapability(
                     NetworkCapabilities.NET_CAPABILITY_TRUSTED)) {
                 if (++mUntrustedReqCount == 1) {
@@ -4498,6 +4493,7 @@
 
         @Override
         protected void releaseNetworkFor(NetworkRequest networkRequest) {
+            --mConnectionRequests;
             if (!networkRequest.networkCapabilities.hasCapability(
                     NetworkCapabilities.NET_CAPABILITY_TRUSTED)) {
                 if (--mUntrustedReqCount == 0) {
@@ -4505,6 +4501,12 @@
                 }
             }
         }
+
+        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            pw.println("mConnectionRequests " + mConnectionRequests);
+            pw.println("mUntrustedReqCount " + mUntrustedReqCount);
+        }
+
     }
     /********************************************************
      * HSM states
@@ -7344,7 +7346,7 @@
                         mWifiConfigStore.handleBadNetworkDisconnectReport(mLastNetworkId, mWifiInfo);
                         mWifiNative.disconnect();
                         transitionTo(mDisconnectingState);
-                    } else if (message.arg1 == network_status_unwanted_disconnect) {
+                    } else if (message.arg1 == network_status_unwanted_disable_autojoin) {
                         config = getCurrentWifiConfiguration();
                         if (config != null) {
                             // Disable autojoin