Name specific app for rapid data usage.

When a single app is responsible for more than half of the data usage
that caused us to trigger a "rapid usage" alert, name that app in the
notification.  Tests to verify.

Move NPMS->NSS direct calls to "Internal" pattern, following
best-practices to avoid unnecessary AIDL exposure.

Remove 3G/4G split mobile plan support, which has been deprecated for
years and was never supported in a shipping product.

Move MultipathPolicyTracker in tree to reflect its package name.

Test: bit FrameworksNetTests:*
Test: bit FrameworksServicesTests:com.android.server.NetworkPolicyManagerServiceTest
Bug: 69263587, 64221505, 73431080, 72746951
Exempt-From-Owner-Approval: approved in previous PS
Change-Id: I3e4ec1ae2222d51b232f76f32faca93d4f8cd272
This commit is contained in:
Jeff Sharkey
2018-02-20 17:24:55 -07:00
committed by Jeff Sharkey
parent ddd09dfbe7
commit 1459069bb6
6 changed files with 107 additions and 134 deletions

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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.
*/

View File

@@ -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

View File

@@ -106,6 +106,10 @@ public class NetworkStatsCollection implements FileRotator.Reader {
reset();
}
public void clear() {
reset();
}
public void reset() {
mStats.clear();
mStartMillis = Long.MAX_VALUE;

View File

@@ -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");