Loading core/java/android/net/metrics/DefaultNetworkEvent.java +47 −19 Original line number Diff line number Diff line Loading @@ -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"; Loading proto/src/ipconnectivity.proto +25 −11 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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 Loading @@ -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. Loading services/core/java/com/android/server/ConnectivityService.java +8 −2 Original line number Diff line number Diff line Loading @@ -2113,9 +2113,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; Loading Loading @@ -2287,7 +2292,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 Loading Loading @@ -5041,7 +5047,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(); } Loading services/core/java/com/android/server/connectivity/DefaultNetworkMetrics.java +102 −15 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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)); } } Loading @@ -59,20 +91,75 @@ public class DefaultNetworkMetrics { mEvents.clear(); } public synchronized void logDefaultNetworkValidity(long timeMs, boolean isValid) { if (!isValid && mIsCurrentlyValid) { mIsCurrentlyValid = false; updateValidationTime(timeMs); } if (isValid && !mIsCurrentlyValid) { mIsCurrentlyValid = true; mLastValidationTimeMs = timeMs; } } private void updateValidationTime(long timeMs) { mCurrentDefaultNetwork.validatedMs += timeMs - mLastValidationTimeMs; } public synchronized void logDefaultNetworkEvent( NetworkAgentInfo newNai, NetworkAgentInfo prevNai) { DefaultNetworkEvent ev = new DefaultNetworkEvent(); 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) { ev.netId = newNai.network().netId; ev.transportTypes = newNai.networkCapabilities.getTransportTypes(); fillLinkInfo(ev, newNai); ev.initialScore = newNai.getCurrentScore(); if (newNai.lastValidated) { mIsCurrentlyValid = true; mLastValidationTimeMs = 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(); mCurrentDefaultNetwork = ev; } mEvents.add(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)); } } services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java +15 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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; Loading Loading
core/java/android/net/metrics/DefaultNetworkEvent.java +47 −19 Original line number Diff line number Diff line Loading @@ -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"; Loading
proto/src/ipconnectivity.proto +25 −11 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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 Loading @@ -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. Loading
services/core/java/com/android/server/ConnectivityService.java +8 −2 Original line number Diff line number Diff line Loading @@ -2113,9 +2113,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; Loading Loading @@ -2287,7 +2292,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 Loading Loading @@ -5041,7 +5047,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(); } Loading
services/core/java/com/android/server/connectivity/DefaultNetworkMetrics.java +102 −15 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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)); } } Loading @@ -59,20 +91,75 @@ public class DefaultNetworkMetrics { mEvents.clear(); } public synchronized void logDefaultNetworkValidity(long timeMs, boolean isValid) { if (!isValid && mIsCurrentlyValid) { mIsCurrentlyValid = false; updateValidationTime(timeMs); } if (isValid && !mIsCurrentlyValid) { mIsCurrentlyValid = true; mLastValidationTimeMs = timeMs; } } private void updateValidationTime(long timeMs) { mCurrentDefaultNetwork.validatedMs += timeMs - mLastValidationTimeMs; } public synchronized void logDefaultNetworkEvent( NetworkAgentInfo newNai, NetworkAgentInfo prevNai) { DefaultNetworkEvent ev = new DefaultNetworkEvent(); 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) { ev.netId = newNai.network().netId; ev.transportTypes = newNai.networkCapabilities.getTransportTypes(); fillLinkInfo(ev, newNai); ev.initialScore = newNai.getCurrentScore(); if (newNai.lastValidated) { mIsCurrentlyValid = true; mLastValidationTimeMs = 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(); mCurrentDefaultNetwork = ev; } mEvents.add(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)); } }
services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java +15 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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; Loading