ConnectivityService: move reportNetworkConnectivity to handler

This patch moves reportNetworkConnectivity onto the handler of
ConnectivityService.

This allows:
  - to inspect NetworkAgentInfo on the ConnectivityService handler,
    which is always more correct than doing so on a Binder thread.
  - to improve locking policies around NetworkAgentInfo.

Test: $ runtest frameworks-net
Bug: 37119619, 36902662
Change-Id: I49a765826e65c29a1995242290e5e7544112c94e
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 56fa420..e386988 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -378,11 +378,6 @@
     private static final int EVENT_SET_ACCEPT_UNVALIDATED = 28;
 
     /**
-     * used to specify whether a network should not be penalized when it becomes unvalidated.
-     */
-    private static final int EVENT_SET_AVOID_UNVALIDATED = 35;
-
-    /**
      * used to ask the user to confirm a connection to an unvalidated network.
      * obj  = network
      */
@@ -399,6 +394,16 @@
      */
     private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31;
 
+    /**
+     * used to specify whether a network should not be penalized when it becomes unvalidated.
+     */
+    private static final int EVENT_SET_AVOID_UNVALIDATED = 35;
+
+    /**
+     * used to trigger revalidation of a network.
+     */
+    private static final int EVENT_REVALIDATE_NETWORK = 36;
+
     private static String eventName(int what) {
         return sMagicDecoderRing.get(what, Integer.toString(what));
     }
@@ -2950,6 +2955,11 @@
                     }
                     break;
                 }
+                case EVENT_REVALIDATE_NETWORK: {
+                    boolean hasConnectivity = (msg.arg2 == 1);
+                    handleReportNetworkConnectivity((Network) msg.obj, msg.arg1, hasConnectivity);
+                    break;
+                }
             }
         }
     }
@@ -3157,8 +3167,14 @@
     public void reportNetworkConnectivity(Network network, boolean hasConnectivity) {
         enforceAccessPermission();
         enforceInternetPermission();
+        final int uid = Binder.getCallingUid();
+        final int connectivityInfo = hasConnectivity ? 1 : 0;
+        mHandler.sendMessage(
+                mHandler.obtainMessage(EVENT_REVALIDATE_NETWORK, uid, connectivityInfo, network));
+    }
 
-        // TODO: execute this logic on ConnectivityService handler.
+    private void handleReportNetworkConnectivity(
+            Network network, int uid, boolean hasConnectivity) {
         final NetworkAgentInfo nai;
         if (network == null) {
             nai = getDefaultNetwork();
@@ -3173,10 +3189,9 @@
         if (hasConnectivity == nai.lastValidated) {
             return;
         }
-        final int uid = Binder.getCallingUid();
         if (DBG) {
-            log("reportNetworkConnectivity(" + nai.network.netId + ", " + hasConnectivity +
-                    ") by " + uid);
+            int netid = nai.network.netId;
+            log("reportNetworkConnectivity(" + netid + ", " + hasConnectivity + ") by " + uid);
         }
         // Validating a network that has not yet connected could result in a call to
         // rematchNetworkAndRequests() which is not meant to work on such networks.