Loading core/java/android/net/metrics/WakeupEvent.java +30 −3 Original line number Diff line number Diff line Loading @@ -16,6 +16,10 @@ package android.net.metrics; import android.net.MacAddress; import java.util.StringJoiner; /** * An event logged when NFLOG notifies userspace of a wakeup packet for * watched interfaces. Loading @@ -23,12 +27,35 @@ package android.net.metrics; */ public class WakeupEvent { public String iface; public long timestampMs; public int uid; public int ethertype; public byte[] dstHwAddr; public String srcIp; public String dstIp; public int ipNextHeader; public int srcPort; public int dstPort; public long timestampMs; @Override public String toString() { return String.format("WakeupEvent(%tT.%tL, %s, uid: %d)", timestampMs, timestampMs, iface, uid); StringJoiner j = new StringJoiner(", ", "WakeupEvent(", ")"); j.add(String.format("%tT.%tL", timestampMs, timestampMs)); j.add(iface); j.add("uid: " + Integer.toString(uid)); j.add("eth=0x" + Integer.toHexString(ethertype)); j.add("dstHw=" + MacAddress.stringAddrFromByteAddr(dstHwAddr)); if (ipNextHeader > 0) { j.add("ipNxtHdr=" + ipNextHeader); j.add("srcIp=" + srcIp); j.add("dstIp=" + dstIp); if (srcPort > -1) { j.add("srcPort=" + srcPort); } if (dstPort > -1) { j.add("dstPort=" + dstPort); } } return j.toString(); } } core/java/android/net/metrics/WakeupStats.java +57 −10 Original line number Diff line number Diff line Loading @@ -16,8 +16,12 @@ package android.net.metrics; import android.net.MacAddress; import android.os.Process; import android.os.SystemClock; import android.util.SparseIntArray; import java.util.StringJoiner; /** * An event logged per interface and that aggregates WakeupEvents for that interface. Loading @@ -38,6 +42,13 @@ public class WakeupStats { public long noUidWakeups = 0; public long durationSec = 0; public long l2UnicastCount = 0; public long l2MulticastCount = 0; public long l2BroadcastCount = 0; public final SparseIntArray ethertypes = new SparseIntArray(); public final SparseIntArray ipNextHeaders = new SparseIntArray(); public WakeupStats(String iface) { this.iface = iface; } Loading Loading @@ -68,20 +79,56 @@ public class WakeupStats { } break; } switch (MacAddress.macAddressType(ev.dstHwAddr)) { case UNICAST: l2UnicastCount++; break; case MULTICAST: l2MulticastCount++; break; case BROADCAST: l2BroadcastCount++; break; default: break; } increment(ethertypes, ev.ethertype); if (ev.ipNextHeader >= 0) { increment(ipNextHeaders, ev.ipNextHeader); } } @Override public String toString() { updateDuration(); return new StringBuilder() .append("WakeupStats(").append(iface) .append(", total: ").append(totalWakeups) .append(", root: ").append(rootWakeups) .append(", system: ").append(systemWakeups) .append(", apps: ").append(applicationWakeups) .append(", non-apps: ").append(nonApplicationWakeups) .append(", no uid: ").append(noUidWakeups) .append(", ").append(durationSec).append("s)") .toString(); StringJoiner j = new StringJoiner(", ", "WakeupStats(", ")"); j.add(iface); j.add("" + durationSec + "s"); j.add("total: " + totalWakeups); j.add("root: " + rootWakeups); j.add("system: " + systemWakeups); j.add("apps: " + applicationWakeups); j.add("non-apps: " + nonApplicationWakeups); j.add("no uid: " + noUidWakeups); j.add(String.format("l2 unicast/multicast/broadcast: %d/%d/%d", l2UnicastCount, l2MulticastCount, l2BroadcastCount)); for (int i = 0; i < ethertypes.size(); i++) { int eth = ethertypes.keyAt(i); int count = ethertypes.valueAt(i); j.add(String.format("ethertype 0x%x: %d", eth, count)); } for (int i = 0; i < ipNextHeaders.size(); i++) { int proto = ipNextHeaders.keyAt(i); int count = ipNextHeaders.valueAt(i); j.add(String.format("ipNxtHdr %d: %d", proto, count)); } return j.toString(); } private static void increment(SparseIntArray counters, int key) { int newcount = counters.get(key, 0) + 1; counters.put(key, newcount); } } proto/src/ipconnectivity.proto +19 −1 Original line number Diff line number Diff line Loading @@ -489,7 +489,7 @@ message NetworkStats { // Represents statistics from NFLOG wakeup events due to ingress packets. // Since oc-mr1. // Next tag: 8. // Next tag: 13. message WakeupStats { // The time duration in seconds covered by these stats, for deriving // exact wakeup rates. Loading Loading @@ -517,6 +517,24 @@ message WakeupStats { // The total number of wakeup packets with no associated socket or uid. optional int64 no_uid_wakeups = 7; // Counts of all different ethertype values from wakeup packets received. repeated Pair ethertype_counts = 8; // Counts of all different IP next header values from wakeup packets received. repeated Pair ip_next_header_counts = 9; // The total number of wakeup packets whose destination hardware address was // a unicast address. optional int64 l2_unicast_count = 10; // The total number of wakeup packets whose destination hardware address was // a multicast address. optional int64 l2_multicast_count = 11; // The total number of wakeup packets whose destination hardware address was // a broadcast address. optional int64 l2_broadcast_count = 12; } // Represents one of the IP connectivity event defined in this file. Loading services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java +5 −0 Original line number Diff line number Diff line Loading @@ -128,6 +128,11 @@ final public class IpConnectivityEventBuilder { wakeupStats.nonApplicationWakeups = in.nonApplicationWakeups; wakeupStats.applicationWakeups = in.applicationWakeups; wakeupStats.noUidWakeups = in.noUidWakeups; wakeupStats.l2UnicastCount = in.l2UnicastCount; wakeupStats.l2MulticastCount = in.l2MulticastCount; wakeupStats.l2BroadcastCount = in.l2BroadcastCount; wakeupStats.ethertypeCounts = toPairArray(in.ethertypes); wakeupStats.ipNextHeaderCounts = toPairArray(in.ipNextHeaders); final IpConnectivityEvent out = buildEvent(0, 0, in.iface); out.setWakeupStats(wakeupStats); return out; Loading services/core/java/com/android/server/connectivity/NetdEventListenerService.java +14 −19 Original line number Diff line number Diff line Loading @@ -58,7 +58,6 @@ public class NetdEventListenerService extends INetdEventListener.Stub { private static final String TAG = NetdEventListenerService.class.getSimpleName(); private static final boolean DBG = false; private static final boolean VDBG = false; // Rate limit connect latency logging to 1 measurement per 15 seconds (5760 / day) with maximum // bursts of 5000 measurements. Loading Loading @@ -198,8 +197,6 @@ public class NetdEventListenerService extends INetdEventListener.Stub { public synchronized void onDnsEvent(int netId, int eventType, int returnCode, int latencyMs, String hostname, String[] ipAddresses, int ipAddressesCount, int uid) throws RemoteException { maybeVerboseLog("onDnsEvent(%d, %d, %d, %dms)", netId, eventType, returnCode, latencyMs); long timestamp = System.currentTimeMillis(); getMetricsForNetwork(timestamp, netId).addDnsResult(eventType, returnCode, latencyMs); Loading @@ -215,8 +212,6 @@ public class NetdEventListenerService extends INetdEventListener.Stub { // This method must not block or perform long-running operations. public synchronized void onConnectEvent(int netId, int error, int latencyMs, String ipAddr, int port, int uid) throws RemoteException { maybeVerboseLog("onConnectEvent(%d, %d, %dms)", netId, error, latencyMs); long timestamp = System.currentTimeMillis(); getMetricsForNetwork(timestamp, netId).addConnectResult(error, latencyMs, ipAddr); Loading @@ -232,11 +227,8 @@ public class NetdEventListenerService extends INetdEventListener.Stub { } @Override public synchronized void onWakeupEvent(String prefix, int uid, int gid, long timestampNs) { maybeVerboseLog("onWakeupEvent(%s, %d, %d, %sns)", prefix, uid, gid, timestampNs); // TODO: add ip protocol and port public synchronized void onWakeupEvent(String prefix, int uid, int ethertype, int ipNextHeader, byte[] dstHw, String srcIp, String dstIp, int srcPort, int dstPort, long timestampNs) { String iface = prefix.replaceFirst(WAKEUP_EVENT_IFACE_PREFIX, ""); final long timestampMs; if (timestampNs > 0) { Loading @@ -245,15 +237,22 @@ public class NetdEventListenerService extends INetdEventListener.Stub { timestampMs = System.currentTimeMillis(); } addWakeupEvent(iface, timestampMs, uid); } @GuardedBy("this") private void addWakeupEvent(String iface, long timestampMs, int uid) { WakeupEvent event = new WakeupEvent(); event.iface = iface; event.timestampMs = timestampMs; event.uid = uid; event.ethertype = ethertype; event.dstHwAddr = dstHw; event.srcIp = srcIp; event.dstIp = dstIp; event.ipNextHeader = ipNextHeader; event.srcPort = srcPort; event.dstPort = dstPort; addWakeupEvent(event); } private void addWakeupEvent(WakeupEvent event) { String iface = event.iface; mWakeupEvents.append(event); WakeupStats stats = mWakeupStats.get(iface); if (stats == null) { Loading Loading @@ -333,10 +332,6 @@ public class NetdEventListenerService extends INetdEventListener.Stub { if (DBG) Log.d(TAG, String.format(s, args)); } private static void maybeVerboseLog(String s, Object... args) { if (VDBG) Log.d(TAG, String.format(s, args)); } /** Helper class for buffering summaries of NetworkMetrics at regular time intervals */ static class NetworkMetricsSnapshot { Loading Loading
core/java/android/net/metrics/WakeupEvent.java +30 −3 Original line number Diff line number Diff line Loading @@ -16,6 +16,10 @@ package android.net.metrics; import android.net.MacAddress; import java.util.StringJoiner; /** * An event logged when NFLOG notifies userspace of a wakeup packet for * watched interfaces. Loading @@ -23,12 +27,35 @@ package android.net.metrics; */ public class WakeupEvent { public String iface; public long timestampMs; public int uid; public int ethertype; public byte[] dstHwAddr; public String srcIp; public String dstIp; public int ipNextHeader; public int srcPort; public int dstPort; public long timestampMs; @Override public String toString() { return String.format("WakeupEvent(%tT.%tL, %s, uid: %d)", timestampMs, timestampMs, iface, uid); StringJoiner j = new StringJoiner(", ", "WakeupEvent(", ")"); j.add(String.format("%tT.%tL", timestampMs, timestampMs)); j.add(iface); j.add("uid: " + Integer.toString(uid)); j.add("eth=0x" + Integer.toHexString(ethertype)); j.add("dstHw=" + MacAddress.stringAddrFromByteAddr(dstHwAddr)); if (ipNextHeader > 0) { j.add("ipNxtHdr=" + ipNextHeader); j.add("srcIp=" + srcIp); j.add("dstIp=" + dstIp); if (srcPort > -1) { j.add("srcPort=" + srcPort); } if (dstPort > -1) { j.add("dstPort=" + dstPort); } } return j.toString(); } }
core/java/android/net/metrics/WakeupStats.java +57 −10 Original line number Diff line number Diff line Loading @@ -16,8 +16,12 @@ package android.net.metrics; import android.net.MacAddress; import android.os.Process; import android.os.SystemClock; import android.util.SparseIntArray; import java.util.StringJoiner; /** * An event logged per interface and that aggregates WakeupEvents for that interface. Loading @@ -38,6 +42,13 @@ public class WakeupStats { public long noUidWakeups = 0; public long durationSec = 0; public long l2UnicastCount = 0; public long l2MulticastCount = 0; public long l2BroadcastCount = 0; public final SparseIntArray ethertypes = new SparseIntArray(); public final SparseIntArray ipNextHeaders = new SparseIntArray(); public WakeupStats(String iface) { this.iface = iface; } Loading Loading @@ -68,20 +79,56 @@ public class WakeupStats { } break; } switch (MacAddress.macAddressType(ev.dstHwAddr)) { case UNICAST: l2UnicastCount++; break; case MULTICAST: l2MulticastCount++; break; case BROADCAST: l2BroadcastCount++; break; default: break; } increment(ethertypes, ev.ethertype); if (ev.ipNextHeader >= 0) { increment(ipNextHeaders, ev.ipNextHeader); } } @Override public String toString() { updateDuration(); return new StringBuilder() .append("WakeupStats(").append(iface) .append(", total: ").append(totalWakeups) .append(", root: ").append(rootWakeups) .append(", system: ").append(systemWakeups) .append(", apps: ").append(applicationWakeups) .append(", non-apps: ").append(nonApplicationWakeups) .append(", no uid: ").append(noUidWakeups) .append(", ").append(durationSec).append("s)") .toString(); StringJoiner j = new StringJoiner(", ", "WakeupStats(", ")"); j.add(iface); j.add("" + durationSec + "s"); j.add("total: " + totalWakeups); j.add("root: " + rootWakeups); j.add("system: " + systemWakeups); j.add("apps: " + applicationWakeups); j.add("non-apps: " + nonApplicationWakeups); j.add("no uid: " + noUidWakeups); j.add(String.format("l2 unicast/multicast/broadcast: %d/%d/%d", l2UnicastCount, l2MulticastCount, l2BroadcastCount)); for (int i = 0; i < ethertypes.size(); i++) { int eth = ethertypes.keyAt(i); int count = ethertypes.valueAt(i); j.add(String.format("ethertype 0x%x: %d", eth, count)); } for (int i = 0; i < ipNextHeaders.size(); i++) { int proto = ipNextHeaders.keyAt(i); int count = ipNextHeaders.valueAt(i); j.add(String.format("ipNxtHdr %d: %d", proto, count)); } return j.toString(); } private static void increment(SparseIntArray counters, int key) { int newcount = counters.get(key, 0) + 1; counters.put(key, newcount); } }
proto/src/ipconnectivity.proto +19 −1 Original line number Diff line number Diff line Loading @@ -489,7 +489,7 @@ message NetworkStats { // Represents statistics from NFLOG wakeup events due to ingress packets. // Since oc-mr1. // Next tag: 8. // Next tag: 13. message WakeupStats { // The time duration in seconds covered by these stats, for deriving // exact wakeup rates. Loading Loading @@ -517,6 +517,24 @@ message WakeupStats { // The total number of wakeup packets with no associated socket or uid. optional int64 no_uid_wakeups = 7; // Counts of all different ethertype values from wakeup packets received. repeated Pair ethertype_counts = 8; // Counts of all different IP next header values from wakeup packets received. repeated Pair ip_next_header_counts = 9; // The total number of wakeup packets whose destination hardware address was // a unicast address. optional int64 l2_unicast_count = 10; // The total number of wakeup packets whose destination hardware address was // a multicast address. optional int64 l2_multicast_count = 11; // The total number of wakeup packets whose destination hardware address was // a broadcast address. optional int64 l2_broadcast_count = 12; } // Represents one of the IP connectivity event defined in this file. Loading
services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java +5 −0 Original line number Diff line number Diff line Loading @@ -128,6 +128,11 @@ final public class IpConnectivityEventBuilder { wakeupStats.nonApplicationWakeups = in.nonApplicationWakeups; wakeupStats.applicationWakeups = in.applicationWakeups; wakeupStats.noUidWakeups = in.noUidWakeups; wakeupStats.l2UnicastCount = in.l2UnicastCount; wakeupStats.l2MulticastCount = in.l2MulticastCount; wakeupStats.l2BroadcastCount = in.l2BroadcastCount; wakeupStats.ethertypeCounts = toPairArray(in.ethertypes); wakeupStats.ipNextHeaderCounts = toPairArray(in.ipNextHeaders); final IpConnectivityEvent out = buildEvent(0, 0, in.iface); out.setWakeupStats(wakeupStats); return out; Loading
services/core/java/com/android/server/connectivity/NetdEventListenerService.java +14 −19 Original line number Diff line number Diff line Loading @@ -58,7 +58,6 @@ public class NetdEventListenerService extends INetdEventListener.Stub { private static final String TAG = NetdEventListenerService.class.getSimpleName(); private static final boolean DBG = false; private static final boolean VDBG = false; // Rate limit connect latency logging to 1 measurement per 15 seconds (5760 / day) with maximum // bursts of 5000 measurements. Loading Loading @@ -198,8 +197,6 @@ public class NetdEventListenerService extends INetdEventListener.Stub { public synchronized void onDnsEvent(int netId, int eventType, int returnCode, int latencyMs, String hostname, String[] ipAddresses, int ipAddressesCount, int uid) throws RemoteException { maybeVerboseLog("onDnsEvent(%d, %d, %d, %dms)", netId, eventType, returnCode, latencyMs); long timestamp = System.currentTimeMillis(); getMetricsForNetwork(timestamp, netId).addDnsResult(eventType, returnCode, latencyMs); Loading @@ -215,8 +212,6 @@ public class NetdEventListenerService extends INetdEventListener.Stub { // This method must not block or perform long-running operations. public synchronized void onConnectEvent(int netId, int error, int latencyMs, String ipAddr, int port, int uid) throws RemoteException { maybeVerboseLog("onConnectEvent(%d, %d, %dms)", netId, error, latencyMs); long timestamp = System.currentTimeMillis(); getMetricsForNetwork(timestamp, netId).addConnectResult(error, latencyMs, ipAddr); Loading @@ -232,11 +227,8 @@ public class NetdEventListenerService extends INetdEventListener.Stub { } @Override public synchronized void onWakeupEvent(String prefix, int uid, int gid, long timestampNs) { maybeVerboseLog("onWakeupEvent(%s, %d, %d, %sns)", prefix, uid, gid, timestampNs); // TODO: add ip protocol and port public synchronized void onWakeupEvent(String prefix, int uid, int ethertype, int ipNextHeader, byte[] dstHw, String srcIp, String dstIp, int srcPort, int dstPort, long timestampNs) { String iface = prefix.replaceFirst(WAKEUP_EVENT_IFACE_PREFIX, ""); final long timestampMs; if (timestampNs > 0) { Loading @@ -245,15 +237,22 @@ public class NetdEventListenerService extends INetdEventListener.Stub { timestampMs = System.currentTimeMillis(); } addWakeupEvent(iface, timestampMs, uid); } @GuardedBy("this") private void addWakeupEvent(String iface, long timestampMs, int uid) { WakeupEvent event = new WakeupEvent(); event.iface = iface; event.timestampMs = timestampMs; event.uid = uid; event.ethertype = ethertype; event.dstHwAddr = dstHw; event.srcIp = srcIp; event.dstIp = dstIp; event.ipNextHeader = ipNextHeader; event.srcPort = srcPort; event.dstPort = dstPort; addWakeupEvent(event); } private void addWakeupEvent(WakeupEvent event) { String iface = event.iface; mWakeupEvents.append(event); WakeupStats stats = mWakeupStats.get(iface); if (stats == null) { Loading Loading @@ -333,10 +332,6 @@ public class NetdEventListenerService extends INetdEventListener.Stub { if (DBG) Log.d(TAG, String.format(s, args)); } private static void maybeVerboseLog(String s, Object... args) { if (VDBG) Log.d(TAG, String.format(s, args)); } /** Helper class for buffering summaries of NetworkMetrics at regular time intervals */ static class NetworkMetricsSnapshot { Loading