diff options
4 files changed, 97 insertions, 15 deletions
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 6648d1e1f1b2..f15fdd5304a1 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -2286,11 +2286,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); - // roaming networks are always considered metered - if (ident.getRoaming()) { - return true; - } - final NetworkPolicy policy; synchronized (mNetworkPoliciesSecondLock) { policy = findPolicyForNetworkNL(ident); @@ -2300,7 +2295,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return policy.metered; } else { final int type = state.networkInfo.getType(); - if (isNetworkTypeMobile(type) || type == TYPE_WIMAX) { + if ((isNetworkTypeMobile(type) && ident.getMetered()) || type == TYPE_WIMAX) { return true; } return false; diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 23c111e56cde..4658c0463f0e 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; @@ -179,6 +181,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub { 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. */ public interface NetworkStatsSettings { @@ -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(); @@ -1312,6 +1336,42 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } /** + * 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. */ diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 2fb9409ed6a4..26ef0cbb87a5 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -5519,5 +5519,24 @@ public class TelephonyManager { Log.e(TAG, "Error calling ITelephony#carrierActionSetRadioEnabled", e); } } + + /** + * Get aggregated video call data usage since boot. + * Permissions android.Manifest.permission.READ_NETWORK_USAGE_HISTORY is required. + * @return total data usage in bytes + * @hide + */ + public long getVtDataUsage() { + + try { + ITelephony service = getITelephony(); + if (service != null) { + return service.getVtDataUsage(); + } + } catch (RemoteException e) { + Log.e(TAG, "Error calling getVtDataUsage", e); + } + return 0; + } } diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 2171c9ed9f75..2168b0ea80db 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -1133,13 +1133,13 @@ interface ITelephony { */ List<CarrierIdentifier> getAllowedCarriers(int slotId); - /** - * Action set from carrier signalling broadcast receivers to enable/disable metered apns - * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required - * @param subId the subscription ID that this action applies to. - * @param enabled control enable or disable metered apns. - * @hide - */ + /** + * Action set from carrier signalling broadcast receivers to enable/disable metered apns + * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required + * @param subId the subscription ID that this action applies to. + * @param enabled control enable or disable metered apns. + * @hide + */ void carrierActionSetMeteredApnsEnabled(int subId, boolean visible); /** @@ -1150,4 +1150,12 @@ interface ITelephony { * @hide */ void carrierActionSetRadioEnabled(int subId, boolean enabled); + + /** + * Get aggregated video call data usage since boot. + * Permissions android.Manifest.permission.READ_NETWORK_USAGE_HISTORY is required. + * @return total data usage in bytes + * @hide + */ + long getVtDataUsage(); } |