From 4eb3a8a9661ab0e47ebb5490d71be8aed5d953fd Mon Sep 17 00:00:00 2001 From: lucaslin Date: Fri, 26 Nov 2021 17:14:43 +0800 Subject: [PATCH] Update the transport types of metrics In the current design, the transport types of metrics won't be updated when the underlying network of VPN is changed. Update the transport types of metrics when getMetricsForNetwork() is called. And since the underlying network is changed, enforce to collect the pending metrics before updating the transport types. dns/connect events: // The original underlying network is wifi, but now it's replaced by mobile data. ConnectStats(netId=105, transports={0, 4}, 0 events, 0 success, 0 blocking, 0 IPv6 dst) DnsEvent(netId=105, transports={0, 4}, 4 events, 4 success) network statistics: // Wifi is the underlying network of VPN {netId=105, transports={1, 4}, dns avg=488ms max=633ms err=0.0% tot=2, connect avg=0ms max=0ms err=0.0% tot=0, tcp avg_loss=0.0% total_sent=0 total_lost=0, tcp rtt=0ms, tcp sent-ack_diff=0ms} // Mobile data is the underlying network of VPN {netId=105, transports={0, 4}, dns avg=633ms max=633ms err=0.0% tot=1, connect avg=0ms max=0ms err=0.0% tot=0, tcp avg_loss=0.0% total_sent=0 total_lost=0, tcp rtt=0ms, tcp sent-ack_diff=0ms} Bug: 189166339 Test: Manual test. Change-Id: I9b1d0c635f30d0c88d85777d820b15e546bda60b --- .../NetdEventListenerService.java | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java index 6ea84ce350024..ee5bda3abc91e 100644 --- a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java +++ b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java @@ -171,25 +171,28 @@ public class NetdEventListenerService extends INetdEventListener.Stub { } private NetworkMetrics getMetricsForNetwork(long timeMs, int netId) { - collectPendingMetricsSnapshot(timeMs); NetworkMetrics metrics = mNetworkMetrics.get(netId); - if (metrics == null) { - // TODO: allow to change transport for a given netid. - metrics = new NetworkMetrics(netId, getTransports(netId), mConnectTb); + final NetworkCapabilities nc = mCallback.getNetworkCapabilities(netId); + final long transports = (nc != null) ? BitUtils.packBits(nc.getTransportTypes()) : 0; + final boolean forceCollect = + (metrics != null && nc != null && metrics.transports != transports); + collectPendingMetricsSnapshot(timeMs, forceCollect); + if (metrics == null || forceCollect) { + metrics = new NetworkMetrics(netId, transports, mConnectTb); mNetworkMetrics.put(netId, metrics); } return metrics; } private NetworkMetricsSnapshot[] getNetworkMetricsSnapshots() { - collectPendingMetricsSnapshot(System.currentTimeMillis()); + collectPendingMetricsSnapshot(System.currentTimeMillis(), false /* forceCollect */); return mNetworkMetricsSnapshots.toArray(); } - private void collectPendingMetricsSnapshot(long timeMs) { + private void collectPendingMetricsSnapshot(long timeMs, boolean forceCollect) { // Detects time differences larger than the snapshot collection period. // This is robust against clock jumps and long inactivity periods. - if (Math.abs(timeMs - mLastSnapshot) <= METRICS_SNAPSHOT_SPAN_MS) { + if (!forceCollect && Math.abs(timeMs - mLastSnapshot) <= METRICS_SNAPSHOT_SPAN_MS) { return; } mLastSnapshot = projectSnapshotTime(timeMs); @@ -394,14 +397,6 @@ public class NetdEventListenerService extends INetdEventListener.Stub { return list; } - private long getTransports(int netId) { - final NetworkCapabilities nc = mCallback.getNetworkCapabilities(netId); - if (nc == null) { - return 0; - } - return BitUtils.packBits(nc.getTransportTypes()); - } - /** Helper class for buffering summaries of NetworkMetrics at regular time intervals */ static class NetworkMetricsSnapshot {