Backport l53e91db7 from master.

Prevents sending out ConnectivityManager broadcasts when the connection
is repeating the same major state.  This means continued wifi scanning
does not generate CM broadcasts (though wifi state broadcasts continue).

bug: 2265222
Dr No approval: jsh
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 78215b0..5c0f352 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -111,6 +111,7 @@
         public int mType;
         public int mRadio;
         public int mPriority;
+        public NetworkInfo.State mLastState;
         public NetworkAttributes(String init) {
             String fragments[] = init.split(",");
             mName = fragments[0].toLowerCase();
@@ -131,6 +132,7 @@
                 mType = ConnectivityManager.TYPE_MOBILE_HIPRI;
             }
             mPriority = Integer.parseInt(fragments[2]);
+            mLastState = NetworkInfo.State.UNKNOWN;
         }
         public boolean isDefault() {
             return (mType == mRadio);
@@ -1214,9 +1216,22 @@
             switch (msg.what) {
                 case NetworkStateTracker.EVENT_STATE_CHANGED:
                     info = (NetworkInfo) msg.obj;
+                    int type = info.getType();
+                    NetworkInfo.State state = info.getState();
+                    if (mNetAttributes[type].mLastState == state) {
+                        if (DBG) {
+                            // TODO - remove this after we validate the dropping doesn't break anything
+                            Log.d(TAG, "Dropping ConnectivityChange for " +
+                                    info.getTypeName() + ": " +
+                                    state + "/" + info.getDetailedState());
+                        }
+                        return;
+                    }
+                    mNetAttributes[type].mLastState = state;
+
                     if (DBG) Log.d(TAG, "ConnectivityChange for " +
                             info.getTypeName() + ": " +
-                            info.getState() + "/" + info.getDetailedState());
+                            state + "/" + info.getDetailedState());
 
                     // Connectivity state changed:
                     // [31-13] Reserved for future use
@@ -1234,10 +1249,9 @@
                     if (info.getDetailedState() ==
                             NetworkInfo.DetailedState.FAILED) {
                         handleConnectionFailure(info);
-                    } else if (info.getState() ==
-                            NetworkInfo.State.DISCONNECTED) {
+                    } else if (state == NetworkInfo.State.DISCONNECTED) {
                         handleDisconnect(info);
-                    } else if (info.getState() == NetworkInfo.State.SUSPENDED) {
+                    } else if (state == NetworkInfo.State.SUSPENDED) {
                         // TODO: need to think this over.
                         // the logic here is, handle SUSPENDED the same as
                         // DISCONNECTED. The only difference being we are
@@ -1246,7 +1260,7 @@
                         // opportunity to handle DISCONNECTED and SUSPENDED
                         // differently, or not.
                         handleDisconnect(info);
-                    } else if (info.getState() == NetworkInfo.State.CONNECTED) {
+                    } else if (state == NetworkInfo.State.CONNECTED) {
                         handleConnect(info);
                     }
                     break;