From e544a48eb24dcb1b6b8e4e85d00325c0eaf4b889 Mon Sep 17 00:00:00 2001 From: Jack Yu Date: Wed, 22 Jun 2016 11:35:10 -0700 Subject: [PATCH] Added a virtual interface for Video Telephony call usage counting 1. Added a virtual VT interface. 2. Qeury VT usage from telephony service. bug: 20888836 Change-Id: I3df0c22922f8394554230b53f8ae091e17c95595 --- .../server/net/NetworkStatsService.java | 64 ++++++++++++++++++- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 23c111e56c..4658c0463f 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -31,6 +31,7 @@ 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.TAG_ALL; import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.UID_ALL; import static android.net.NetworkTemplate.buildTemplateMobileWildcard; @@ -79,6 +80,7 @@ import android.net.INetworkManagementEventObserver; import android.net.INetworkStatsService; import android.net.INetworkStatsSession; import android.net.LinkProperties; +import android.net.NetworkCapabilities; import android.net.NetworkIdentity; import android.net.NetworkInfo; import android.net.NetworkState; @@ -178,6 +180,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private static final String PREFIX_UID = "uid"; private static final String PREFIX_UID_TAG = "uid_tag"; + /** + * Virtual network interface for video telephony. This is for VT data usage counting purpose. + */ + public static final String VT_INTERFACE = "vt_data0"; + /** * Settings that can be changed externally. */ @@ -967,6 +974,23 @@ public class NetworkStatsService extends INetworkStatsService.Stub { if (baseIface != null) { findOrCreateNetworkIdentitySet(mActiveIfaces, baseIface).add(ident); findOrCreateNetworkIdentitySet(mActiveUidIfaces, baseIface).add(ident); + + // Build a separate virtual interface for VT (Video Telephony) data usage. + // Only do this when IMS is not metered, but VT is metered. + // If IMS is metered, then the IMS network usage has already included VT usage. + // VT is considered always metered in framework's layer. If VT is not metered + // per carrier's policy, modem will report 0 usage for VT calls. + if (state.networkCapabilities.hasCapability( + NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.getMetered()) { + + // Copy the identify from IMS one but mark it as metered. + NetworkIdentity vtIdent = new NetworkIdentity(ident.getType(), + ident.getSubType(), ident.getSubscriberId(), ident.getNetworkId(), + ident.getRoaming(), true); + findOrCreateNetworkIdentitySet(mActiveIfaces, VT_INTERFACE).add(vtIdent); + findOrCreateNetworkIdentitySet(mActiveUidIfaces, VT_INTERFACE).add(vtIdent); + } + if (isMobile) { mobileIfaces.add(baseIface); } @@ -1004,9 +1028,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private void recordSnapshotLocked(long currentTime) throws RemoteException { // snapshot and record current counters; read UID stats first to - // avoid overcounting dev stats. + // avoid over counting dev stats. final NetworkStats uidSnapshot = getNetworkStatsUidDetail(); - final NetworkStats xtSnapshot = mNetworkManager.getNetworkStatsSummaryXt(); + final NetworkStats xtSnapshot = getNetworkStatsXtAndVt(); final NetworkStats devSnapshot = mNetworkManager.getNetworkStatsSummaryDev(); @@ -1311,6 +1335,42 @@ public class NetworkStatsService extends INetworkStatsService.Stub { return uidSnapshot; } + /** + * Return snapshot of current XT plus VT statistics. + */ + private NetworkStats getNetworkStatsXtAndVt() throws RemoteException { + final NetworkStats xtSnapshot = mNetworkManager.getNetworkStatsSummaryXt(); + + TelephonyManager tm = (TelephonyManager) mContext.getSystemService( + Context.TELEPHONY_SERVICE); + + long usage = tm.getVtDataUsage(); + + if (LOGV) Slog.d(TAG, "VT call data usage = " + usage); + + final NetworkStats vtSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 1); + + final NetworkStats.Entry entry = new NetworkStats.Entry(); + entry.iface = VT_INTERFACE; + entry.uid = -1; + entry.set = TAG_ALL; + entry.tag = TAG_NONE; + + // Since modem only tell us the total usage instead of each usage for RX and TX, + // we need to split it up (though it might not quite accurate). At + // least we can make sure the data usage report to the user will still be accurate. + entry.rxBytes = usage / 2; + entry.rxPackets = 0; + entry.txBytes = usage - entry.rxBytes; + entry.txPackets = 0; + vtSnapshot.combineValues(entry); + + // Merge VT int XT + xtSnapshot.combineAllValues(vtSnapshot); + + return xtSnapshot; + } + /** * Return snapshot of current tethering statistics. Will return empty * {@link NetworkStats} if any problems are encountered.