From 1654b1d11c3f4195d6f691bd1b6eb5aa672ffc94 Mon Sep 17 00:00:00 2001 From: Hugo Benichi Date: Tue, 24 May 2016 11:50:31 +0900 Subject: [PATCH] Fix default network transition event recording When disconnecting from a default network X and falling back on another connected network Y as the new default, ConnectivityService was attempting to record this event as a X -> Y "atomic" transition. In practice the default network connectivity is actually lost and recovering default network takes some non-zero time. This patch changes the event recording to always record disconnection as X -> 0 events. At the same time, if there is a fallback network that is elected as the new default ConnectivityService will also record a 0 -> Y event. This patch also improves pretty-printing of DefaultNetworkEvent. Extract from $ adb shell dumpsys connectivity_metrics_logger --events 17:51:00.086: DefaultNetworkEvent(0 -> 100:CELLULAR) 17:51:25.232: DefaultNetworkEvent(100:IPv4 -> 101:WIFI) # wifi goes on 17:51:44.064: DefaultNetworkEvent(101:DUAL -> 0) # wifi goes off 17:51:44.187: DefaultNetworkEvent(0 -> 100:CELLULAR) Bug: 28204408 Change-Id: I63252633235bf6ba833b9ac431a80dda75a93e67 --- .../net/metrics/DefaultNetworkEvent.java | 24 +++++++++++++++++-- .../android/server/ConnectivityService.java | 16 +++++++------ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/core/java/android/net/metrics/DefaultNetworkEvent.java b/core/java/android/net/metrics/DefaultNetworkEvent.java index 6138b83fe5b8b..f8b59925cb910 100644 --- a/core/java/android/net/metrics/DefaultNetworkEvent.java +++ b/core/java/android/net/metrics/DefaultNetworkEvent.java @@ -68,8 +68,28 @@ public final class DefaultNetworkEvent extends IpConnectivityEvent implements Pa @Override public String toString() { - return String.format("DefaultNetworkEvent(%d -> %d, %s, IPv4: %b, IPv6: %b)", prevNetId, - netId, NetworkCapabilities.transportNamesOf(transportTypes), prevIPv4, prevIPv6); + String prevNetwork = String.valueOf(prevNetId); + String newNetwork = String.valueOf(netId); + if (prevNetId != 0) { + prevNetwork += ":" + ipSupport(); + } + if (netId != 0) { + newNetwork += ":" + NetworkCapabilities.transportNamesOf(transportTypes); + } + return String.format("DefaultNetworkEvent(%s -> %s)", prevNetwork, newNetwork); + } + + private String ipSupport() { + if (prevIPv4 && prevIPv6) { + return "DUAL"; + } + if (prevIPv6) { + return "IPv6"; + } + if (prevIPv4) { + return "IPv4"; + } + return "NONE"; } public static final Parcelable.Creator CREATOR diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index c096fa5f39467..c30e54005e8d3 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -2245,6 +2245,11 @@ public class ConnectivityService extends IConnectivityManager.Stub final boolean wasDefault = isDefaultNetwork(nai); if (wasDefault) { mDefaultInetConditionPublished = 0; + // Log default network disconnection before required book-keeping. + // 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. + logDefaultNetworkEvent(null, nai); } notifyIfacesChangedForNetworkStats(); // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied @@ -2278,10 +2283,6 @@ public class ConnectivityService extends IConnectivityManager.Stub } mLegacyTypeTracker.remove(nai, wasDefault); rematchAllNetworksAndRequests(null, 0); - if (wasDefault && getDefaultNetwork() == null) { - // Log that we lost the default network and there is no replacement. - logDefaultNetworkEvent(null, nai); - } if (nai.created) { // Tell netd to clean up the configuration for this network // (routing rules, DNS, etc). @@ -4583,7 +4584,7 @@ public class ConnectivityService extends IConnectivityManager.Stub teardownUnneededNetwork(oldNetwork); } - private void makeDefault(NetworkAgentInfo newNetwork, NetworkAgentInfo prevNetwork) { + private void makeDefault(NetworkAgentInfo newNetwork) { if (DBG) log("Switching to new default network: " + newNetwork); setupDataActivityTracking(newNetwork); try { @@ -4595,7 +4596,6 @@ public class ConnectivityService extends IConnectivityManager.Stub handleApplyDefaultProxy(newNetwork.linkProperties.getHttpProxy()); updateTcpBufferSizes(newNetwork); setDefaultDnsSystemProperties(newNetwork.linkProperties.getDnsServers()); - logDefaultNetworkEvent(newNetwork, prevNetwork); } // Handles a network appearing or improving its score. @@ -4746,7 +4746,9 @@ public class ConnectivityService extends IConnectivityManager.Stub } if (isNewDefault) { // Notify system services that this network is up. - makeDefault(newNetwork, oldDefaultNetwork); + makeDefault(newNetwork); + // Log 0 -> X and Y -> X default network transitions, where X is the new default. + logDefaultNetworkEvent(newNetwork, oldDefaultNetwork); synchronized (ConnectivityService.this) { // have a new default network, release the transition wakelock in // a second if it's held. The second pause is to allow apps