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); 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. */ /** Return data layer snapshot of UID network usage. */
NetworkStats getDataLayerSnapshotForUid(int uid); NetworkStats getDataLayerSnapshotForUid(int uid);
/** Return set of any ifaces associated with mobile networks since boot. */ /** 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. */ /** Increment data layer count of operations performed for UID and tag. */
void incrementOperationCount(int uid, int tag, int operationCount); 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. */ /** Force update of ifaces. */
void forceUpdateIfaces(in Network[] defaultNetworks); void forceUpdateIfaces(in Network[] defaultNetworks);
/** Force update of statistics. */ /** Force update of statistics. */
void forceUpdate(); void forceUpdate();
/** Advise persistance threshold; may be overridden internally. */
void advisePersistThreshold(long thresholdBytes);
/** Registers a callback on data usage. */ /** Registers a callback on data usage. */
DataUsageRequest registerUsageCallback(String callingPackage, DataUsageRequest registerUsageCallback(String callingPackage,
in DataUsageRequest request, in Messenger messenger, in IBinder binder); 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) { public NetworkStats(long elapsedRealtime, int initialSize) {
this.elapsedRealtime = elapsedRealtime; this.elapsedRealtime = elapsedRealtime;
this.size = 0; this.size = 0;
if (initialSize >= 0) { if (initialSize > 0) {
this.capacity = initialSize; this.capacity = initialSize;
this.iface = new String[initialSize]; this.iface = new String[initialSize];
this.uid = new int[initialSize]; this.uid = new int[initialSize];
@@ -250,19 +250,7 @@ public class NetworkStats implements Parcelable {
this.operations = new long[initialSize]; this.operations = new long[initialSize];
} else { } else {
// Special case for use by NetworkStatsFactory to start out *really* empty. // Special case for use by NetworkStatsFactory to start out *really* empty.
this.capacity = 0; clear();
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;
} }
} }
@@ -314,6 +302,25 @@ public class NetworkStats implements Parcelable {
return clone; 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 @VisibleForTesting
public NetworkStats addIfaceValues( public NetworkStats addIfaceValues(
String iface, long rxBytes, long rxPackets, long txBytes, long txPackets) { 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 com.android.internal.util.IndentingPrintWriter;
import libcore.util.EmptyArray;
import java.io.CharArrayWriter; import java.io.CharArrayWriter;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
@@ -458,6 +460,21 @@ public class NetworkStatsHistory implements Parcelable {
bucketCount++; 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. * 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;
import static android.net.ConnectivityManager.TYPE_WIFI_P2P; import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
import static android.net.ConnectivityManager.TYPE_WIMAX; 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_ALL;
import static android.net.NetworkStats.DEFAULT_NETWORK_NO; import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
import static android.net.NetworkStats.DEFAULT_NETWORK_YES; 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_NO;
import static android.net.NetworkStats.ROAMING_YES; import static android.net.NetworkStats.ROAMING_YES;
import static android.net.wifi.WifiInfo.removeDoubleQuotes; 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.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
@@ -55,8 +49,8 @@ import java.util.Arrays;
import java.util.Objects; import java.util.Objects;
/** /**
* Template definition used to generically match {@link NetworkIdentity}, * Predicate used to match {@link NetworkIdentity}, usually when collecting
* usually when collecting statistics. * statistics. (It should probably have been named {@code NetworkPredicate}.)
* *
* @hide * @hide
*/ */
@@ -68,13 +62,7 @@ public class NetworkTemplate implements Parcelable {
*/ */
private static final int BACKUP_VERSION = 1; private static final int BACKUP_VERSION = 1;
public static final int MATCH_MOBILE_ALL = 1; public static final int MATCH_MOBILE = 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_WIFI = 4; public static final int MATCH_WIFI = 4;
public static final int MATCH_ETHERNET = 5; public static final int MATCH_ETHERNET = 5;
public static final int MATCH_MOBILE_WILDCARD = 6; public static final int MATCH_MOBILE_WILDCARD = 6;
@@ -84,9 +72,7 @@ public class NetworkTemplate implements Parcelable {
private static boolean isKnownMatchRule(final int rule) { private static boolean isKnownMatchRule(final int rule) {
switch (rule) { switch (rule) {
case MATCH_MOBILE_ALL: case MATCH_MOBILE:
case MATCH_MOBILE_3G_LOWER:
case MATCH_MOBILE_4G:
case MATCH_WIFI: case MATCH_WIFI:
case MATCH_ETHERNET: case MATCH_ETHERNET:
case MATCH_MOBILE_WILDCARD: case MATCH_MOBILE_WILDCARD:
@@ -111,25 +97,7 @@ public class NetworkTemplate implements Parcelable {
* the given IMSI. * the given IMSI.
*/ */
public static NetworkTemplate buildTemplateMobileAll(String subscriberId) { public static NetworkTemplate buildTemplateMobileAll(String subscriberId) {
return new NetworkTemplate(MATCH_MOBILE_ALL, subscriberId, null); return new NetworkTemplate(MATCH_MOBILE, 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);
} }
/** /**
@@ -307,9 +275,7 @@ public class NetworkTemplate implements Parcelable {
public boolean isMatchRuleMobile() { public boolean isMatchRuleMobile() {
switch (mMatchRule) { switch (mMatchRule) {
case MATCH_MOBILE_3G_LOWER: case MATCH_MOBILE:
case MATCH_MOBILE_4G:
case MATCH_MOBILE_ALL:
case MATCH_MOBILE_WILDCARD: case MATCH_MOBILE_WILDCARD:
return true; return true;
default: default:
@@ -348,12 +314,8 @@ public class NetworkTemplate implements Parcelable {
if (!matchesDefaultNetwork(ident)) return false; if (!matchesDefaultNetwork(ident)) return false;
switch (mMatchRule) { switch (mMatchRule) {
case MATCH_MOBILE_ALL: case MATCH_MOBILE:
return matchesMobile(ident); return matchesMobile(ident);
case MATCH_MOBILE_3G_LOWER:
return matchesMobile3gLower(ident);
case MATCH_MOBILE_4G:
return matchesMobile4g(ident);
case MATCH_WIFI: case MATCH_WIFI:
return matchesWifi(ident); return matchesWifi(ident);
case MATCH_ETHERNET: 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. * Check if matches Wi-Fi network template.
*/ */
@@ -506,12 +431,8 @@ public class NetworkTemplate implements Parcelable {
private static String getMatchRuleName(int matchRule) { private static String getMatchRuleName(int matchRule) {
switch (matchRule) { switch (matchRule) {
case MATCH_MOBILE_3G_LOWER: case MATCH_MOBILE:
return "MOBILE_3G_LOWER"; return "MOBILE";
case MATCH_MOBILE_4G:
return "MOBILE_4G";
case MATCH_MOBILE_ALL:
return "MOBILE_ALL";
case MATCH_WIFI: case MATCH_WIFI:
return "WIFI"; return "WIFI";
case MATCH_ETHERNET: 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" * Examine the given template and normalize if it refers to a "merged"
* mobile subscriber. We pick the "lowest" merged subscriber as the primary * mobile subscriber. We pick the "lowest" merged subscriber as the primary

View File

@@ -106,6 +106,10 @@ public class NetworkStatsCollection implements FileRotator.Reader {
reset(); reset();
} }
public void clear() {
reset();
}
public void reset() { public void reset() {
mStats.clear(); mStats.clear();
mStartMillis = Long.MAX_VALUE; 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_GLOBAL_ALERT_BYTES;
import static android.provider.Settings.Global.NETSTATS_POLL_INTERVAL; 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_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_BUCKET_DURATION;
import static android.provider.Settings.Global.NETSTATS_UID_DELETE_AGE; import static android.provider.Settings.Global.NETSTATS_UID_DELETE_AGE;
import static android.provider.Settings.Global.NETSTATS_UID_PERSIST_BYTES; 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.NetworkStatsHistory;
import android.net.NetworkTemplate; import android.net.NetworkTemplate;
import android.net.TrafficStats; import android.net.TrafficStats;
import android.os.BestClock;
import android.os.Binder; import android.os.Binder;
import android.os.DropBoxManager; import android.os.DropBoxManager;
import android.os.Environment; import android.os.Environment;
import android.os.BestClock;
import android.os.Handler; import android.os.Handler;
import android.os.HandlerThread; import android.os.HandlerThread;
import android.os.IBinder; 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.FileRotator;
import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.IndentingPrintWriter;
import com.android.server.EventLogTags; import com.android.server.EventLogTags;
import com.android.server.LocalServices;
import com.android.server.connectivity.Tethering; import com.android.server.connectivity.Tethering;
import java.io.File; import java.io.File;
@@ -333,6 +333,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
mStatsObservers = checkNotNull(statsObservers, "missing NetworkStatsObservers"); mStatsObservers = checkNotNull(statsObservers, "missing NetworkStatsObservers");
mSystemDir = checkNotNull(systemDir, "missing systemDir"); mSystemDir = checkNotNull(systemDir, "missing systemDir");
mBaseDir = checkNotNull(baseDir, "missing baseDir"); mBaseDir = checkNotNull(baseDir, "missing baseDir");
LocalServices.addService(NetworkStatsManagerInternal.class,
new NetworkStatsManagerInternalImpl());
} }
@VisibleForTesting @VisibleForTesting
@@ -640,7 +643,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private SubscriptionPlan resolveSubscriptionPlan(NetworkTemplate template, int flags) { private SubscriptionPlan resolveSubscriptionPlan(NetworkTemplate template, int flags) {
SubscriptionPlan plan = null; SubscriptionPlan plan = null;
if ((flags & NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN) != 0 if ((flags & NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN) != 0
&& (template.getMatchRule() == NetworkTemplate.MATCH_MOBILE_ALL) && (template.getMatchRule() == NetworkTemplate.MATCH_MOBILE)
&& mSettings.getAugmentEnabled()) { && mSettings.getAugmentEnabled()) {
if (LOGD) Slog.d(TAG, "Resolving plan for " + template); if (LOGD) Slog.d(TAG, "Resolving plan for " + template);
final long token = Binder.clearCallingIdentity(); final long token = Binder.clearCallingIdentity();
@@ -701,12 +704,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
} }
} }
@Override private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) { assertSystemReady();
// 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);
assertBandwidthControlEnabled(); assertBandwidthControlEnabled();
// NOTE: if callers want to get non-augmented data, they should go // 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(); 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 @Override
public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException { public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException {
if (Binder.getCallingUid() != uid) { if (Binder.getCallingUid() != uid) {
@@ -777,10 +788,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
} }
} }
@Override @VisibleForTesting
public void setUidForeground(int uid, boolean uidForeground) { void setUidForeground(int uid, boolean uidForeground) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
synchronized (mStatsLock) { synchronized (mStatsLock) {
final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT; final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT;
final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT); final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT);
@@ -817,9 +826,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
} }
} }
@Override private void advisePersistThreshold(long thresholdBytes) {
public void advisePersistThreshold(long thresholdBytes) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
assertBandwidthControlEnabled(); assertBandwidthControlEnabled();
// clamp threshold into safe range // clamp threshold into safe range
@@ -1330,6 +1337,33 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
removeUidsLocked(uids); 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 @Override
protected void dump(FileDescriptor fd, PrintWriter rawWriter, String[] args) { protected void dump(FileDescriptor fd, PrintWriter rawWriter, String[] args) {
if (!DumpUtils.checkDumpPermission(mContext, TAG, rawWriter)) return; 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() { private void assertBandwidthControlEnabled() {
if (!isBandwidthControlEnabled()) { if (!isBandwidthControlEnabled()) {
throw new IllegalStateException("Bandwidth module disabled"); throw new IllegalStateException("Bandwidth module disabled");