Connectivity metrics: add transports to validation probes

This patch adds transports info to ValidationProbeEvent and migrates
netId logging for this event to the topt-level netId field in
ConnectivityMetricsEvent.

Test: modified unit tests. $ runtest frameworks-net passes
Bug: 3490169
Change-Id: Ibf51049ba8901ae5ca4ea86e2f500944a4738b5c
diff --git a/core/java/android/net/ConnectivityMetricsEvent.java b/core/java/android/net/ConnectivityMetricsEvent.java
index 6e468d2..63ccaae 100644
--- a/core/java/android/net/ConnectivityMetricsEvent.java
+++ b/core/java/android/net/ConnectivityMetricsEvent.java
@@ -78,7 +78,10 @@
     public String toString() {
         StringBuilder buffer = new StringBuilder("ConnectivityMetricsEvent(");
         buffer.append(String.format("%tT.%tL", timestamp, timestamp));
-        // TODO: add transports, netId
+        // TODO: add transports
+        if (netId != 0) {
+            buffer.append(", ").append(netId);
+        }
         if (ifname != null) {
             buffer.append(", ").append(ifname);
         }
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 0765c86..8665b9c 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -478,6 +478,17 @@
     }
 
     /**
+     * Gets all the transports set on this {@code NetworkCapability} instance.
+     *
+     * @return a bit field composed of up bits at indexes defined by
+     * {@code NetworkCapabilities.TRANSPORT_*} values for this instance.
+     * @hide
+     */
+    public long getTransports() {
+        return mTransportTypes;
+    }
+
+    /**
      * Tests for the presence of a transport on this instance.
      *
      * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be tested for.
diff --git a/core/java/android/net/metrics/IpConnectivityLog.java b/core/java/android/net/metrics/IpConnectivityLog.java
index 8f5e673..ac727ca 100644
--- a/core/java/android/net/metrics/IpConnectivityLog.java
+++ b/core/java/android/net/metrics/IpConnectivityLog.java
@@ -111,6 +111,21 @@
 
     /**
      * Log an IpConnectivity event.
+     * @param netid the id of the network associated with the event.
+     * @param transports the current transports of the network associated with the event, as defined
+     * in NetworkCapabilities.
+     * @param data is a Parcelable instance representing the event.
+     * @return true if the event was successfully logged.
+     */
+    public boolean log(int netid, long transports, Parcelable data) {
+        ConnectivityMetricsEvent ev = makeEv(data);
+        ev.netId = netid;
+        ev.transports = transports;
+        return log(ev);
+    }
+
+    /**
+     * Log an IpConnectivity event.
      * @param data is a Parcelable instance representing the event.
      * @return true if the event was successfully logged.
      */
diff --git a/core/java/android/net/metrics/ValidationProbeEvent.java b/core/java/android/net/metrics/ValidationProbeEvent.java
index 70c6e84..1ad0929 100644
--- a/core/java/android/net/metrics/ValidationProbeEvent.java
+++ b/core/java/android/net/metrics/ValidationProbeEvent.java
@@ -48,26 +48,19 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface ReturnCode {}
 
-    public final int netId;
-    public final long durationMs;
+    public long durationMs;
     // probeType byte format (MSB to LSB):
     // byte 0: unused
     // byte 1: unused
     // byte 2: 0 = UNKNOWN, 1 = FIRST_VALIDATION, 2 = REVALIDATION
     // byte 3: PROBE_* constant
-    public final int probeType;
-    public final @ReturnCode int returnCode;
+    public int probeType;
+    public @ReturnCode int returnCode;
 
