Merge "Transition from DEV network stats to XT." into jb-dev
This commit is contained in:
@@ -111,6 +111,14 @@ public class NetworkStats implements Parcelable {
|
|||||||
&& operations == 0;
|
&& operations == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void add(Entry another) {
|
||||||
|
this.rxBytes += another.rxBytes;
|
||||||
|
this.rxPackets += another.rxPackets;
|
||||||
|
this.txBytes += another.txBytes;
|
||||||
|
this.txPackets += another.txPackets;
|
||||||
|
this.operations += another.operations;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
final StringBuilder builder = new StringBuilder();
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
|||||||
@@ -342,11 +342,23 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
* for combining together stats for external reporting.
|
* for combining together stats for external reporting.
|
||||||
*/
|
*/
|
||||||
public void recordEntireHistory(NetworkStatsHistory input) {
|
public void recordEntireHistory(NetworkStatsHistory input) {
|
||||||
|
recordHistory(input, Long.MIN_VALUE, Long.MAX_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record given {@link NetworkStatsHistory} into this history, copying only
|
||||||
|
* buckets that atomically occur in the inclusive time range. Doesn't
|
||||||
|
* interpolate across partial buckets.
|
||||||
|
*/
|
||||||
|
public void recordHistory(NetworkStatsHistory input, long start, long end) {
|
||||||
final NetworkStats.Entry entry = new NetworkStats.Entry(
|
final NetworkStats.Entry entry = new NetworkStats.Entry(
|
||||||
IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0L);
|
IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0L);
|
||||||
for (int i = 0; i < input.bucketCount; i++) {
|
for (int i = 0; i < input.bucketCount; i++) {
|
||||||
final long start = input.bucketStart[i];
|
final long bucketStart = input.bucketStart[i];
|
||||||
final long end = start + input.bucketDuration;
|
final long bucketEnd = bucketStart + input.bucketDuration;
|
||||||
|
|
||||||
|
// skip when bucket is outside requested range
|
||||||
|
if (bucketStart < start || bucketEnd > end) continue;
|
||||||
|
|
||||||
entry.rxBytes = getLong(input.rxBytes, i, 0L);
|
entry.rxBytes = getLong(input.rxBytes, i, 0L);
|
||||||
entry.rxPackets = getLong(input.rxPackets, i, 0L);
|
entry.rxPackets = getLong(input.rxPackets, i, 0L);
|
||||||
@@ -354,7 +366,7 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
entry.txPackets = getLong(input.txPackets, i, 0L);
|
entry.txPackets = getLong(input.txPackets, i, 0L);
|
||||||
entry.operations = getLong(input.operations, i, 0L);
|
entry.operations = getLong(input.operations, i, 0L);
|
||||||
|
|
||||||
recordData(start, end, entry);
|
recordData(bucketStart, bucketEnd, entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,13 @@ public class NetworkTemplate implements Parcelable {
|
|||||||
com.android.internal.R.array.config_data_usage_network_types);
|
com.android.internal.R.array.config_data_usage_network_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean sForceAllNetworkTypes = false;
|
||||||
|
|
||||||
|
// @VisibleForTesting
|
||||||
|
public static void forceAllNetworkTypes() {
|
||||||
|
sForceAllNetworkTypes = true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
|
* Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
|
||||||
* the given IMSI.
|
* the given IMSI.
|
||||||
@@ -225,7 +232,7 @@ public class NetworkTemplate implements Parcelable {
|
|||||||
// TODO: consider matching against WiMAX subscriber identity
|
// TODO: consider matching against WiMAX subscriber identity
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return (contains(DATA_USAGE_NETWORK_TYPES, ident.mType)
|
return ((sForceAllNetworkTypes || contains(DATA_USAGE_NETWORK_TYPES, ident.mType))
|
||||||
&& Objects.equal(mSubscriberId, ident.mSubscriberId));
|
&& Objects.equal(mSubscriberId, ident.mSubscriberId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -291,7 +298,7 @@ public class NetworkTemplate implements Parcelable {
|
|||||||
if (ident.mType == TYPE_WIMAX) {
|
if (ident.mType == TYPE_WIMAX) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return contains(DATA_USAGE_NETWORK_TYPES, ident.mType);
|
return sForceAllNetworkTypes || contains(DATA_USAGE_NETWORK_TYPES, ident.mType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public class NetworkStatsCollection implements FileRotator.Reader {
|
|||||||
|
|
||||||
private HashMap<Key, NetworkStatsHistory> mStats = Maps.newHashMap();
|
private HashMap<Key, NetworkStatsHistory> mStats = Maps.newHashMap();
|
||||||
|
|
||||||
private long mBucketDuration;
|
private final long mBucketDuration;
|
||||||
|
|
||||||
private long mStartMillis;
|
private long mStartMillis;
|
||||||
private long mEndMillis;
|
private long mEndMillis;
|
||||||
@@ -95,6 +95,18 @@ public class NetworkStatsCollection implements FileRotator.Reader {
|
|||||||
return mStartMillis;
|
return mStartMillis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return first atomic bucket in this collection, which is more conservative
|
||||||
|
* than {@link #mStartMillis}.
|
||||||
|
*/
|
||||||
|
public long getFirstAtomicBucketMillis() {
|
||||||
|
if (mStartMillis == Long.MAX_VALUE) {
|
||||||
|
return Long.MAX_VALUE;
|
||||||
|
} else {
|
||||||
|
return mStartMillis + mBucketDuration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public long getEndMillis() {
|
public long getEndMillis() {
|
||||||
return mEndMillis;
|
return mEndMillis;
|
||||||
}
|
}
|
||||||
@@ -121,6 +133,15 @@ public class NetworkStatsCollection implements FileRotator.Reader {
|
|||||||
*/
|
*/
|
||||||
public NetworkStatsHistory getHistory(
|
public NetworkStatsHistory getHistory(
|
||||||
NetworkTemplate template, int uid, int set, int tag, int fields) {
|
NetworkTemplate template, int uid, int set, int tag, int fields) {
|
||||||
|
return getHistory(template, uid, set, tag, fields, Long.MIN_VALUE, Long.MAX_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Combine all {@link NetworkStatsHistory} in this collection which match
|
||||||
|
* the requested parameters.
|
||||||
|
*/
|
||||||
|
public NetworkStatsHistory getHistory(
|
||||||
|
NetworkTemplate template, int uid, int set, int tag, int fields, long start, long end) {
|
||||||
final NetworkStatsHistory combined = new NetworkStatsHistory(
|
final NetworkStatsHistory combined = new NetworkStatsHistory(
|
||||||
mBucketDuration, estimateBuckets(), fields);
|
mBucketDuration, estimateBuckets(), fields);
|
||||||
for (Map.Entry<Key, NetworkStatsHistory> entry : mStats.entrySet()) {
|
for (Map.Entry<Key, NetworkStatsHistory> entry : mStats.entrySet()) {
|
||||||
@@ -128,7 +149,7 @@ public class NetworkStatsCollection implements FileRotator.Reader {
|
|||||||
final boolean setMatches = set == SET_ALL || key.set == set;
|
final boolean setMatches = set == SET_ALL || key.set == set;
|
||||||
if (key.uid == uid && setMatches && key.tag == tag
|
if (key.uid == uid && setMatches && key.tag == tag
|
||||||
&& templateMatches(template, key.ident)) {
|
&& templateMatches(template, key.ident)) {
|
||||||
combined.recordEntireHistory(entry.getValue());
|
combined.recordHistory(entry.getValue(), start, end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return combined;
|
return combined;
|
||||||
@@ -145,6 +166,9 @@ public class NetworkStatsCollection implements FileRotator.Reader {
|
|||||||
final NetworkStats.Entry entry = new NetworkStats.Entry();
|
final NetworkStats.Entry entry = new NetworkStats.Entry();
|
||||||
NetworkStatsHistory.Entry historyEntry = null;
|
NetworkStatsHistory.Entry historyEntry = null;
|
||||||
|
|
||||||
|
// shortcut when we know stats will be empty
|
||||||
|
if (start == end) return stats;
|
||||||
|
|
||||||
for (Map.Entry<Key, NetworkStatsHistory> mapEntry : mStats.entrySet()) {
|
for (Map.Entry<Key, NetworkStatsHistory> mapEntry : mStats.entrySet()) {
|
||||||
final Key key = mapEntry.getKey();
|
final Key key = mapEntry.getKey();
|
||||||
if (templateMatches(template, key.ident)) {
|
if (templateMatches(template, key.ident)) {
|
||||||
@@ -175,8 +199,9 @@ public class NetworkStatsCollection implements FileRotator.Reader {
|
|||||||
*/
|
*/
|
||||||
public void recordData(NetworkIdentitySet ident, int uid, int set, int tag, long start,
|
public void recordData(NetworkIdentitySet ident, int uid, int set, int tag, long start,
|
||||||
long end, NetworkStats.Entry entry) {
|
long end, NetworkStats.Entry entry) {
|
||||||
noteRecordedHistory(start, end, entry.rxBytes + entry.txBytes);
|
final NetworkStatsHistory history = findOrCreateHistory(ident, uid, set, tag);
|
||||||
findOrCreateHistory(ident, uid, set, tag).recordData(start, end, entry);
|
history.recordData(start, end, entry);
|
||||||
|
noteRecordedHistory(history.getStart(), history.getEnd(), entry.rxBytes + entry.txBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import static android.provider.Settings.Secure.NETSTATS_DEV_PERSIST_BYTES;
|
|||||||
import static android.provider.Settings.Secure.NETSTATS_DEV_ROTATE_AGE;
|
import static android.provider.Settings.Secure.NETSTATS_DEV_ROTATE_AGE;
|
||||||
import static android.provider.Settings.Secure.NETSTATS_GLOBAL_ALERT_BYTES;
|
import static android.provider.Settings.Secure.NETSTATS_GLOBAL_ALERT_BYTES;
|
||||||
import static android.provider.Settings.Secure.NETSTATS_POLL_INTERVAL;
|
import static android.provider.Settings.Secure.NETSTATS_POLL_INTERVAL;
|
||||||
|
import static android.provider.Settings.Secure.NETSTATS_REPORT_XT_OVER_DEV;
|
||||||
import static android.provider.Settings.Secure.NETSTATS_SAMPLE_ENABLED;
|
import static android.provider.Settings.Secure.NETSTATS_SAMPLE_ENABLED;
|
||||||
import static android.provider.Settings.Secure.NETSTATS_TIME_CACHE_MAX_AGE;
|
import static android.provider.Settings.Secure.NETSTATS_TIME_CACHE_MAX_AGE;
|
||||||
import static android.provider.Settings.Secure.NETSTATS_UID_BUCKET_DURATION;
|
import static android.provider.Settings.Secure.NETSTATS_UID_BUCKET_DURATION;
|
||||||
@@ -177,6 +178,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
public long getPollInterval();
|
public long getPollInterval();
|
||||||
public long getTimeCacheMaxAge();
|
public long getTimeCacheMaxAge();
|
||||||
public boolean getSampleEnabled();
|
public boolean getSampleEnabled();
|
||||||
|
public boolean getReportXtOverDev();
|
||||||
|
|
||||||
public static class Config {
|
public static class Config {
|
||||||
public final long bucketDuration;
|
public final long bucketDuration;
|
||||||
@@ -221,6 +223,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
|
|
||||||
/** Cached {@link #mDevRecorder} stats. */
|
/** Cached {@link #mDevRecorder} stats. */
|
||||||
private NetworkStatsCollection mDevStatsCached;
|
private NetworkStatsCollection mDevStatsCached;
|
||||||
|
/** Cached {@link #mXtRecorder} stats. */
|
||||||
|
private NetworkStatsCollection mXtStatsCached;
|
||||||
|
|
||||||
/** Current counter sets for each UID. */
|
/** Current counter sets for each UID. */
|
||||||
private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
|
private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
|
||||||
@@ -295,6 +299,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
// read historical network stats from disk, since policy service
|
// read historical network stats from disk, since policy service
|
||||||
// might need them right away.
|
// might need them right away.
|
||||||
mDevStatsCached = mDevRecorder.getOrLoadCompleteLocked();
|
mDevStatsCached = mDevRecorder.getOrLoadCompleteLocked();
|
||||||
|
mXtStatsCached = mXtRecorder.getOrLoadCompleteLocked();
|
||||||
|
|
||||||
// bootstrap initial stats to prevent double-counting later
|
// bootstrap initial stats to prevent double-counting later
|
||||||
bootstrapStatsLocked();
|
bootstrapStatsLocked();
|
||||||
@@ -371,6 +376,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
mUidTagRecorder = null;
|
mUidTagRecorder = null;
|
||||||
|
|
||||||
mDevStatsCached = null;
|
mDevStatsCached = null;
|
||||||
|
mXtStatsCached = null;
|
||||||
|
|
||||||
mSystemReady = false;
|
mSystemReady = false;
|
||||||
}
|
}
|
||||||
@@ -469,12 +475,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
@Override
|
@Override
|
||||||
public NetworkStats getSummaryForNetwork(
|
public NetworkStats getSummaryForNetwork(
|
||||||
NetworkTemplate template, long start, long end) {
|
NetworkTemplate template, long start, long end) {
|
||||||
return mDevStatsCached.getSummary(template, start, end);
|
return internalGetSummaryForNetwork(template, start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
|
public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
|
||||||
return mDevStatsCached.getHistory(template, UID_ALL, SET_ALL, TAG_NONE, fields);
|
return internalGetHistoryForNetwork(template, fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -507,11 +513,56 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return network summary, splicing between {@link #mDevStatsCached}
|
||||||
|
* and {@link #mXtStatsCached} when appropriate.
|
||||||
|
*/
|
||||||
|
private NetworkStats internalGetSummaryForNetwork(
|
||||||
|
NetworkTemplate template, long start, long end) {
|
||||||
|
if (!mSettings.getReportXtOverDev()) {
|
||||||
|
// shortcut when XT reporting disabled
|
||||||
|
return mDevStatsCached.getSummary(template, start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
// splice stats between DEV and XT, switching over from DEV to XT at
|
||||||
|
// first atomic bucket.
|
||||||
|
final long firstAtomicBucket = mXtStatsCached.getFirstAtomicBucketMillis();
|
||||||
|
final NetworkStats dev = mDevStatsCached.getSummary(
|
||||||
|
template, Math.min(start, firstAtomicBucket), Math.min(end, firstAtomicBucket));
|
||||||
|
final NetworkStats xt = mXtStatsCached.getSummary(
|
||||||
|
template, Math.max(start, firstAtomicBucket), Math.max(end, firstAtomicBucket));
|
||||||
|
|
||||||
|
xt.combineAllValues(dev);
|
||||||
|
return xt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return network history, splicing between {@link #mDevStatsCached}
|
||||||
|
* and {@link #mXtStatsCached} when appropriate.
|
||||||
|
*/
|
||||||
|
private NetworkStatsHistory internalGetHistoryForNetwork(NetworkTemplate template, int fields) {
|
||||||
|
if (!mSettings.getReportXtOverDev()) {
|
||||||
|
// shortcut when XT reporting disabled
|
||||||
|
return mDevStatsCached.getHistory(template, UID_ALL, SET_ALL, TAG_NONE, fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
// splice stats between DEV and XT, switching over from DEV to XT at
|
||||||
|
// first atomic bucket.
|
||||||
|
final long firstAtomicBucket = mXtStatsCached.getFirstAtomicBucketMillis();
|
||||||
|
final NetworkStatsHistory dev = mDevStatsCached.getHistory(
|
||||||
|
template, UID_ALL, SET_ALL, TAG_NONE, fields, Long.MIN_VALUE, firstAtomicBucket);
|
||||||
|
final NetworkStatsHistory xt = mXtStatsCached.getHistory(
|
||||||
|
template, UID_ALL, SET_ALL, TAG_NONE, fields, firstAtomicBucket, Long.MAX_VALUE);
|
||||||
|
|
||||||
|
xt.recordEntireHistory(dev);
|
||||||
|
return xt;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
|
public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
|
||||||
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
|
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
|
||||||
assertBandwidthControlEnabled();
|
assertBandwidthControlEnabled();
|
||||||
return mDevStatsCached.getSummary(template, start, end).getTotalBytes();
|
return internalGetSummaryForNetwork(template, start, end).getTotalBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1190,6 +1241,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
return getSecureBoolean(NETSTATS_SAMPLE_ENABLED, true);
|
return getSecureBoolean(NETSTATS_SAMPLE_ENABLED, true);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
public boolean getReportXtOverDev() {
|
||||||
|
return getSecureBoolean(NETSTATS_REPORT_XT_OVER_DEV, true);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
public Config getDevConfig() {
|
public Config getDevConfig() {
|
||||||
return new Config(getSecureLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
|
return new Config(getSecureLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
|
||||||
getSecureLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
|
getSecureLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
|
||||||
|
|||||||
Reference in New Issue
Block a user