diff options
author | 2017-11-06 07:31:39 +0000 | |
---|---|---|
committer | 2017-11-06 07:31:39 +0000 | |
commit | 384d458c8fee951b62cf04a066d37fac88d86489 (patch) | |
tree | dd7ea146ccd7bd5922cfa9b20fcf16184a684490 | |
parent | 37c8698c1f809f4229b34535135c3b81f6fbb182 (diff) | |
parent | d025358166e34d01c57f56748f896e786d59d260 (diff) |
Merge "DefaultNetworkEvent metrics: rehaul" am: 69c9402a29
am: d025358166
Change-Id: If6bf966ba547a2ce50e17340e0374dd9b75b80d9
10 files changed, 340 insertions, 246 deletions
diff --git a/core/java/android/net/metrics/DefaultNetworkEvent.java b/core/java/android/net/metrics/DefaultNetworkEvent.java index eb61c1532d49..8ff8e4f38d6d 100644 --- a/core/java/android/net/metrics/DefaultNetworkEvent.java +++ b/core/java/android/net/metrics/DefaultNetworkEvent.java @@ -20,44 +20,72 @@ import static android.net.ConnectivityManager.NETID_UNSET; import android.net.NetworkCapabilities; +import com.android.internal.util.BitUtils; + +import java.util.StringJoiner; + /** * An event recorded by ConnectivityService when there is a change in the default network. * {@hide} */ public class DefaultNetworkEvent { - // The ID of the network that has become the new default or NETID_UNSET if none. + // The creation time in milliseconds of this DefaultNetworkEvent. + public final long creationTimeMs; + // The network ID of the network or NETID_UNSET if none. public int netId = NETID_UNSET; - // The list of transport types of the new default network, for example TRANSPORT_WIFI, as - // defined in NetworkCapabilities.java. - public int[] transportTypes = new int[0]; - // The ID of the network that was the default before or NETID_UNSET if none. - public int prevNetId = NETID_UNSET; - // Whether the previous network had IPv4/IPv6 connectivity. - public boolean prevIPv4; - public boolean prevIPv6; + // The list of transport types, as defined in NetworkCapabilities.java. + public int transports; + // The list of transport types of the last previous default network. + public int previousTransports; + // Whether the network has IPv4/IPv6 connectivity. + public boolean ipv4; + public boolean ipv6; + // The initial network score when this network became the default network. + public int initialScore; + // The initial network score when this network stopped being the default network. + public int finalScore; + // The total duration in milliseconds this network was the default network. + public long durationMs; + // The total duration in milliseconds this network was the default network and was validated. + public long validatedMs; + + public DefaultNetworkEvent(long timeMs) { + creationTimeMs = timeMs; + } + + /** Update the durationMs of this DefaultNetworkEvent for the given current time. */ + public void updateDuration(long timeMs) { + durationMs = timeMs - creationTimeMs; + } @Override public String toString() { - String prevNetwork = String.valueOf(prevNetId); - String newNetwork = String.valueOf(netId); - if (prevNetId != 0) { - prevNetwork += ":" + ipSupport(); + StringJoiner j = new StringJoiner(", ", "DefaultNetworkEvent(", ")"); + j.add("netId=" + netId); + for (int t : BitUtils.unpackBits(transports)) { + j.add(NetworkCapabilities.transportNameOf(t)); + } + j.add("ip=" + ipSupport()); + if (initialScore > 0) { + j.add("initial_score=" + initialScore); } - if (netId != 0) { - newNetwork += ":" + NetworkCapabilities.transportNamesOf(transportTypes); + if (finalScore > 0) { + j.add("final_score=" + finalScore); } - return String.format("DefaultNetworkEvent(%s -> %s)", prevNetwork, newNetwork); + j.add(String.format("duration=%.0fs", durationMs / 1000.0)); + j.add(String.format("validation=%4.1f%%", (validatedMs * 100.0) / durationMs)); + return j.toString(); } private String ipSupport() { - if (prevIPv4 && prevIPv6) { + if (ipv4 && ipv6) { return "IPv4v6"; } - if (prevIPv6) { + if (ipv6) { return "IPv6"; } - if (prevIPv4) { + if (ipv4) { return "IPv4"; } return "NONE"; diff --git a/proto/src/ipconnectivity.proto b/proto/src/ipconnectivity.proto index 437da8f3f17a..327f17da8626 100644 --- a/proto/src/ipconnectivity.proto +++ b/proto/src/ipconnectivity.proto @@ -50,9 +50,10 @@ message Pair { optional int32 value = 2; }; -// An event record when the system default network disconnects or the system -// switches to a new default network. -// Next tag: 10. +// An event recorded when the system default network disconnects or the system +// switches to a new default network. An event is also recorded to cover gaps +// without a default network. +// Next tag: 12 message DefaultNetworkEvent { // Reason why this network stopped being the default. @@ -72,26 +73,34 @@ message DefaultNetworkEvent { }; // Duration in milliseconds when this network was the default. - // Since version 4 + // Since P. optional int64 default_network_duration_ms = 5; - // Duration in milliseconds without a default network before this network - // became the default. - // Since version 4 - optional int64 no_default_network_duration_ms = 6; + // Duration in milliseconds when this default network Internet access was + // validated. This field is equal to 0 for DefaultNetworkEvents representing + // lack of a default network. + // Since P. + optional int64 validation_duration_ms = 11; // Network score of this network when it became the default network. - // Since version 4 + // Or 0 if this event represents a period without a default network. + // Since P. optional int64 initial_score = 7; // Network score of this network when it stopped being the default network. - // Since version 4 + // Or 0 if this event represents a period without a default network. + // Since P. optional int64 final_score = 8; // Best available information about IP support of this default network. - // Since version 4 + // Or NONE if this event represents a period without a default network. + // Since P. optional IPSupport ip_support = 9; + // LinkLayer of the previous default network. Ignores any previous period + // without a default network. + // Since P + optional LinkLayer previous_default_network_link_layer = 10; // Deprecated fields @@ -112,6 +121,11 @@ message DefaultNetworkEvent { // TRANSPORT_* constants as defined in NetworkCapabilities. // Deprecated since version 3. Replaced by top-level transports field. repeated int32 transport_types = 4 [deprecated = true]; + + // Duration in milliseconds without a default network. This field is non-zero + // only for DefaultNetworkEvents representing lack of a default network. + // Since P. + optional int64 no_default_network_duration_ms = 6 [deprecated = true]; }; // Logs IpReachabilityMonitor probe events and NUD_FAILED events. diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index f6ca87fdb920..9bc92fde225a 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -2095,9 +2095,14 @@ public class ConnectivityService extends IConnectivityManager.Stub final boolean valid = (msg.arg1 == NetworkMonitor.NETWORK_TEST_RESULT_VALID); final boolean wasValidated = nai.lastValidated; + final boolean wasDefault = isDefaultNetwork(nai); if (DBG) log(nai.name() + " validation " + (valid ? "passed" : "failed") + (msg.obj == null ? "" : " with redirect to " + (String)msg.obj)); if (valid != nai.lastValidated) { + if (wasDefault) { + metricsLogger().defaultNetworkMetrics().logDefaultNetworkValidity( + SystemClock.elapsedRealtime(), valid); + } final int oldScore = nai.getCurrentScore(); nai.lastValidated = valid; nai.everValidated |= valid; @@ -2269,7 +2274,8 @@ public class ConnectivityService extends IConnectivityManager.Stub // Let rematchAllNetworksAndRequests() below record a new default network event // if there is a fallback. Taken together, the two form a X -> 0, 0 -> Y sequence // whose timestamps tell how long it takes to recover a default network. - metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(null, nai); + long now = SystemClock.elapsedRealtime(); + metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(now, null, nai); } notifyIfacesChangedForNetworkStats(); // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied @@ -5024,7 +5030,7 @@ public class ConnectivityService extends IConnectivityManager.Stub makeDefault(newNetwork); // Log 0 -> X and Y -> X default network transitions, where X is the new default. metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent( - newNetwork, oldDefaultNetwork); + now, newNetwork, oldDefaultNetwork); // Have a new default network, release the transition wakelock in scheduleReleaseNetworkTransitionWakelock(); } diff --git a/services/core/java/com/android/server/connectivity/DefaultNetworkMetrics.java b/services/core/java/com/android/server/connectivity/DefaultNetworkMetrics.java index 8981db11f7f8..28c358582dbe 100644 --- a/services/core/java/com/android/server/connectivity/DefaultNetworkMetrics.java +++ b/services/core/java/com/android/server/connectivity/DefaultNetworkMetrics.java @@ -18,9 +18,11 @@ package com.android.server.connectivity; import android.net.LinkProperties; import android.net.metrics.DefaultNetworkEvent; -import android.net.metrics.IpConnectivityLog; +import android.os.SystemClock; import com.android.internal.annotations.GuardedBy; +import com.android.internal.util.BitUtils; +import com.android.internal.util.RingBuffer; import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent; import java.io.PrintWriter; @@ -35,19 +37,49 @@ public class DefaultNetworkMetrics { private static final int ROLLING_LOG_SIZE = 64; + public final long creationTimeMs = SystemClock.elapsedRealtime(); + // Event buffer used for metrics upload. The buffer is cleared when events are collected. @GuardedBy("this") private final List<DefaultNetworkEvent> mEvents = new ArrayList<>(); + // Rolling event buffer used for dumpsys and bugreports. + @GuardedBy("this") + private final RingBuffer<DefaultNetworkEvent> mEventsLog = + new RingBuffer(DefaultNetworkEvent.class, ROLLING_LOG_SIZE); + + // Information about the current status of the default network. + @GuardedBy("this") + private DefaultNetworkEvent mCurrentDefaultNetwork; + @GuardedBy("this") + private boolean mIsCurrentlyValid; + @GuardedBy("this") + private long mLastValidationTimeMs; + // Transport information about the last default network. + @GuardedBy("this") + private int mLastTransports; + + public DefaultNetworkMetrics() { + newDefaultNetwork(creationTimeMs, null); + } + public synchronized void listEvents(PrintWriter pw) { + pw.println("default network events:"); long localTimeMs = System.currentTimeMillis(); - for (DefaultNetworkEvent ev : mEvents) { - pw.println(ev); + long timeMs = SystemClock.elapsedRealtime(); + for (DefaultNetworkEvent ev : mEventsLog.toArray()) { + printEvent(localTimeMs, pw, ev); + } + mCurrentDefaultNetwork.updateDuration(timeMs); + if (mIsCurrentlyValid) { + updateValidationTime(timeMs); + mLastValidationTimeMs = timeMs; } + printEvent(localTimeMs, pw, mCurrentDefaultNetwork); } public synchronized void listEventsAsProto(PrintWriter pw) { - for (DefaultNetworkEvent ev : mEvents) { + for (DefaultNetworkEvent ev : mEventsLog.toArray()) { pw.print(IpConnectivityEventBuilder.toProto(ev)); } } @@ -59,20 +91,75 @@ public class DefaultNetworkMetrics { mEvents.clear(); } - public synchronized void logDefaultNetworkEvent( - NetworkAgentInfo newNai, NetworkAgentInfo prevNai) { - DefaultNetworkEvent ev = new DefaultNetworkEvent(); - if (newNai != null) { - ev.netId = newNai.network().netId; - ev.transportTypes = newNai.networkCapabilities.getTransportTypes(); + public synchronized void logDefaultNetworkValidity(long timeMs, boolean isValid) { + if (!isValid && mIsCurrentlyValid) { + mIsCurrentlyValid = false; + updateValidationTime(timeMs); } - if (prevNai != null) { - ev.prevNetId = prevNai.network().netId; - final LinkProperties lp = prevNai.linkProperties; - ev.prevIPv4 = lp.hasIPv4Address() && lp.hasIPv4DefaultRoute(); - ev.prevIPv6 = lp.hasGlobalIPv6Address() && lp.hasIPv6DefaultRoute(); + + if (isValid && !mIsCurrentlyValid) { + mIsCurrentlyValid = true; + mLastValidationTimeMs = timeMs; } + } + + private void updateValidationTime(long timeMs) { + mCurrentDefaultNetwork.validatedMs += timeMs - mLastValidationTimeMs; + } + + public synchronized void logDefaultNetworkEvent( + long timeMs, NetworkAgentInfo newNai, NetworkAgentInfo oldNai) { + logCurrentDefaultNetwork(timeMs, oldNai); + newDefaultNetwork(timeMs, newNai); + } + private void logCurrentDefaultNetwork(long timeMs, NetworkAgentInfo oldNai) { + DefaultNetworkEvent ev = mCurrentDefaultNetwork; + ev.updateDuration(timeMs); + ev.previousTransports = mLastTransports; + // oldNai is null if the system had no default network before the transition. + if (oldNai != null) { + // The system acquired a new default network. + fillLinkInfo(ev, oldNai); + ev.finalScore = oldNai.getCurrentScore(); + ev.validatedMs = ev.durationMs; + } + // Only change transport of the previous default network if the event currently logged + // corresponds to an existing default network, and not to the absence of a default network. + // This allows to log pairs of transports for successive default networks regardless of + // whether or not the system experienced a period without any default network. + if (ev.transports != 0) { + mLastTransports = ev.transports; + } mEvents.add(ev); + mEventsLog.append(ev); + } + + private void newDefaultNetwork(long timeMs, NetworkAgentInfo newNai) { + DefaultNetworkEvent ev = new DefaultNetworkEvent(timeMs); + ev.durationMs = timeMs; + // newNai is null if the system has no default network after the transition. + if (newNai != null) { + fillLinkInfo(ev, newNai); + ev.initialScore = newNai.getCurrentScore(); + if (newNai.lastValidated) { + mIsCurrentlyValid = true; + mLastValidationTimeMs = timeMs; + } + } + mCurrentDefaultNetwork = ev; + } + + private static void fillLinkInfo(DefaultNetworkEvent ev, NetworkAgentInfo nai) { + LinkProperties lp = nai.linkProperties; + ev.netId = nai.network().netId; + ev.transports |= BitUtils.packBits(nai.networkCapabilities.getTransportTypes()); + ev.ipv4 |= lp.hasIPv4Address() && lp.hasIPv4DefaultRoute(); + ev.ipv6 |= lp.hasGlobalIPv6Address() && lp.hasIPv6DefaultRoute(); + } + + private static void printEvent(long localTimeMs, PrintWriter pw, DefaultNetworkEvent ev) { + long localCreationTimeMs = localTimeMs - ev.durationMs; + pw.println(String.format("%tT.%tL: %s", localCreationTimeMs, localCreationTimeMs, ev)); } } diff --git a/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java b/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java index 3d71ecb50d9f..a011692be37c 100644 --- a/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java +++ b/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java @@ -25,6 +25,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_VPN; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE; +import android.net.ConnectivityManager; import android.net.ConnectivityMetricsEvent; import android.net.metrics.ApfProgramEvent; import android.net.metrics.ApfStats; @@ -135,11 +136,17 @@ final public class IpConnectivityEventBuilder { public static IpConnectivityEvent toProto(DefaultNetworkEvent in) { IpConnectivityLogClass.DefaultNetworkEvent ev = new IpConnectivityLogClass.DefaultNetworkEvent(); - ev.networkId = netIdOf(in.netId); - ev.previousNetworkId = netIdOf(in.prevNetId); - ev.transportTypes = in.transportTypes; - ev.previousNetworkIpSupport = ipSupportOf(in); - final IpConnectivityEvent out = buildEvent(in.netId, 0, null); + ev.finalScore = in.finalScore; + ev.initialScore = in.initialScore; + ev.ipSupport = ipSupportOf(in); + ev.defaultNetworkDurationMs = in.durationMs; + ev.validationDurationMs = in.validatedMs; + ev.previousDefaultNetworkLinkLayer = transportsToLinkLayer(in.previousTransports); + final IpConnectivityEvent out = buildEvent(in.netId, in.transports, null); + if (in.transports == 0) { + // Set link layer to NONE for events representing the absence of a default network. + out.linkLayer = IpConnectivityLogClass.NONE; + } out.setDefaultNetworkEvent(ev); return out; } @@ -321,13 +328,13 @@ final public class IpConnectivityEventBuilder { } private static int ipSupportOf(DefaultNetworkEvent in) { - if (in.prevIPv4 && in.prevIPv6) { + if (in.ipv4 && in.ipv6) { return IpConnectivityLogClass.DefaultNetworkEvent.DUAL; } - if (in.prevIPv6) { + if (in.ipv6) { return IpConnectivityLogClass.DefaultNetworkEvent.IPV6; } - if (in.prevIPv4) { + if (in.ipv4) { return IpConnectivityLogClass.DefaultNetworkEvent.IPV4; } return IpConnectivityLogClass.DefaultNetworkEvent.NONE; diff --git a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java index 24217e6eef0b..5cc390a02b86 100644 --- a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java +++ b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java @@ -45,6 +45,7 @@ import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.function.ToIntFunction; @@ -214,86 +215,66 @@ final public class IpConnectivityMetrics extends SystemService { } /** - * Clears the event buffer and prints its content as a protobuf serialized byte array + * Clear the event buffer and prints its content as a protobuf serialized byte array * inside a base64 encoded string. */ - private void cmdFlush(FileDescriptor fd, PrintWriter pw, String[] args) { + private void cmdFlush(PrintWriter pw) { pw.print(flushEncodedOutput()); } /** - * Prints the content of the event buffer, either using the events ASCII representation - * or using protobuf text format. + * Print the content of the rolling event buffer in human readable format. + * Also print network dns/connect statistics and recent default network events. */ - private void cmdList(FileDescriptor fd, PrintWriter pw, String[] args) { - final ArrayList<ConnectivityMetricsEvent> events; - synchronized (mLock) { - events = new ArrayList(mBuffer); - } - - if (args.length > 1 && args[1].equals("proto")) { - for (IpConnectivityEvent ev : IpConnectivityEventBuilder.toProto(events)) { - pw.print(ev.toString()); - } - if (mNetdListener != null) { - mNetdListener.listAsProtos(pw); - } - mDefaultNetworkMetrics.listEventsAsProto(pw); - return; - } - + private void cmdList(PrintWriter pw) { + pw.println("metrics events:"); + final List<ConnectivityMetricsEvent> events = getEvents(); for (ConnectivityMetricsEvent ev : events) { pw.println(ev.toString()); } + pw.println(""); if (mNetdListener != null) { mNetdListener.list(pw); } + pw.println(""); mDefaultNetworkMetrics.listEvents(pw); } - /** - * Prints for bug reports the content of the rolling event log and the - * content of Netd event listener. + /* + * Print the content of the rolling event buffer in text proto format. */ - private void cmdDumpsys(FileDescriptor fd, PrintWriter pw, String[] args) { - final ConnectivityMetricsEvent[] events; - synchronized (mLock) { - events = mEventLog.toArray(); - } - for (ConnectivityMetricsEvent ev : events) { - pw.println(ev.toString()); + private void cmdListAsProto(PrintWriter pw) { + final List<ConnectivityMetricsEvent> events = getEvents(); + for (IpConnectivityEvent ev : IpConnectivityEventBuilder.toProto(events)) { + pw.print(ev.toString()); } if (mNetdListener != null) { - mNetdListener.list(pw); + mNetdListener.listAsProtos(pw); } - mDefaultNetworkMetrics.listEvents(pw); + mDefaultNetworkMetrics.listEventsAsProto(pw); } - private void cmdStats(FileDescriptor fd, PrintWriter pw, String[] args) { + /* + * Return a copy of metrics events stored in buffer for metrics uploading. + */ + private List<ConnectivityMetricsEvent> getEvents() { synchronized (mLock) { - pw.println("Buffered events: " + mBuffer.size()); - pw.println("Buffer capacity: " + mCapacity); - pw.println("Dropped events: " + mDropped); - } - if (mNetdListener != null) { - mNetdListener.dump(pw); + return Arrays.asList(mEventLog.toArray()); } } - private void cmdDefault(FileDescriptor fd, PrintWriter pw, String[] args) { - if (args.length == 0) { - pw.println("No command"); - return; - } - pw.println("Unknown command " + TextUtils.join(" ", args)); - } - public final class Impl extends IIpConnectivityMetrics.Stub { - static final String CMD_FLUSH = "flush"; - static final String CMD_LIST = "list"; - static final String CMD_STATS = "stats"; - static final String CMD_DUMPSYS = "-a"; // dumpsys.cpp dumps services with "-a" as arguments - static final String CMD_DEFAULT = CMD_STATS; + // Dump and flushes the metrics event buffer in base64 encoded serialized proto output. + static final String CMD_FLUSH = "flush"; + // Dump the rolling buffer of metrics event in human readable proto text format. + static final String CMD_PROTO = "proto"; + // Dump the rolling buffer of metrics event and pretty print events using a human readable + // format. Also print network dns/connect statistics and default network event time series. + static final String CMD_LIST = "list"; + // By default any other argument will fall into the default case which is remapped to the + // "list" command. This includes most notably bug reports collected by dumpsys.cpp with + // the "-a" argument. + static final String CMD_DEFAULT = CMD_LIST; @Override public int logEvent(ConnectivityMetricsEvent event) { @@ -308,19 +289,15 @@ final public class IpConnectivityMetrics extends SystemService { final String cmd = (args.length > 0) ? args[0] : CMD_DEFAULT; switch (cmd) { case CMD_FLUSH: - cmdFlush(fd, pw, args); + cmdFlush(pw); return; - case CMD_DUMPSYS: - cmdDumpsys(fd, pw, args); - return; - case CMD_LIST: - cmdList(fd, pw, args); - return; - case CMD_STATS: - cmdStats(fd, pw, args); + case CMD_PROTO: + cmdListAsProto(pw); return; + case CMD_LIST: // fallthrough default: - cmdDefault(fd, pw, args); + cmdList(pw); + return; } } diff --git a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java index 05c6e69c1895..61b11e18e3cd 100644 --- a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java +++ b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java @@ -243,24 +243,21 @@ public class NetdEventListenerService extends INetdEventListener.Stub { mWakeupStats.clear(); } - public synchronized void dump(PrintWriter writer) { - IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); - pw.println(TAG + ":"); - pw.increaseIndent(); - list(pw); - pw.decreaseIndent(); - } - public synchronized void list(PrintWriter pw) { + pw.println("dns/connect events:"); for (int i = 0; i < mNetworkMetrics.size(); i++) { pw.println(mNetworkMetrics.valueAt(i).connectMetrics); } for (int i = 0; i < mNetworkMetrics.size(); i++) { pw.println(mNetworkMetrics.valueAt(i).dnsMetrics); } + pw.println(""); + pw.println("network statistics:"); for (NetworkMetricsSnapshot s : getNetworkMetricsSnapshots()) { pw.println(s); } + pw.println(""); + pw.println("packet wakeup events:"); for (int i = 0; i < mWakeupStats.size(); i++) { pw.println(mWakeupStats.valueAt(i)); } diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java index ad6ebf933776..a65bb2436287 100644 --- a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java +++ b/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java @@ -198,37 +198,33 @@ public class IpConnectivityEventBuilderTest { @Test public void testDefaultNetworkEventSerialization() { - DefaultNetworkEvent ev = new DefaultNetworkEvent(); + DefaultNetworkEvent ev = new DefaultNetworkEvent(1001); ev.netId = 102; - ev.prevNetId = 101; - ev.transportTypes = new int[]{1, 2, 3}; - ev.prevIPv4 = true; - ev.prevIPv6 = true; + ev.transports = 2; + ev.previousTransports = 4; + ev.ipv4 = true; + ev.initialScore = 20; + ev.finalScore = 60; + ev.durationMs = 54; + ev.validatedMs = 27; String want = String.join("\n", "dropped_events: 0", "events <", " if_name: \"\"", - " link_layer: 0", + " link_layer: 4", " network_id: 102", " time_ms: 0", - " transports: 0", + " transports: 2", " default_network_event <", - " default_network_duration_ms: 0", - " final_score: 0", - " initial_score: 0", - " ip_support: 0", - " network_id <", - " network_id: 102", - " >", + " default_network_duration_ms: 54", + " final_score: 60", + " initial_score: 20", + " ip_support: 1", " no_default_network_duration_ms: 0", - " previous_network_id <", - " network_id: 101", - " >", - " previous_network_ip_support: 3", - " transport_types: 1", - " transport_types: 2", - " transport_types: 3", + " previous_default_network_link_layer: 1", + " previous_network_ip_support: 0", + " validation_duration_ms: 27", " >", ">", "version: 2\n"); diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java index 6c1decc3b3b8..b48ff8da2ba4 100644 --- a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java +++ b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java @@ -188,119 +188,99 @@ public class IpConnectivityMetricsTest { {makeNai(102, 50, true, true, cell), makeNai(103, 20, true, false, wifi)}, }; + long timeMs = mService.mDefaultNetworkMetrics.creationTimeMs; + long durationMs = 1001; for (NetworkAgentInfo[] pair : defaultNetworks) { - mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(pair[1], pair[0]); + timeMs += durationMs; + durationMs += durationMs; + mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(timeMs, pair[1], pair[0]); } String want = String.join("\n", "dropped_events: 0", "events <", " if_name: \"\"", - " link_layer: 0", - " network_id: 100", + " link_layer: 5", + " network_id: 0", " time_ms: 0", " transports: 0", " default_network_event <", - " default_network_duration_ms: 0", + " default_network_duration_ms: 1001", " final_score: 0", " initial_score: 0", " ip_support: 0", - " network_id <", - " network_id: 100", - " >", " no_default_network_duration_ms: 0", - " previous_network_id <", - " network_id: 0", - " >", + " previous_default_network_link_layer: 0", " previous_network_ip_support: 0", - " transport_types: 0", + " validation_duration_ms: 0", " >", ">", "events <", " if_name: \"\"", - " link_layer: 0", - " network_id: 101", + " link_layer: 2", + " network_id: 100", " time_ms: 0", - " transports: 0", + " transports: 1", " default_network_event <", - " default_network_duration_ms: 0", - " final_score: 0", - " initial_score: 0", - " ip_support: 0", - " network_id <", - " network_id: 101", - " >", + " default_network_duration_ms: 2002", + " final_score: 50", + " initial_score: 10", + " ip_support: 3", " no_default_network_duration_ms: 0", - " previous_network_id <", - " network_id: 100", - " >", - " previous_network_ip_support: 3", - " transport_types: 1", + " previous_default_network_link_layer: 0", + " previous_network_ip_support: 0", + " validation_duration_ms: 2002", " >", ">", "events <", " if_name: \"\"", - " link_layer: 0", - " network_id: 0", + " link_layer: 4", + " network_id: 101", " time_ms: 0", - " transports: 0", + " transports: 2", " default_network_event <", - " default_network_duration_ms: 0", - " final_score: 0", - " initial_score: 0", - " ip_support: 0", - " network_id <", - " network_id: 0", - " >", + " default_network_duration_ms: 4004", + " final_score: 60", + " initial_score: 20", + " ip_support: 1", " no_default_network_duration_ms: 0", - " previous_network_id <", - " network_id: 101", - " >", - " previous_network_ip_support: 1", + " previous_default_network_link_layer: 2", + " previous_network_ip_support: 0", + " validation_duration_ms: 4004", " >", ">", "events <", " if_name: \"\"", - " link_layer: 0", - " network_id: 102", + " link_layer: 5", + " network_id: 0", " time_ms: 0", " transports: 0", " default_network_event <", - " default_network_duration_ms: 0", + " default_network_duration_ms: 8008", " final_score: 0", " initial_score: 0", " ip_support: 0", - " network_id <", - " network_id: 102", - " >", " no_default_network_duration_ms: 0", - " previous_network_id <", - " network_id: 0", - " >", + " previous_default_network_link_layer: 4", " previous_network_ip_support: 0", - " transport_types: 0", + " validation_duration_ms: 0", " >", ">", "events <", " if_name: \"\"", - " link_layer: 0", - " network_id: 103", + " link_layer: 2", + " network_id: 102", " time_ms: 0", - " transports: 0", + " transports: 1", " default_network_event <", - " default_network_duration_ms: 0", - " final_score: 0", - " initial_score: 0", - " ip_support: 0", - " network_id <", - " network_id: 103", - " >", + " default_network_duration_ms: 16016", + " final_score: 50", + " initial_score: 10", + " ip_support: 3", " no_default_network_duration_ms: 0", - " previous_network_id <", - " network_id: 102", - " >", - " previous_network_ip_support: 3", - " transport_types: 1", + " previous_default_network_link_layer: 4", + " previous_network_ip_support: 0", + " validation_duration_ms: 16016", " >", ">", "version: 2\n"); @@ -379,12 +359,13 @@ public class IpConnectivityMetricsTest { wakeupEvent("wlan0", 10008); wakeupEvent("rmnet0", 1000); + long timeMs = mService.mDefaultNetworkMetrics.creationTimeMs; final long cell = BitUtils.packBits(new int[]{NetworkCapabilities.TRANSPORT_CELLULAR}); final long wifi = BitUtils.packBits(new int[]{NetworkCapabilities.TRANSPORT_WIFI}); NetworkAgentInfo cellNai = makeNai(100, 50, false, true, cell); NetworkAgentInfo wifiNai = makeNai(101, 60, true, false, wifi); - mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(cellNai, null); - mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(wifiNai, cellNai); + mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(timeMs + 200, cellNai, null); + mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(timeMs + 300, wifiNai, cellNai); String want = String.join("\n", "dropped_events: 0", @@ -473,46 +454,36 @@ public class IpConnectivityMetricsTest { ">", "events <", " if_name: \"\"", - " link_layer: 0", - " network_id: 100", + " link_layer: 5", + " network_id: 0", " time_ms: 0", " transports: 0", " default_network_event <", - " default_network_duration_ms: 0", + " default_network_duration_ms: 200", " final_score: 0", " initial_score: 0", " ip_support: 0", - " network_id <", - " network_id: 100", - " >", " no_default_network_duration_ms: 0", - " previous_network_id <", - " network_id: 0", - " >", + " previous_default_network_link_layer: 0", " previous_network_ip_support: 0", - " transport_types: 0", + " validation_duration_ms: 0", " >", ">", "events <", " if_name: \"\"", - " link_layer: 0", - " network_id: 101", + " link_layer: 2", + " network_id: 100", " time_ms: 0", - " transports: 0", + " transports: 1", " default_network_event <", - " default_network_duration_ms: 0", - " final_score: 0", - " initial_score: 0", - " ip_support: 0", - " network_id <", - " network_id: 101", - " >", + " default_network_duration_ms: 100", + " final_score: 50", + " initial_score: 50", + " ip_support: 2", " no_default_network_duration_ms: 0", - " previous_network_id <", - " network_id: 100", - " >", - " previous_network_ip_support: 2", - " transport_types: 1", + " previous_default_network_link_layer: 0", + " previous_network_ip_support: 0", + " validation_duration_ms: 100", " >", ">", "events <", diff --git a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java index 6723601fc5c3..83194d9e6fa9 100644 --- a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java +++ b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java @@ -82,9 +82,8 @@ public class NetdEventListenerServiceTest { public void testWakeupEventLogging() throws Exception { final int BUFFER_LENGTH = NetdEventListenerService.WAKEUP_EVENT_BUFFER_LENGTH; - // Assert no events - String[] events1 = listNetdEvent(); - assertEquals(new String[]{""}, events1); + // Baseline without any event + String[] baseline = listNetdEvent(); long now = System.currentTimeMillis(); String prefix = "iface:wlan0"; @@ -93,7 +92,7 @@ public class NetdEventListenerServiceTest { mNetdEventListenerService.onWakeupEvent(prefix, uid, uid, now); } - String[] events2 = listNetdEvent(); + String[] events2 = remove(listNetdEvent(), baseline); int expectedLength2 = uids.length + 1; // +1 for the WakeupStats line assertEquals(expectedLength2, events2.length); assertContains(events2[0], "WakeupStats"); @@ -111,7 +110,7 @@ public class NetdEventListenerServiceTest { mNetdEventListenerService.onWakeupEvent(prefix, uid, uid, ts); } - String[] events3 = listNetdEvent(); + String[] events3 = remove(listNetdEvent(), baseline); int expectedLength3 = BUFFER_LENGTH + 1; // +1 for the WakeupStats line assertEquals(expectedLength3, events3.length); assertContains(events2[0], "WakeupStats"); @@ -126,7 +125,7 @@ public class NetdEventListenerServiceTest { uid = 45678; mNetdEventListenerService.onWakeupEvent(prefix, uid, uid, now); - String[] events4 = listNetdEvent(); + String[] events4 = remove(listNetdEvent(), baseline); String lastEvent = events4[events4.length - 1]; assertContains(lastEvent, "WakeupEvent"); assertContains(lastEvent, "wlan0"); @@ -423,7 +422,7 @@ public class NetdEventListenerServiceTest { final PrintWriter pw = new PrintWriter(new FileOutputStream("/dev/null")); new Thread(() -> { while (System.currentTimeMillis() < stop) { - mNetdEventListenerService.dump(pw); + mNetdEventListenerService.list(pw); } }).start(); } @@ -461,4 +460,16 @@ public class NetdEventListenerServiceTest { static void assertContains(String got, String want) { assertTrue(got + " did not contain \"" + want + "\"", got.contains(want)); } + + static <T> T[] remove(T[] array, T[] filtered) { + List<T> c = Arrays.asList(filtered); + int next = 0; + for (int i = 0; i < array.length; i++) { + if (c.contains(array[i])) { + continue; + } + array[next++] = array[i]; + } + return Arrays.copyOf(array, next); + } } |