-    public ValidationProbeEvent(
-            int netId, long durationMs, int probeType, @ReturnCode int returnCode) {
-        this.netId = netId;
-        this.durationMs = durationMs;
-        this.probeType = probeType;
-        this.returnCode = returnCode;
+    public ValidationProbeEvent() {
     }
 
     private ValidationProbeEvent(Parcel in) {
-        netId = in.readInt();
         durationMs = in.readLong();
         probeType = in.readInt();
         returnCode = in.readInt();
@@ -75,7 +68,6 @@
 
     @Override
     public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(netId);
         out.writeLong(durationMs);
         out.writeInt(probeType);
         out.writeInt(returnCode);
@@ -111,7 +103,7 @@
 
     @Override
     public String toString() {
-        return String.format("ValidationProbeEvent(%d, %s:%d %s, %dms)", netId,
+        return String.format("ValidationProbeEvent(%s:%d %s, %dms)",
                 getProbeName(probeType), returnCode, getValidationStage(probeType), durationMs);
     }
 
diff --git a/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java b/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java
index 1eea0a9..ad66faa 100644
--- a/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java
+++ b/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java
@@ -210,7 +210,6 @@
     private static void setValidationProbeEvent(IpConnectivityEvent out, ValidationProbeEvent in) {
         IpConnectivityLogClass.ValidationProbeEvent validationProbeEvent =
                 new IpConnectivityLogClass.ValidationProbeEvent();
-        validationProbeEvent.networkId = netIdOf(in.netId);
         validationProbeEvent.latencyMs = (int) in.durationMs;
         validationProbeEvent.probeType = in.probeType;
         validationProbeEvent.probeResult = in.returnCode;
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index cf33313..d591858 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -1048,8 +1048,12 @@
     }
 
     private void logValidationProbe(long durationMs, int probeType, int probeResult) {
-        probeType =
-                ValidationProbeEvent.makeProbeType(probeType, validationStage().isFirstValidation);
-        mMetricsLog.log(new ValidationProbeEvent(mNetId, durationMs, probeType, probeResult));
+        long transports = mNetworkAgentInfo.networkCapabilities.getTransports();
+        boolean isFirstValidation = validationStage().isFirstValidation;
+        ValidationProbeEvent ev = new ValidationProbeEvent();
+        ev.probeType = ValidationProbeEvent.makeProbeType(probeType, isFirstValidation);
+        ev.returnCode = probeResult;
+        ev.durationMs = durationMs;
+        mMetricsLog.log(mNetId, transports, ev);
     }
 }
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
index dbc7861..d819b96 100644
--- a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
+++ b/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
@@ -402,7 +402,6 @@
     public void testValidationProbeEventSerialization() {
         ConnectivityMetricsEvent ev = describeIpEvent(
                 aType(ValidationProbeEvent.class),
-                anInt(120),
                 aLong(40730),
                 anInt(ValidationProbeEvent.PROBE_HTTP),
                 anInt(204));
@@ -417,9 +416,6 @@
                 "  transports: 0",
                 "  validation_probe_event <",
                 "    latency_ms: 40730",
-                "    network_id <",
-                "      network_id: 120",
-                "    >",
                 "    probe_result: 204",
                 "    probe_type: 1",
                 "  >",
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
index 50c92b3..68786d0 100644
--- a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
+++ b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
@@ -153,12 +153,18 @@
         apfStats.programUpdatesAll = 7;
         apfStats.programUpdatesAllowingMulticast = 3;
         apfStats.maxProgramSize = 2048;
+
+        ValidationProbeEvent validationEv = new ValidationProbeEvent();
+        validationEv.durationMs = 40730;
+        validationEv.probeType = ValidationProbeEvent.PROBE_HTTP;
+        validationEv.returnCode = 204;
+
         Parcelable[] events = {
             new IpReachabilityEvent(IpReachabilityEvent.NUD_FAILED),
             new DhcpClientEvent("SomeState", 192),
             new DefaultNetworkEvent(102, new int[]{1,2,3}, 101, true, false),
             new IpManagerEvent(IpManagerEvent.PROVISIONING_OK, 5678),
-            new ValidationProbeEvent(120, 40730, ValidationProbeEvent.PROBE_HTTP, 204),
+            validationEv,
             apfStats,
             new RaEvent(2000, 400, 300, -1, 1000, -1)
         };
@@ -235,9 +241,6 @@
                 "  transports: 0",
                 "  validation_probe_event <",
                 "    latency_ms: 40730",
-                "    network_id <",
-                "      network_id: 120",
-                "    >",
                 "    probe_result: 204",
                 "    probe_type: 1",
                 "  >",