diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl index 90e3ffd550..381cfb61de 100644 --- a/core/java/android/net/INetworkStatsService.aidl +++ b/core/java/android/net/INetworkStatsService.aidl @@ -39,9 +39,6 @@ interface INetworkStatsService { */ INetworkStatsSession openSessionForUsageStats(int flags, String callingPackage); - /** Return network layer usage total for traffic that matches template. */ - long getNetworkTotalBytes(in NetworkTemplate template, long start, long end); - /** Return data layer snapshot of UID network usage. */ NetworkStats getDataLayerSnapshotForUid(int uid); /** Return set of any ifaces associated with mobile networks since boot. */ @@ -50,17 +47,11 @@ interface INetworkStatsService { /** Increment data layer count of operations performed for UID and tag. */ void incrementOperationCount(int uid, int tag, int operationCount); - /** Mark given UID as being in foreground for stats purposes. */ - void setUidForeground(int uid, boolean uidForeground); - /** Force update of ifaces. */ void forceUpdateIfaces(in Network[] defaultNetworks); /** Force update of statistics. */ void forceUpdate(); - /** Advise persistance threshold; may be overridden internally. */ - void advisePersistThreshold(long thresholdBytes); - /** Registers a callback on data usage. */ DataUsageRequest registerUsageCallback(String callingPackage, in DataUsageRequest request, in Messenger messenger, in IBinder binder); diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java index 01b2b39213..16fb858a58 100644 --- a/core/java/android/net/NetworkStats.java +++ b/core/java/android/net/NetworkStats.java @@ -234,7 +234,7 @@ public class NetworkStats implements Parcelable { public NetworkStats(long elapsedRealtime, int initialSize) { this.elapsedRealtime = elapsedRealtime; this.size = 0; - if (initialSize >= 0) { + if (initialSize > 0) { this.capacity = initialSize; this.iface = new String[initialSize]; this.uid = new int[initialSize]; @@ -250,19 +250,7 @@ public class NetworkStats implements Parcelable { this.operations = new long[initialSize]; } else { // Special case for use by NetworkStatsFactory to start out *really* empty. - this.capacity = 0; - this.iface = EmptyArray.STRING; - this.uid = EmptyArray.INT; - this.set = EmptyArray.INT; - this.tag = EmptyArray.INT; - this.metered = EmptyArray.INT; - this.roaming = EmptyArray.INT; - this.defaultNetwork = EmptyArray.INT; - this.rxBytes = EmptyArray.LONG; - this.rxPackets = EmptyArray.LONG; - this.txBytes = EmptyArray.LONG; - this.txPackets = EmptyArray.LONG; - this.operations = EmptyArray.LONG; + clear(); } } @@ -314,6 +302,25 @@ public class NetworkStats implements Parcelable { return clone; } + /** + * Clear all data stored in this object. + */ + public void clear() { + this.capacity = 0; + this.iface = EmptyArray.STRING; + this.uid = EmptyArray.INT; + this.set = EmptyArray.INT; + this.tag = EmptyArray.INT; + this.metered = EmptyArray.INT; + this.roaming = EmptyArray.INT; + this.defaultNetwork = EmptyArray.INT; + this.rxBytes = EmptyArray.LONG; + this.rxPackets = EmptyArray.LONG; + this.txBytes = EmptyArray.LONG; + this.txPackets = EmptyArray.LONG; + this.operations = EmptyArray.LONG; + } + @VisibleForTesting public NetworkStats addIfaceValues( String iface, long rxBytes, long rxPackets, long txBytes, long txPackets) { diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java index 433f9410cc..a13ad659e7 100644 --- a/core/java/android/net/NetworkStatsHistory.java +++ b/core/java/android/net/NetworkStatsHistory.java @@ -39,6 +39,8 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.util.IndentingPrintWriter; +import libcore.util.EmptyArray; + import java.io.CharArrayWriter; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -458,6 +460,21 @@ public class NetworkStatsHistory implements Parcelable { bucketCount++; } + /** + * Clear all data stored in this object. + */ + public void clear() { + bucketStart = EmptyArray.LONG; + if (activeTime != null) activeTime = EmptyArray.LONG; + if (rxBytes != null) rxBytes = EmptyArray.LONG; + if (rxPackets != null) rxPackets = EmptyArray.LONG; + if (txBytes != null) txBytes = EmptyArray.LONG; + if (txPackets != null) txPackets = EmptyArray.LONG; + if (operations != null) operations = EmptyArray.LONG; + bucketCount = 0; + totalBytes = 0; + } + /** * Remove buckets older than requested cutoff. */ diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java index 8efd39a7a7..74233fd990 100644 --- a/core/java/android/net/NetworkTemplate.java +++ b/core/java/android/net/NetworkTemplate.java @@ -23,7 +23,6 @@ import static android.net.ConnectivityManager.TYPE_PROXY; import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.ConnectivityManager.TYPE_WIFI_P2P; import static android.net.ConnectivityManager.TYPE_WIMAX; -import static android.net.NetworkIdentity.COMBINE_SUBTYPE_ENABLED; import static android.net.NetworkStats.DEFAULT_NETWORK_ALL; import static android.net.NetworkStats.DEFAULT_NETWORK_NO; import static android.net.NetworkStats.DEFAULT_NETWORK_YES; @@ -34,11 +33,6 @@ import static android.net.NetworkStats.ROAMING_ALL; import static android.net.NetworkStats.ROAMING_NO; import static android.net.NetworkStats.ROAMING_YES; import static android.net.wifi.WifiInfo.removeDoubleQuotes; -import static android.telephony.TelephonyManager.NETWORK_CLASS_2_G; -import static android.telephony.TelephonyManager.NETWORK_CLASS_3_G; -import static android.telephony.TelephonyManager.NETWORK_CLASS_4_G; -import static android.telephony.TelephonyManager.NETWORK_CLASS_UNKNOWN; -import static android.telephony.TelephonyManager.getNetworkClass; import android.os.Parcel; import android.os.Parcelable; @@ -55,8 +49,8 @@ import java.util.Arrays; import java.util.Objects; /** - * Template definition used to generically match {@link NetworkIdentity}, - * usually when collecting statistics. + * Predicate used to match {@link NetworkIdentity}, usually when collecting + * statistics. (It should probably have been named {@code NetworkPredicate}.) * * @hide */ @@ -68,13 +62,7 @@ public class NetworkTemplate implements Parcelable { */ private static final int BACKUP_VERSION = 1; - public static final int MATCH_MOBILE_ALL = 1; - /** @deprecated don't use this any more */ - @Deprecated - public static final int MATCH_MOBILE_3G_LOWER = 2; - /** @deprecated don't use this any more */ - @Deprecated - public static final int MATCH_MOBILE_4G = 3; + public static final int MATCH_MOBILE = 1; public static final int MATCH_WIFI = 4; public static final int MATCH_ETHERNET = 5; public static final int MATCH_MOBILE_WILDCARD = 6; @@ -84,9 +72,7 @@ public class NetworkTemplate implements Parcelable { private static boolean isKnownMatchRule(final int rule) { switch (rule) { - case MATCH_MOBILE_ALL: - case MATCH_MOBILE_3G_LOWER: - case MATCH_MOBILE_4G: + case MATCH_MOBILE: case MATCH_WIFI: case MATCH_ETHERNET: case MATCH_MOBILE_WILDCARD: @@ -111,25 +97,7 @@ public class NetworkTemplate implements Parcelable { * the given IMSI. */ public static NetworkTemplate buildTemplateMobileAll(String subscriberId) { - return new NetworkTemplate(MATCH_MOBILE_ALL, subscriberId, null); - } - - /** - * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with - * the given IMSI that roughly meet a "3G" definition, or lower. - */ - @Deprecated - public static NetworkTemplate buildTemplateMobile3gLower(String subscriberId) { - return new NetworkTemplate(MATCH_MOBILE_3G_LOWER, subscriberId, null); - } - - /** - * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with - * the given IMSI that roughly meet a "4G" definition. - */ - @Deprecated - public static NetworkTemplate buildTemplateMobile4g(String subscriberId) { - return new NetworkTemplate(MATCH_MOBILE_4G, subscriberId, null); + return new NetworkTemplate(MATCH_MOBILE, subscriberId, null); } /** @@ -307,9 +275,7 @@ public class NetworkTemplate implements Parcelable { public boolean isMatchRuleMobile() { switch (mMatchRule) { - case MATCH_MOBILE_3G_LOWER: - case MATCH_MOBILE_4G: - case MATCH_MOBILE_ALL: + case MATCH_MOBILE: case MATCH_MOBILE_WILDCARD: return true; default: @@ -348,12 +314,8 @@ public class NetworkTemplate implements Parcelable { if (!matchesDefaultNetwork(ident)) return false; switch (mMatchRule) { - case MATCH_MOBILE_ALL: + case MATCH_MOBILE: return matchesMobile(ident); - case MATCH_MOBILE_3G_LOWER: - return matchesMobile3gLower(ident); - case MATCH_MOBILE_4G: - return matchesMobile4g(ident); case MATCH_WIFI: return matchesWifi(ident); case MATCH_ETHERNET: @@ -409,43 +371,6 @@ public class NetworkTemplate implements Parcelable { } } - /** - * Check if mobile network classified 3G or lower with matching IMSI. - */ - @Deprecated - private boolean matchesMobile3gLower(NetworkIdentity ident) { - ensureSubtypeAvailable(); - if (ident.mType == TYPE_WIMAX) { - return false; - } else if (matchesMobile(ident)) { - switch (getNetworkClass(ident.mSubType)) { - case NETWORK_CLASS_UNKNOWN: - case NETWORK_CLASS_2_G: - case NETWORK_CLASS_3_G: - return true; - } - } - return false; - } - - /** - * Check if mobile network classified 4G with matching IMSI. - */ - @Deprecated - private boolean matchesMobile4g(NetworkIdentity ident) { - ensureSubtypeAvailable(); - if (ident.mType == TYPE_WIMAX) { - // TODO: consider matching against WiMAX subscriber identity - return true; - } else if (matchesMobile(ident)) { - switch (getNetworkClass(ident.mSubType)) { - case NETWORK_CLASS_4_G: - return true; - } - } - return false; - } - /** * Check if matches Wi-Fi network template. */ @@ -506,12 +431,8 @@ public class NetworkTemplate implements Parcelable { private static String getMatchRuleName(int matchRule) { switch (matchRule) { - case MATCH_MOBILE_3G_LOWER: - return "MOBILE_3G_LOWER"; - case MATCH_MOBILE_4G: - return "MOBILE_4G"; - case MATCH_MOBILE_ALL: - return "MOBILE_ALL"; + case MATCH_MOBILE: + return "MOBILE"; case MATCH_WIFI: return "WIFI"; case MATCH_ETHERNET: @@ -529,13 +450,6 @@ public class NetworkTemplate implements Parcelable { } } - private static void ensureSubtypeAvailable() { - if (COMBINE_SUBTYPE_ENABLED) { - throw new IllegalArgumentException( - "Unable to enforce 3G_LOWER template on combined data."); - } - } - /** * Examine the given template and normalize if it refers to a "merged" * mobile subscriber. We pick the "lowest" merged subscriber as the primary diff --git a/services/core/java/com/android/server/net/NetworkStatsCollection.java b/services/core/java/com/android/server/net/NetworkStatsCollection.java index 3cc4d83267..a5f8dc72d8 100644 --- a/services/core/java/com/android/server/net/NetworkStatsCollection.java +++ b/services/core/java/com/android/server/net/NetworkStatsCollection.java @@ -106,6 +106,10 @@ public class NetworkStatsCollection implements FileRotator.Reader { reset(); } + public void clear() { + reset(); + } + public void reset() { mStats.clear(); mStartMillis = Long.MAX_VALUE; diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 32e15c9d9c..93c04fe206 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -49,7 +49,6 @@ import static android.provider.Settings.Global.NETSTATS_DEV_ROTATE_AGE; import static android.provider.Settings.Global.NETSTATS_GLOBAL_ALERT_BYTES; import static android.provider.Settings.Global.NETSTATS_POLL_INTERVAL; import static android.provider.Settings.Global.NETSTATS_SAMPLE_ENABLED; -import static android.provider.Settings.Global.NETSTATS_TIME_CACHE_MAX_AGE; import static android.provider.Settings.Global.NETSTATS_UID_BUCKET_DURATION; import static android.provider.Settings.Global.NETSTATS_UID_DELETE_AGE; import static android.provider.Settings.Global.NETSTATS_UID_PERSIST_BYTES; @@ -95,10 +94,10 @@ import android.net.NetworkStats.NonMonotonicObserver; import android.net.NetworkStatsHistory; import android.net.NetworkTemplate; import android.net.TrafficStats; +import android.os.BestClock; import android.os.Binder; import android.os.DropBoxManager; import android.os.Environment; -import android.os.BestClock; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; @@ -134,6 +133,7 @@ import com.android.internal.util.DumpUtils; import com.android.internal.util.FileRotator; import com.android.internal.util.IndentingPrintWriter; import com.android.server.EventLogTags; +import com.android.server.LocalServices; import com.android.server.connectivity.Tethering; import java.io.File; @@ -333,6 +333,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mStatsObservers = checkNotNull(statsObservers, "missing NetworkStatsObservers"); mSystemDir = checkNotNull(systemDir, "missing systemDir"); mBaseDir = checkNotNull(baseDir, "missing baseDir"); + + LocalServices.addService(NetworkStatsManagerInternal.class, + new NetworkStatsManagerInternalImpl()); } @VisibleForTesting @@ -640,7 +643,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private SubscriptionPlan resolveSubscriptionPlan(NetworkTemplate template, int flags) { SubscriptionPlan plan = null; if ((flags & NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN) != 0 - && (template.getMatchRule() == NetworkTemplate.MATCH_MOBILE_ALL) + && (template.getMatchRule() == NetworkTemplate.MATCH_MOBILE) && mSettings.getAugmentEnabled()) { if (LOGD) Slog.d(TAG, "Resolving plan for " + template); final long token = Binder.clearCallingIdentity(); @@ -701,12 +704,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } } - @Override - public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) { - // Special case - since this is for internal use only, don't worry about - // a full access level check and just require the signature/privileged - // permission. - mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG); + private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) { + assertSystemReady(); assertBandwidthControlEnabled(); // NOTE: if callers want to get non-augmented data, they should go @@ -716,6 +715,18 @@ public class NetworkStatsService extends INetworkStatsService.Stub { NetworkStatsAccess.Level.DEVICE, Binder.getCallingUid()).getTotalBytes(); } + private NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) { + assertSystemReady(); + assertBandwidthControlEnabled(); + + final NetworkStatsCollection uidComplete; + synchronized (mStatsLock) { + uidComplete = mUidRecorder.getOrLoadCompleteLocked(); + } + return uidComplete.getSummary(template, start, end, NetworkStatsAccess.Level.DEVICE, + android.os.Process.SYSTEM_UID); + } + @Override public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException { if (Binder.getCallingUid() != uid) { @@ -777,10 +788,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } } - @Override - public void setUidForeground(int uid, boolean uidForeground) { - mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); - + @VisibleForTesting + void setUidForeground(int uid, boolean uidForeground) { synchronized (mStatsLock) { final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT; final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT); @@ -817,9 +826,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } } - @Override - public void advisePersistThreshold(long thresholdBytes) { - mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); + private void advisePersistThreshold(long thresholdBytes) { assertBandwidthControlEnabled(); // clamp threshold into safe range @@ -1330,6 +1337,33 @@ public class NetworkStatsService extends INetworkStatsService.Stub { removeUidsLocked(uids); } + private class NetworkStatsManagerInternalImpl extends NetworkStatsManagerInternal { + @Override + public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) { + return NetworkStatsService.this.getNetworkTotalBytes(template, start, end); + } + + @Override + public NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) { + return NetworkStatsService.this.getNetworkUidBytes(template, start, end); + } + + @Override + public void setUidForeground(int uid, boolean uidForeground) { + NetworkStatsService.this.setUidForeground(uid, uidForeground); + } + + @Override + public void advisePersistThreshold(long thresholdBytes) { + NetworkStatsService.this.advisePersistThreshold(thresholdBytes); + } + + @Override + public void forceUpdate() { + NetworkStatsService.this.forceUpdate(); + } + } + @Override protected void dump(FileDescriptor fd, PrintWriter rawWriter, String[] args) { if (!DumpUtils.checkDumpPermission(mContext, TAG, rawWriter)) return; @@ -1550,6 +1584,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } } + private void assertSystemReady() { + if (!mSystemReady) { + throw new IllegalStateException("System not ready"); + } + } + private void assertBandwidthControlEnabled() { if (!isBandwidthControlEnabled()) { throw new IllegalStateException("Bandwidth module disabled");