Connectivity metrics: change how interface names are logged

This patch deprecates the ifname field for specific metrics events of
types DhcpClientEvent, DhcpErrorEvent, IpReachabilityEvent and
IpManagerEvent.

Instead ifnames are logged in ConnectivityMetricsEvent, allowing for
link layer inference.

Test: updated unit tests, $ runtest frameworks-net passes
Bug: 34901696
Change-Id: I8bfabcb115bbd5289471d653c153a40bb48f28cd
diff --git a/core/java/android/net/ConnectivityMetricsEvent.java b/core/java/android/net/ConnectivityMetricsEvent.java
index 4faff62..6e468d2 100644
--- a/core/java/android/net/ConnectivityMetricsEvent.java
+++ b/core/java/android/net/ConnectivityMetricsEvent.java
@@ -76,7 +76,13 @@
 
     @Override
     public String toString() {
-        // TODO: add transports, netId, ifname
-        return String.format("ConnectivityMetricsEvent(%tT.%tL): %s", timestamp, timestamp, data);
+        StringBuilder buffer = new StringBuilder("ConnectivityMetricsEvent(");
+        buffer.append(String.format("%tT.%tL", timestamp, timestamp));
+        // TODO: add transports, netId
+        if (ifname != null) {
+            buffer.append(", ").append(ifname);
+        }
+        buffer.append("): ").append(data.toString());
+        return buffer.toString();
     }
 }
diff --git a/core/java/android/net/metrics/DhcpClientEvent.java b/core/java/android/net/metrics/DhcpClientEvent.java
index 7e30ab5..c5b78a5 100644
--- a/core/java/android/net/metrics/DhcpClientEvent.java
+++ b/core/java/android/net/metrics/DhcpClientEvent.java
@@ -31,25 +31,21 @@
     /** {@hide} Represents transitions from and to DhcpBoundState via DhcpRenewingState */
     public static final String RENEWING_BOUND = "RenewingBoundState";
 
-    public final String ifName;
     public final String msg;
     public final int durationMs;
 
