From f31c942e890dac68c257c347538bac23c772393d Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 17 Aug 2017 19:23:08 +0900 Subject: [PATCH] Add tether offload traffic to interface stats as well. Currently, we only count add tethering traffic to per-UID stats, but not to total data usage (i.e., dev and XT stats). This is correct for software tethering, because all software forwarded packets are already included in interface counters, but it is incorrect for hardware offload, because such packets do not increment interface counters. To fix this: 1. Add an argument to ITetheringStatsProvider#getTetherStats to indicate whether per-UID stats are requested. For clarity, define integer constants STATS_PER_IFACE and STATS_PER_UID to represent these operations. 2. Make NetdTetheringStatsProvider return stats only if per-UID stats are requested. (Otherwise tethering traffic would be double-counted). 3. Make OffloadController's stats provider return the same stats regardless of whether per-UID stats were requested or not. 4. Make NetworkStatsService add non-per-UID tethering stats to the dev and XT snapshots. The per-UID snapshots were already correctly adding in per-UID stats. Bug: 29337859 Bug: 32163131 Test: runtest frameworks-net Test: runtest frameworks-telephony Change-Id: I7a4d04ab47694d754874136179f8edad71099638 --- core/java/android/net/NetworkStats.java | 5 +++++ .../android/server/net/NetworkStatsService.java | 17 ++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java index be9e809738..171adc054b 100644 --- a/core/java/android/net/NetworkStats.java +++ b/core/java/android/net/NetworkStats.java @@ -82,6 +82,11 @@ public class NetworkStats implements Parcelable { /** {@link #roaming} value where roaming data is accounted. */ public static final int ROAMING_YES = 1; + /** Denotes a request for stats at the interface level. */ + public static final int STATS_PER_IFACE = 0; + /** Denotes a request for stats at the interface and UID level. */ + public static final int STATS_PER_UID = 1; + // TODO: move fields to "mVariable" notation /** diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 8209adeb89..b14aa13bfb 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -29,6 +29,8 @@ import static android.net.NetworkStats.IFACE_ALL; import static android.net.NetworkStats.SET_ALL; import static android.net.NetworkStats.SET_DEFAULT; import static android.net.NetworkStats.SET_FOREGROUND; +import static android.net.NetworkStats.STATS_PER_IFACE; +import static android.net.NetworkStats.STATS_PER_UID; import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.UID_ALL; import static android.net.NetworkTemplate.buildTemplateMobileWildcard; @@ -1041,6 +1043,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final NetworkStats xtSnapshot = getNetworkStatsXt(); final NetworkStats devSnapshot = mNetworkManager.getNetworkStatsSummaryDev(); + // Tethering snapshot for dev and xt stats. Counts per-interface data from tethering stats + // providers that isn't already counted by dev and XT stats. + final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_IFACE); + xtSnapshot.combineAllValues(tetherSnapshot); + devSnapshot.combineAllValues(tetherSnapshot); // For xt/dev, we pass a null VPN array because usage is aggregated by UID, so VPN traffic // can't be reattributed to responsible apps. @@ -1371,14 +1378,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final NetworkStats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL); // fold tethering stats and operations into uid snapshot - final NetworkStats tetherSnapshot = getNetworkStatsTethering(); + final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_UID); uidSnapshot.combineAllValues(tetherSnapshot); final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService( Context.TELEPHONY_SERVICE); // fold video calling data usage stats into uid snapshot - final NetworkStats vtStats = telephonyManager.getVtDataUsage(true); + final NetworkStats vtStats = telephonyManager.getVtDataUsage(STATS_PER_UID); if (vtStats != null) { uidSnapshot.combineAllValues(vtStats); } @@ -1397,7 +1404,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { Context.TELEPHONY_SERVICE); // Merge video calling data usage into XT - final NetworkStats vtSnapshot = telephonyManager.getVtDataUsage(false); + final NetworkStats vtSnapshot = telephonyManager.getVtDataUsage(STATS_PER_IFACE); if (vtSnapshot != null) { xtSnapshot.combineAllValues(vtSnapshot); } @@ -1409,9 +1416,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { * Return snapshot of current tethering statistics. Will return empty * {@link NetworkStats} if any problems are encountered. */ - private NetworkStats getNetworkStatsTethering() throws RemoteException { + private NetworkStats getNetworkStatsTethering(int how) throws RemoteException { try { - return mNetworkManager.getNetworkStatsTethering(); + return mNetworkManager.getNetworkStatsTethering(how); } catch (IllegalStateException e) { Log.wtf(TAG, "problem reading network stats", e); return new NetworkStats(0L, 10);