Merge "Stop logging false error when lingering completes." into lmp-dev
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 3c219fd..70b402d 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -1298,7 +1298,7 @@
     }
 
     /**
-     * Callback for use with {@link ConnectivityManager#registerDefaultNetworkActiveListener}
+     * Callback for use with {@link ConnectivityManager#addDefaultNetworkActiveListener}
      * to find out when the system default network has gone in to a high power state.
      */
     public interface OnNetworkActiveListener {
@@ -1340,7 +1340,7 @@
      *
      * @param l The listener to be told when the network is active.
      */
-    public void registerDefaultNetworkActiveListener(final OnNetworkActiveListener l) {
+    public void addDefaultNetworkActiveListener(final OnNetworkActiveListener l) {
         INetworkActivityListener rl = new INetworkActivityListener.Stub() {
             @Override
             public void onNetworkActive() throws RemoteException {
@@ -1357,11 +1357,11 @@
 
     /**
      * Remove network active listener previously registered with
-     * {@link #registerDefaultNetworkActiveListener}.
+     * {@link #addDefaultNetworkActiveListener}.
      *
      * @param l Previously registered listener.
      */
-    public void unregisterDefaultNetworkActiveListener(OnNetworkActiveListener l) {
+    public void removeDefaultNetworkActiveListener(OnNetworkActiveListener l) {
         INetworkActivityListener rl = mNetworkActivityListeners.get(l);
         if (rl == null) {
             throw new IllegalArgumentException("Listener not registered: " + l);
diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java
index f9a25f9..c387055 100644
--- a/core/java/android/net/LinkAddress.java
+++ b/core/java/android/net/LinkAddress.java
@@ -274,7 +274,6 @@
 
     /**
      * Implement the Parcelable interface.
-     * @hide
      */
     public int describeContents() {
         return 0;
@@ -282,7 +281,6 @@
 
     /**
      * Implement the Parcelable interface.
-     * @hide
      */
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeByteArray(address.getAddress());
@@ -293,7 +291,6 @@
 
     /**
      * Implement the Parcelable interface.
-     * @hide
      */
     public static final Creator<LinkAddress> CREATOR =
         new Creator<LinkAddress>() {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index a811bb9..3062a92 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -425,8 +425,8 @@
 
     TelephonyManager mTelephonyManager;
 
-    // sequence number for Networks
-    private final static int MIN_NET_ID = 10; // some reserved marks
+    // sequence number for Networks; keep in sync with system/netd/NetworkController.cpp
+    private final static int MIN_NET_ID = 100; // some reserved marks
     private final static int MAX_NET_ID = 65535;
     private int mNextNetId = MIN_NET_ID;
 
@@ -793,14 +793,28 @@
     }
 
     /**
-     * Check if UID should be blocked from using the network represented by the
-     * given {@link NetworkStateTracker}.
+     * Check if UID should be blocked from using the network represented by the given networkType.
+     * @deprecated Uses mLegacyTypeTracker; cannot deal with multiple Networks of the same type.
      */
     private boolean isNetworkBlocked(int networkType, int uid) {
+        return isNetworkWithLinkPropertiesBlocked(getLinkPropertiesForType(networkType), uid);
+    }
+
+    /**
+     * Check if UID should be blocked from using the network represented by the given
+     * NetworkAgentInfo.
+     */
+    private boolean isNetworkBlocked(NetworkAgentInfo nai, int uid) {
+        return isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid);
+    }
+
+    /**
+     * Check if UID should be blocked from using the network with the given LinkProperties.
+     */
+    private boolean isNetworkWithLinkPropertiesBlocked(LinkProperties lp, int uid) {
         final boolean networkCostly;
         final int uidRules;
 
-        LinkProperties lp = getLinkPropertiesForType(networkType);
         final String iface = (lp == null ? "" : lp.getInterfaceName());
         synchronized (mRulesLock) {
             networkCostly = mMeteredIfaces.contains(iface);
@@ -819,17 +833,36 @@
      * Return a filtered {@link NetworkInfo}, potentially marked
      * {@link DetailedState#BLOCKED} based on
      * {@link #isNetworkBlocked}.
+     * @deprecated Uses mLegacyTypeTracker; cannot deal with multiple Networks of the same type.
      */
     private NetworkInfo getFilteredNetworkInfo(int networkType, int uid) {
         NetworkInfo info = getNetworkInfoForType(networkType);
         return getFilteredNetworkInfo(info, networkType, uid);
     }
 
+    /*
+     * @deprecated Uses mLegacyTypeTracker; cannot deal with multiple Networks of the same type.
+     */
     private NetworkInfo getFilteredNetworkInfo(NetworkInfo info, int networkType, int uid) {
         if (isNetworkBlocked(networkType, uid)) {
             // network is blocked; clone and override state
             info = new NetworkInfo(info);
             info.setDetailedState(DetailedState.BLOCKED, null, null);
+            if (VDBG) log("returning Blocked NetworkInfo");
+        }
+        if (mLockdownTracker != null) {
+            info = mLockdownTracker.augmentNetworkInfo(info);
+            if (VDBG) log("returning Locked NetworkInfo");
+        }
+        return info;
+    }
+
+    private NetworkInfo getFilteredNetworkInfo(NetworkAgentInfo nai, int uid) {
+        NetworkInfo info = nai.networkInfo;
+        if (isNetworkBlocked(nai, uid)) {
+            // network is blocked; clone and override state
+            info = new NetworkInfo(info);
+            info.setDetailedState(DetailedState.BLOCKED, null, null);
             if (DBG) log("returning Blocked NetworkInfo");
         }
         if (mLockdownTracker != null) {
@@ -946,7 +979,7 @@
         synchronized (nai) {
             if (nai.networkInfo == null) return null;
 
-            return getFilteredNetworkInfo(nai.networkInfo, nai.networkInfo.getType(), uid);
+            return getFilteredNetworkInfo(nai, uid);
         }
     }
 
@@ -1315,6 +1348,12 @@
 //        }
     }
 
+    private void enforceInternetPermission() {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.INTERNET,
+                "ConnectivityService");
+    }
+
     private void enforceAccessPermission() {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.ACCESS_NETWORK_STATE,
@@ -2468,7 +2507,22 @@
     }
 
     public void reportBadNetwork(Network network) {
-        //TODO
+        enforceAccessPermission();
+        enforceInternetPermission();
+
+        if (network == null) return;
+
+        final int uid = Binder.getCallingUid();
+        NetworkAgentInfo nai = null;
+        synchronized (mNetworkForNetId) {
+            nai = mNetworkForNetId.get(network.netId);
+        }
+        if (nai == null) return;
+        synchronized (nai) {
+            if (isNetworkBlocked(nai, uid)) return;
+
+            nai.networkMonitor.sendMessage(NetworkMonitor.CMD_FORCE_REEVALUATION, uid);
+        }
     }
 
     public ProxyInfo getProxy() {
@@ -4467,6 +4521,8 @@
             loge("Unknown NetworkAgentInfo in handleConnectionValidated");
             return;
         }
+        if (newNetwork.validated) return;
+        newNetwork.validated = true;
         boolean keep = newNetwork.isVPN();
         boolean isNewDefault = false;
         if (DBG) log("handleConnectionValidated for "+newNetwork.name());
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 5a97aee..bba786d 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -47,6 +47,7 @@
     public final NetworkMonitor networkMonitor;
     public final NetworkMisc networkMisc;
     public boolean created;
+    public boolean validated;
 
     // The list of NetworkRequests being satisfied by this Network.
     public final SparseArray<NetworkRequest> networkRequests = new SparseArray<NetworkRequest>();
@@ -68,6 +69,7 @@
         networkMonitor = new NetworkMonitor(context, handler, this);
         networkMisc = misc;
         created = false;
+        validated = false;
     }
 
     public void addRequest(NetworkRequest networkRequest) {