-    public DhcpClientEvent(String ifName, String msg, int durationMs) {
-        this.ifName = ifName;
+    public DhcpClientEvent(String msg, int durationMs) {
         this.msg = msg;
         this.durationMs = durationMs;
     }
 
     private DhcpClientEvent(Parcel in) {
-        this.ifName = in.readString();
         this.msg = in.readString();
         this.durationMs = in.readInt();
     }
 
     @Override
     public void writeToParcel(Parcel out, int flags) {
-        out.writeString(ifName);
         out.writeString(msg);
         out.writeInt(durationMs);
     }
@@ -61,7 +57,7 @@
 
     @Override
     public String toString() {
-        return String.format("DhcpClientEvent(%s, %s, %dms)", ifName, msg, durationMs);
+        return String.format("DhcpClientEvent(%s, %dms)", msg, durationMs);
     }
 
     public static final Parcelable.Creator<DhcpClientEvent> CREATOR
diff --git a/core/java/android/net/metrics/DhcpErrorEvent.java b/core/java/android/net/metrics/DhcpErrorEvent.java
index f34ffdf..8b77197 100644
--- a/core/java/android/net/metrics/DhcpErrorEvent.java
+++ b/core/java/android/net/metrics/DhcpErrorEvent.java
@@ -54,7 +54,6 @@
     public static final int RECEIVE_ERROR              = makeErrorCode(MISC_ERROR, 2);
     public static final int PARSING_ERROR              = makeErrorCode(MISC_ERROR, 3);
 
-    public final String ifName;
     // error code byte format (MSB to LSB):
     // byte 0: error type
     // byte 1: error subtype
@@ -62,19 +61,16 @@
     // byte 3: optional code
     public final int errorCode;
 
-    public DhcpErrorEvent(String ifName, int errorCode) {
-        this.ifName = ifName;
+    public DhcpErrorEvent(int errorCode) {
         this.errorCode = errorCode;
     }
 
     private DhcpErrorEvent(Parcel in) {
-        this.ifName = in.readString();
         this.errorCode = in.readInt();
     }
 
     @Override
     public void writeToParcel(Parcel out, int flags) {
-        out.writeString(ifName);
         out.writeInt(errorCode);
     }
 
@@ -104,7 +100,7 @@
 
     @Override
     public String toString() {
-        return String.format("DhcpErrorEvent(%s, %s)", ifName, Decoder.constants.get(errorCode));
+        return String.format("DhcpErrorEvent(%s)", Decoder.constants.get(errorCode));
     }
 
     final static class Decoder {
diff --git a/core/java/android/net/metrics/IpConnectivityLog.java b/core/java/android/net/metrics/IpConnectivityLog.java
index 79094c0..8f5e673 100644
--- a/core/java/android/net/metrics/IpConnectivityLog.java
+++ b/core/java/android/net/metrics/IpConnectivityLog.java
@@ -99,6 +99,18 @@
 
     /**
      * Log an IpConnectivity event.
+     * @param ifname the network interface associated with the event.
+     * @param data is a Parcelable instance representing the event.
+     * @return true if the event was successfully logged.
+     */
+    public boolean log(String ifname, Parcelable data) {
+        ConnectivityMetricsEvent ev = makeEv(data);
+        ev.ifname = ifname;
+        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/IpManagerEvent.java b/core/java/android/net/metrics/IpManagerEvent.java
index 50dda7c..f5aea73 100644
--- a/core/java/android/net/metrics/IpManagerEvent.java
+++ b/core/java/android/net/metrics/IpManagerEvent.java
@@ -47,25 +47,21 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface EventType {}
 
-    public final String ifName;
     public final @EventType int eventType;
     public final long durationMs;
 
-    public IpManagerEvent(String ifName, @EventType int eventType, long duration) {
-        this.ifName = ifName;
+    public IpManagerEvent(@EventType int eventType, long duration) {
         this.eventType = eventType;
         this.durationMs = duration;
     }
 
     private IpManagerEvent(Parcel in) {
-        this.ifName = in.readString();
         this.eventType = in.readInt();
         this.durationMs = in.readLong();
     }
 
     @Override
     public void writeToParcel(Parcel out, int flags) {
-        out.writeString(ifName);
         out.writeInt(eventType);
         out.writeLong(durationMs);
     }
@@ -88,8 +84,8 @@
 
     @Override
     public String toString() {
-        return String.format("IpManagerEvent(%s, %s, %dms)",
-                ifName, Decoder.constants.get(eventType), durationMs);
+        return String.format("IpManagerEvent(%s, %dms)",
+                Decoder.constants.get(eventType), durationMs);
     }
 
     final static class Decoder {
diff --git a/core/java/android/net/metrics/IpReachabilityEvent.java b/core/java/android/net/metrics/IpReachabilityEvent.java
index d69e806..019c2c5 100644
--- a/core/java/android/net/metrics/IpReachabilityEvent.java
+++ b/core/java/android/net/metrics/IpReachabilityEvent.java
@@ -41,7 +41,6 @@
     /** Neighbor unreachable notification from kernel, IP provisioning is also lost. */
     public static final int PROVISIONING_LOST_ORGANIC = 5 << 8;
 
-    public final String ifName;
     // eventType byte format (MSB to LSB):
     // byte 0: unused
     // byte 1: unused
@@ -49,19 +48,16 @@
     // byte 3: when byte 2 == PROBE, errno code from RTNetlink or IpReachabilityMonitor.
     public final int eventType;
 
-    public IpReachabilityEvent(String ifName, int eventType) {
-        this.ifName = ifName;
+    public IpReachabilityEvent(int eventType) {
         this.eventType = eventType;
     }
 
     private IpReachabilityEvent(Parcel in) {
-        this.ifName = in.readString();
         this.eventType = in.readInt();
     }
 
     @Override
     public void writeToParcel(Parcel out, int flags) {
-        out.writeString(ifName);
         out.writeInt(eventType);
     }
 
@@ -97,7 +93,7 @@
         int hi = eventType & 0xff00;
         int lo = eventType & 0x00ff;
         String eventName = Decoder.constants.get(hi);
-        return String.format("IpReachabilityEvent(%s, %s:%02x)", ifName, eventName, lo);
+        return String.format("IpReachabilityEvent(%s:%02x)", eventName, lo);
     }
 
     final static class Decoder {
diff --git a/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java b/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java
index 4991b2b..1eea0a9 100644
--- a/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java
+++ b/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java
@@ -152,14 +152,12 @@
 
     private static void setDhcpErrorEvent(IpConnectivityEvent out, DhcpErrorEvent in) {
         IpConnectivityLogClass.DHCPEvent dhcpEvent = new IpConnectivityLogClass.DHCPEvent();
-        dhcpEvent.ifName = in.ifName;
         dhcpEvent.setErrorCode(in.errorCode);
         out.setDhcpEvent(dhcpEvent);
     }
 
     private static void setDhcpClientEvent(IpConnectivityEvent out, DhcpClientEvent in) {
         IpConnectivityLogClass.DHCPEvent dhcpEvent = new IpConnectivityLogClass.DHCPEvent();
-        dhcpEvent.ifName = in.ifName;
         dhcpEvent.setStateTransition(in.msg);
         dhcpEvent.durationMs = in.durationMs;
         out.setDhcpEvent(dhcpEvent);
@@ -178,7 +176,6 @@
     private static void setIpManagerEvent(IpConnectivityEvent out, IpManagerEvent in) {
         IpConnectivityLogClass.IpProvisioningEvent ipProvisioningEvent =
                 new IpConnectivityLogClass.IpProvisioningEvent();
-        ipProvisioningEvent.ifName = in.ifName;
         ipProvisioningEvent.eventType = in.eventType;
         ipProvisioningEvent.latencyMs = (int) in.durationMs;
         out.setIpProvisioningEvent(ipProvisioningEvent);
@@ -187,7 +184,6 @@
     private static void setIpReachabilityEvent(IpConnectivityEvent out, IpReachabilityEvent in) {
         IpConnectivityLogClass.IpReachabilityEvent ipReachabilityEvent =
                 new IpConnectivityLogClass.IpReachabilityEvent();
-        ipReachabilityEvent.ifName = in.ifName;
         ipReachabilityEvent.eventType = in.eventType;
         out.setIpReachabilityEvent(ipReachabilityEvent);
     }
diff --git a/services/net/java/android/net/dhcp/DhcpClient.java b/services/net/java/android/net/dhcp/DhcpClient.java
index 2624f0b..ed78175 100644
--- a/services/net/java/android/net/dhcp/DhcpClient.java
+++ b/services/net/java/android/net/dhcp/DhcpClient.java
@@ -1023,10 +1023,10 @@
     }
 
     private void logError(int errorCode) {
-        mMetricsLog.log(new DhcpErrorEvent(mIfaceName, errorCode));
+        mMetricsLog.log(mIfaceName, new DhcpErrorEvent(errorCode));
     }
 
     private void logState(String name, int durationMs) {
-        mMetricsLog.log(new DhcpClientEvent(mIfaceName, name, durationMs));
+        mMetricsLog.log(mIfaceName, new DhcpClientEvent(name, durationMs));
     }
 }
diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
index c670782..59e698c 100644
--- a/services/net/java/android/net/ip/IpManager.java
+++ b/services/net/java/android/net/ip/IpManager.java
@@ -720,7 +720,7 @@
     private void recordMetric(final int type) {
         if (mStartTimeMillis <= 0) { Log.wtf(mTag, "Start time undefined!"); }
         final long duration = SystemClock.elapsedRealtime() - mStartTimeMillis;
-        mMetricsLog.log(new IpManagerEvent(mInterfaceName, type, duration));
+        mMetricsLog.log(mInterfaceName, new IpManagerEvent(type, duration));
     }
 
     // For now: use WifiStateMachine's historical notion of provisioned.
diff --git a/services/net/java/android/net/ip/IpReachabilityMonitor.java b/services/net/java/android/net/ip/IpReachabilityMonitor.java
index 20eac62..d13449a 100644
--- a/services/net/java/android/net/ip/IpReachabilityMonitor.java
+++ b/services/net/java/android/net/ip/IpReachabilityMonitor.java
@@ -426,7 +426,7 @@
 
     private void logEvent(int probeType, int errorCode) {
         int eventType = probeType | (errorCode & 0xff);
-        mMetricsLog.log(new IpReachabilityEvent(mInterfaceName, eventType));
+        mMetricsLog.log(mInterfaceName, new IpReachabilityEvent(eventType));
     }
 
     private void logNudFailed(ProvisioningChange delta) {
@@ -434,7 +434,7 @@
         boolean isFromProbe = (duration < getProbeWakeLockDuration());
         boolean isProvisioningLost = (delta == ProvisioningChange.LOST_PROVISIONING);
         int eventType = IpReachabilityEvent.nudFailureEventType(isFromProbe, isProvisioningLost);
-        mMetricsLog.log(new IpReachabilityEvent(mInterfaceName, eventType));
+        mMetricsLog.log(mInterfaceName, new IpReachabilityEvent(eventType));
     }
 
     // TODO: simplify the number of objects by making this extend Thread.
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
index 7f53495..dbc7861 100644
--- a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
+++ b/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
@@ -55,7 +55,6 @@
     public void testLinkLayerInferrence() {
         ConnectivityMetricsEvent ev = describeIpEvent(
                 aType(IpReachabilityEvent.class),
-                aString("wlan0"),
                 anInt(IpReachabilityEvent.NUD_FAILED));
 
         String want = joinLines(
@@ -68,7 +67,7 @@
                 "  transports: 0",
                 "  ip_reachability_event <",
                 "    event_type: 512",
-                "    if_name: \"wlan0\"",
+                "    if_name: \"\"",
                 "  >",
                 ">",
                 "version: 2");
@@ -87,7 +86,7 @@
                 "  transports: 3",
                 "  ip_reachability_event <",
                 "    event_type: 512",
-                "    if_name: \"wlan0\"",
+                "    if_name: \"\"",
                 "  >",
                 ">",
                 "version: 2");
@@ -105,7 +104,7 @@
                 "  transports: 1",
                 "  ip_reachability_event <",
                 "    event_type: 512",
-                "    if_name: \"wlan0\"",
+                "    if_name: \"\"",
                 "  >",
                 ">",
                 "version: 2");
@@ -123,7 +122,7 @@
                 "  transports: 0",
                 "  ip_reachability_event <",
                 "    event_type: 512",
-                "    if_name: \"wlan0\"",
+                "    if_name: \"\"",
                 "  >",
                 ">",
                 "version: 2");
@@ -140,7 +139,7 @@
                 "  transports: 0",
                 "  ip_reachability_event <",
                 "    event_type: 512",
-                "    if_name: \"wlan0\"",
+                "    if_name: \"\"",
                 "  >",
                 ">",
                 "version: 2");
@@ -157,7 +156,7 @@
                 "  transports: 0",
                 "  ip_reachability_event <",
                 "    event_type: 512",
-                "    if_name: \"wlan0\"",
+                "    if_name: \"\"",
                 "  >",
                 ">",
                 "version: 2");
@@ -174,7 +173,7 @@
                 "  transports: 0",
                 "  ip_reachability_event <",
                 "    event_type: 512",
-                "    if_name: \"wlan0\"",
+                "    if_name: \"\"",
                 "  >",
                 ">",
                 "version: 2");
@@ -221,7 +220,6 @@
     public void testDhcpClientEventSerialization() {
         ConnectivityMetricsEvent ev = describeIpEvent(
                 aType(DhcpClientEvent.class),
-                aString("wlan0"),
                 aString("SomeState"),
                 anInt(192));
 
@@ -235,7 +233,7 @@
                 "  transports: 0",
                 "  dhcp_event <",
                 "    duration_ms: 192",
-                "    if_name: \"wlan0\"",
+                "    if_name: \"\"",
                 "    state_transition: \"SomeState\"",
                 "  >",
                 ">",
@@ -248,7 +246,6 @@
     public void testDhcpErrorEventSerialization() {
         ConnectivityMetricsEvent ev = describeIpEvent(
                 aType(DhcpErrorEvent.class),
-                aString("wlan0"),
                 anInt(DhcpErrorEvent.L4_NOT_UDP));
 
         String want = joinLines(
@@ -261,7 +258,7 @@
                 "  transports: 0",
                 "  dhcp_event <",
                 "    duration_ms: 0",
-                "    if_name: \"wlan0\"",
+                "    if_name: \"\"",
                 "    error_code: 50397184",
                 "  >",
                 ">",
@@ -326,7 +323,6 @@
     public void testIpManagerEventSerialization() {
         ConnectivityMetricsEvent ev = describeIpEvent(
                 aType(IpManagerEvent.class),
-                aString("wlan0"),
                 anInt(IpManagerEvent.PROVISIONING_OK),
                 aLong(5678));
 
@@ -340,7 +336,7 @@
                 "  transports: 0",
                 "  ip_provisioning_event <",
                 "    event_type: 1",
-                "    if_name: \"wlan0\"",
+                "    if_name: \"\"",
                 "    latency_ms: 5678",
                 "  >",
                 ">",
@@ -353,7 +349,6 @@
     public void testIpReachabilityEventSerialization() {
         ConnectivityMetricsEvent ev = describeIpEvent(
                 aType(IpReachabilityEvent.class),
-                aString("wlan0"),
                 anInt(IpReachabilityEvent.NUD_FAILED));
 
         String want = joinLines(
@@ -366,7 +361,7 @@
                 "  transports: 0",
                 "  ip_reachability_event <",
                 "    event_type: 512",
-                "    if_name: \"wlan0\"",
+                "    if_name: \"\"",
                 "  >",
                 ">",
                 "version: 2");
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
index 785e1ce..50c92b3 100644
--- a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
+++ b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
@@ -48,7 +48,7 @@
 
 public class IpConnectivityMetricsTest extends TestCase {
     static final IpReachabilityEvent FAKE_EV =
-            new IpReachabilityEvent("wlan0", IpReachabilityEvent.NUD_FAILED);
+            new IpReachabilityEvent(IpReachabilityEvent.NUD_FAILED);
 
     @Mock Context mCtx;
     @Mock IIpConnectivityMetrics mMockService;
@@ -154,47 +154,51 @@
         apfStats.programUpdatesAllowingMulticast = 3;
         apfStats.maxProgramSize = 2048;
         Parcelable[] events = {
-            new IpReachabilityEvent("wlan0", IpReachabilityEvent.NUD_FAILED),
-            new DhcpClientEvent("wlan0", "SomeState", 192),
+            new IpReachabilityEvent(IpReachabilityEvent.NUD_FAILED),
+            new DhcpClientEvent("SomeState", 192),
             new DefaultNetworkEvent(102, new int[]{1,2,3}, 101, true, false),
-            new IpManagerEvent("wlan0", IpManagerEvent.PROVISIONING_OK, 5678),
+            new IpManagerEvent(IpManagerEvent.PROVISIONING_OK, 5678),
             new ValidationProbeEvent(120, 40730, ValidationProbeEvent.PROBE_HTTP, 204),
             apfStats,
             new RaEvent(2000, 400, 300, -1, 1000, -1)
         };
 
         for (int i = 0; i < events.length; i++) {
-            logger.log(100 * (i + 1), events[i]);
+            ConnectivityMetricsEvent ev = new ConnectivityMetricsEvent();
+            ev.timestamp = 100 * (i + 1);
+            ev.ifname = "wlan0";
+            ev.data = events[i];
+            logger.log(ev);
         }
 
         String want = joinLines(
                 "dropped_events: 0",
                 "events <",
                 "  if_name: \"\"",
-                "  link_layer: 0",
+                "  link_layer: 4",
                 "  network_id: 0",
                 "  time_ms: 100",
                 "  transports: 0",
                 "  ip_reachability_event <",
                 "    event_type: 512",
-                "    if_name: \"wlan0\"",
+                "    if_name: \"\"",
                 "  >",
                 ">",
                 "events <",
                 "  if_name: \"\"",
-                "  link_layer: 0",
+                "  link_layer: 4",
                 "  network_id: 0",
                 "  time_ms: 200",
                 "  transports: 0",
                 "  dhcp_event <",
                 "    duration_ms: 192",
-                "    if_name: \"wlan0\"",
+                "    if_name: \"\"",
                 "    state_transition: \"SomeState\"",
                 "  >",
                 ">",
                 "events <",
                 "  if_name: \"\"",
-                "  link_layer: 0",
+                "  link_layer: 4",
                 "  network_id: 0",
                 "  time_ms: 300",
                 "  transports: 0",
@@ -213,19 +217,19 @@
                 ">",
                 "events <",
                 "  if_name: \"\"",
-                "  link_layer: 0",
+                "  link_layer: 4",
                 "  network_id: 0",
                 "  time_ms: 400",
                 "  transports: 0",
                 "  ip_provisioning_event <",
                 "    event_type: 1",
-                "    if_name: \"wlan0\"",
+                "    if_name: \"\"",
                 "    latency_ms: 5678",
                 "  >",
                 ">",
                 "events <",
                 "  if_name: \"\"",
-                "  link_layer: 0",
+                "  link_layer: 4",
                 "  network_id: 0",
                 "  time_ms: 500",
                 "  transports: 0",
@@ -240,7 +244,7 @@
                 ">",
                 "events <",
                 "  if_name: \"\"",
-                "  link_layer: 0",
+                "  link_layer: 4",
                 "  network_id: 0",
                 "  time_ms: 600",
                 "  transports: 0",
@@ -259,7 +263,7 @@
                 ">",
                 "events <",
                 "  if_name: \"\"",
-                "  link_layer: 0",
+                "  link_layer: 4",
                 "  network_id: 0",
                 "  time_ms: 700",
                 "  transports: 0",