Merge commit '98e12851336b7db16e583f9afac63ecc97465980' from
oc-mr1-dev-plus-aosp-without-vendor into stage-aosp-master. Change-Id: Ia7b8da4a00d215160e4a4fa40f6044208d1297b7 Merged-In: I19846d2a3ee27aecbae2367a74ee49082eea154d
This commit is contained in:
@@ -97,12 +97,12 @@ public final class NetworkStats implements AutoCloseable {
|
|||||||
private NetworkStatsHistory.Entry mRecycledHistoryEntry = null;
|
private NetworkStatsHistory.Entry mRecycledHistoryEntry = null;
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
NetworkStats(Context context, NetworkTemplate template, long startTimestamp,
|
NetworkStats(Context context, NetworkTemplate template, int flags, long startTimestamp,
|
||||||
long endTimestamp) throws RemoteException, SecurityException {
|
long endTimestamp) throws RemoteException, SecurityException {
|
||||||
final INetworkStatsService statsService = INetworkStatsService.Stub.asInterface(
|
final INetworkStatsService statsService = INetworkStatsService.Stub.asInterface(
|
||||||
ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
|
ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
|
||||||
// Open network stats session
|
// Open network stats session
|
||||||
mSession = statsService.openSessionForUsageStats(context.getOpPackageName());
|
mSession = statsService.openSessionForUsageStats(flags, context.getOpPackageName());
|
||||||
mCloseGuard.open("close");
|
mCloseGuard.open("close");
|
||||||
mTemplate = template;
|
mTemplate = template;
|
||||||
mStartTimeStamp = startTimestamp;
|
mStartTimeStamp = startTimestamp;
|
||||||
|
|||||||
@@ -24,15 +24,14 @@ import android.app.usage.NetworkStats.Bucket;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.DataUsageRequest;
|
import android.net.DataUsageRequest;
|
||||||
|
import android.net.INetworkStatsService;
|
||||||
import android.net.NetworkIdentity;
|
import android.net.NetworkIdentity;
|
||||||
import android.net.NetworkTemplate;
|
import android.net.NetworkTemplate;
|
||||||
import android.net.INetworkStatsService;
|
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Message;
|
|
||||||
import android.os.Messenger;
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.os.Messenger;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
import android.os.ServiceManager.ServiceNotFoundException;
|
import android.os.ServiceManager.ServiceNotFoundException;
|
||||||
@@ -79,7 +78,7 @@ import android.util.Log;
|
|||||||
* In addition to tethering usage, usage by removed users and apps, and usage by the system
|
* In addition to tethering usage, usage by removed users and apps, and usage by the system
|
||||||
* is also included in the results for callers with one of these higher levels of access.
|
* is also included in the results for callers with one of these higher levels of access.
|
||||||
* <p />
|
* <p />
|
||||||
* <b>NOTE:</b> Prior to API level {@value Build.VERSION_CODES#N}, all calls to these APIs required
|
* <b>NOTE:</b> Prior to API level {@value android.os.Build.VERSION_CODES#N}, all calls to these APIs required
|
||||||
* the above permission, even to access an app's own data usage, and carrier-privileged apps were
|
* the above permission, even to access an app's own data usage, and carrier-privileged apps were
|
||||||
* not included.
|
* not included.
|
||||||
*/
|
*/
|
||||||
@@ -96,6 +95,13 @@ public class NetworkStatsManager {
|
|||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final INetworkStatsService mService;
|
private final INetworkStatsService mService;
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
public static final int FLAG_POLL_ON_OPEN = 1 << 0;
|
||||||
|
/** @hide */
|
||||||
|
public static final int FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN = 1 << 1;
|
||||||
|
|
||||||
|
private int mFlags;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@hide}
|
* {@hide}
|
||||||
*/
|
*/
|
||||||
@@ -103,6 +109,25 @@ public class NetworkStatsManager {
|
|||||||
mContext = context;
|
mContext = context;
|
||||||
mService = INetworkStatsService.Stub.asInterface(
|
mService = INetworkStatsService.Stub.asInterface(
|
||||||
ServiceManager.getServiceOrThrow(Context.NETWORK_STATS_SERVICE));
|
ServiceManager.getServiceOrThrow(Context.NETWORK_STATS_SERVICE));
|
||||||
|
setPollOnOpen(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
public void setPollOnOpen(boolean pollOnOpen) {
|
||||||
|
if (pollOnOpen) {
|
||||||
|
mFlags |= FLAG_POLL_ON_OPEN;
|
||||||
|
} else {
|
||||||
|
mFlags &= ~FLAG_POLL_ON_OPEN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
public void setAugmentWithSubscriptionPlan(boolean augmentWithSubscriptionPlan) {
|
||||||
|
if (augmentWithSubscriptionPlan) {
|
||||||
|
mFlags |= FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN;
|
||||||
|
} else {
|
||||||
|
mFlags &= ~FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -136,7 +161,7 @@ public class NetworkStatsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Bucket bucket = null;
|
Bucket bucket = null;
|
||||||
NetworkStats stats = new NetworkStats(mContext, template, startTime, endTime);
|
NetworkStats stats = new NetworkStats(mContext, template, mFlags, startTime, endTime);
|
||||||
bucket = stats.getDeviceSummaryForNetwork();
|
bucket = stats.getDeviceSummaryForNetwork();
|
||||||
|
|
||||||
stats.close();
|
stats.close();
|
||||||
@@ -174,7 +199,7 @@ public class NetworkStatsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NetworkStats stats;
|
NetworkStats stats;
|
||||||
stats = new NetworkStats(mContext, template, startTime, endTime);
|
stats = new NetworkStats(mContext, template, mFlags, startTime, endTime);
|
||||||
stats.startSummaryEnumeration();
|
stats.startSummaryEnumeration();
|
||||||
|
|
||||||
stats.close();
|
stats.close();
|
||||||
@@ -211,7 +236,7 @@ public class NetworkStatsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NetworkStats result;
|
NetworkStats result;
|
||||||
result = new NetworkStats(mContext, template, startTime, endTime);
|
result = new NetworkStats(mContext, template, mFlags, startTime, endTime);
|
||||||
result.startSummaryEnumeration();
|
result.startSummaryEnumeration();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -260,7 +285,7 @@ public class NetworkStatsManager {
|
|||||||
|
|
||||||
NetworkStats result;
|
NetworkStats result;
|
||||||
try {
|
try {
|
||||||
result = new NetworkStats(mContext, template, startTime, endTime);
|
result = new NetworkStats(mContext, template, mFlags, startTime, endTime);
|
||||||
result.startHistoryEnumeration(uid, tag);
|
result.startHistoryEnumeration(uid, tag);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "Error while querying stats for uid=" + uid + " tag=" + tag, e);
|
Log.e(TAG, "Error while querying stats for uid=" + uid + " tag=" + tag, e);
|
||||||
@@ -305,7 +330,7 @@ public class NetworkStatsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NetworkStats result;
|
NetworkStats result;
|
||||||
result = new NetworkStats(mContext, template, startTime, endTime);
|
result = new NetworkStats(mContext, template, mFlags, startTime, endTime);
|
||||||
result.startUserUidEnumeration();
|
result.startUserUidEnumeration();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ interface INetworkStatsService {
|
|||||||
* PACKAGE_USAGE_STATS permission is always checked. If PACKAGE_USAGE_STATS is not granted
|
* PACKAGE_USAGE_STATS permission is always checked. If PACKAGE_USAGE_STATS is not granted
|
||||||
* READ_NETWORK_USAGE_STATS is checked for.
|
* READ_NETWORK_USAGE_STATS is checked for.
|
||||||
*/
|
*/
|
||||||
INetworkStatsSession openSessionForUsageStats(String callingPackage);
|
INetworkStatsSession openSessionForUsageStats(int flags, String callingPackage);
|
||||||
|
|
||||||
/** Return network layer usage total for traffic that matches template. */
|
/** Return network layer usage total for traffic that matches template. */
|
||||||
long getNetworkTotalBytes(in NetworkTemplate template, long start, long end);
|
long getNetworkTotalBytes(in NetworkTemplate template, long start, long end);
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> {
|
|||||||
* Scrub given IMSI on production builds.
|
* Scrub given IMSI on production builds.
|
||||||
*/
|
*/
|
||||||
public static String scrubSubscriberId(String subscriberId) {
|
public static String scrubSubscriberId(String subscriberId) {
|
||||||
if ("eng".equals(Build.TYPE)) {
|
if (Build.IS_ENG) {
|
||||||
return subscriberId;
|
return subscriberId;
|
||||||
} else if (subscriberId != null) {
|
} else if (subscriberId != null) {
|
||||||
// TODO: parse this as MCC+MNC instead of hard-coding
|
// TODO: parse this as MCC+MNC instead of hard-coding
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import static android.net.NetworkStatsHistory.Entry.UNKNOWN;
|
|||||||
import static android.net.NetworkStatsHistory.ParcelUtils.readLongArray;
|
import static android.net.NetworkStatsHistory.ParcelUtils.readLongArray;
|
||||||
import static android.net.NetworkStatsHistory.ParcelUtils.writeLongArray;
|
import static android.net.NetworkStatsHistory.ParcelUtils.writeLongArray;
|
||||||
import static android.text.format.DateUtils.SECOND_IN_MILLIS;
|
import static android.text.format.DateUtils.SECOND_IN_MILLIS;
|
||||||
|
|
||||||
import static com.android.internal.util.ArrayUtils.total;
|
import static com.android.internal.util.ArrayUtils.total;
|
||||||
|
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
@@ -282,6 +283,24 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setValues(int i, Entry entry) {
|
||||||
|
// Unwind old values
|
||||||
|
if (rxBytes != null) totalBytes -= rxBytes[i];
|
||||||
|
if (txBytes != null) totalBytes -= txBytes[i];
|
||||||
|
|
||||||
|
bucketStart[i] = entry.bucketStart;
|
||||||
|
setLong(activeTime, i, entry.activeTime);
|
||||||
|
setLong(rxBytes, i, entry.rxBytes);
|
||||||
|
setLong(rxPackets, i, entry.rxPackets);
|
||||||
|
setLong(txBytes, i, entry.txBytes);
|
||||||
|
setLong(txPackets, i, entry.txPackets);
|
||||||
|
setLong(operations, i, entry.operations);
|
||||||
|
|
||||||
|
// Apply new values
|
||||||
|
if (rxBytes != null) totalBytes += rxBytes[i];
|
||||||
|
if (txBytes != null) totalBytes += txBytes[i];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Record that data traffic occurred in the given time range. Will
|
* Record that data traffic occurred in the given time range. Will
|
||||||
* distribute across internal buckets, creating new buckets as needed.
|
* distribute across internal buckets, creating new buckets as needed.
|
||||||
|
|||||||
@@ -326,6 +326,10 @@ public class NetworkTemplate implements Parcelable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean matchesSubscriberId(String subscriberId) {
|
||||||
|
return ArrayUtils.contains(mMatchSubscriberIds, subscriberId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if mobile network with matching IMSI.
|
* Check if mobile network with matching IMSI.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -109,25 +109,26 @@ public class TrafficStats {
|
|||||||
*/
|
*/
|
||||||
public static final int TAG_SYSTEM_RESTORE = 0xFFFFFF04;
|
public static final int TAG_SYSTEM_RESTORE = 0xFFFFFF04;
|
||||||
|
|
||||||
/** @hide */
|
|
||||||
public static final int TAG_SYSTEM_DHCP = 0xFFFFFF05;
|
|
||||||
/** @hide */
|
|
||||||
public static final int TAG_SYSTEM_NTP = 0xFFFFFF06;
|
|
||||||
/** @hide */
|
|
||||||
public static final int TAG_SYSTEM_PROBE = 0xFFFFFF07;
|
|
||||||
/** @hide */
|
|
||||||
public static final int TAG_SYSTEM_NEIGHBOR = 0xFFFFFF08;
|
|
||||||
/** @hide */
|
|
||||||
public static final int TAG_SYSTEM_GPS = 0xFFFFFF09;
|
|
||||||
/** @hide */
|
|
||||||
public static final int TAG_SYSTEM_PAC = 0xFFFFFF0A;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sockets that are strictly local on device; never hits network.
|
* Default tag value for code (typically APKs) downloaded by an app store on
|
||||||
|
* behalf of the app, such as updates.
|
||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final int TAG_SYSTEM_LOCAL = 0xFFFFFFAA;
|
public static final int TAG_SYSTEM_APP = 0xFFFFFF05;
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
public static final int TAG_SYSTEM_DHCP = 0xFFFFFF40;
|
||||||
|
/** @hide */
|
||||||
|
public static final int TAG_SYSTEM_NTP = 0xFFFFFF41;
|
||||||
|
/** @hide */
|
||||||
|
public static final int TAG_SYSTEM_PROBE = 0xFFFFFF42;
|
||||||
|
/** @hide */
|
||||||
|
public static final int TAG_SYSTEM_NEIGHBOR = 0xFFFFFF43;
|
||||||
|
/** @hide */
|
||||||
|
public static final int TAG_SYSTEM_GPS = 0xFFFFFF44;
|
||||||
|
/** @hide */
|
||||||
|
public static final int TAG_SYSTEM_PAC = 0xFFFFFF45;
|
||||||
|
|
||||||
private static INetworkStatsService sStatsService;
|
private static INetworkStatsService sStatsService;
|
||||||
|
|
||||||
@@ -209,6 +210,19 @@ public class TrafficStats {
|
|||||||
setThreadStatsTag(TAG_SYSTEM_RESTORE);
|
setThreadStatsTag(TAG_SYSTEM_RESTORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set active tag to use when accounting {@link Socket} traffic originating
|
||||||
|
* from the current thread. The tag used internally is well-defined to
|
||||||
|
* distinguish all code (typically APKs) downloaded by an app store on
|
||||||
|
* behalf of the app, such as updates.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@SystemApi
|
||||||
|
public static void setThreadStatsTagApp() {
|
||||||
|
setThreadStatsTag(TAG_SYSTEM_APP);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the active tag used when accounting {@link Socket} traffic originating
|
* Get the active tag used when accounting {@link Socket} traffic originating
|
||||||
* from the current thread. Only one active tag per thread is supported.
|
* from the current thread. Only one active tag per thread is supported.
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ import static android.net.NetworkStats.UID_ALL;
|
|||||||
import static android.net.TrafficStats.UID_REMOVED;
|
import static android.net.TrafficStats.UID_REMOVED;
|
||||||
import static android.text.format.DateUtils.WEEK_IN_MILLIS;
|
import static android.text.format.DateUtils.WEEK_IN_MILLIS;
|
||||||
|
|
||||||
|
import static com.android.server.net.NetworkStatsService.TAG;
|
||||||
|
|
||||||
import android.net.NetworkIdentity;
|
import android.net.NetworkIdentity;
|
||||||
import android.net.NetworkStats;
|
import android.net.NetworkStats;
|
||||||
import android.net.NetworkStatsHistory;
|
import android.net.NetworkStatsHistory;
|
||||||
@@ -37,20 +39,24 @@ import android.os.Binder;
|
|||||||
import android.service.NetworkStatsCollectionKeyProto;
|
import android.service.NetworkStatsCollectionKeyProto;
|
||||||
import android.service.NetworkStatsCollectionProto;
|
import android.service.NetworkStatsCollectionProto;
|
||||||
import android.service.NetworkStatsCollectionStatsProto;
|
import android.service.NetworkStatsCollectionStatsProto;
|
||||||
|
import android.telephony.SubscriptionPlan;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.AtomicFile;
|
import android.util.AtomicFile;
|
||||||
import android.util.IntArray;
|
import android.util.IntArray;
|
||||||
|
import android.util.Pair;
|
||||||
|
import android.util.Slog;
|
||||||
import android.util.proto.ProtoOutputStream;
|
import android.util.proto.ProtoOutputStream;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.util.ArrayUtils;
|
import com.android.internal.util.ArrayUtils;
|
||||||
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 libcore.io.IoUtils;
|
||||||
|
|
||||||
import com.google.android.collect.Lists;
|
import com.google.android.collect.Lists;
|
||||||
import com.google.android.collect.Maps;
|
import com.google.android.collect.Maps;
|
||||||
|
|
||||||
import libcore.io.IoUtils;
|
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
@@ -60,9 +66,11 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.net.ProtocolException;
|
import java.net.ProtocolException;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -140,6 +148,63 @@ public class NetworkStatsCollection implements FileRotator.Reader {
|
|||||||
return mStartMillis == Long.MAX_VALUE && mEndMillis == Long.MIN_VALUE;
|
return mStartMillis == Long.MAX_VALUE && mEndMillis == Long.MIN_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public long roundUp(long time) {
|
||||||
|
if (time == Long.MIN_VALUE || time == Long.MAX_VALUE
|
||||||
|
|| time == SubscriptionPlan.TIME_UNKNOWN) {
|
||||||
|
return time;
|
||||||
|
} else {
|
||||||
|
final long mod = time % mBucketDuration;
|
||||||
|
if (mod > 0) {
|
||||||
|
time -= mod;
|
||||||
|
time += mBucketDuration;
|
||||||
|
}
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public long roundDown(long time) {
|
||||||
|
if (time == Long.MIN_VALUE || time == Long.MAX_VALUE
|
||||||
|
|| time == SubscriptionPlan.TIME_UNKNOWN) {
|
||||||
|
return time;
|
||||||
|
} else {
|
||||||
|
final long mod = time % mBucketDuration;
|
||||||
|
if (mod > 0) {
|
||||||
|
time -= mod;
|
||||||
|
}
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Safely multiple a value by a rational.
|
||||||
|
* <p>
|
||||||
|
* Internally it uses integer-based math whenever possible, but switches
|
||||||
|
* over to double-based math if values would overflow.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
public static long multiplySafe(long value, long num, long den) {
|
||||||
|
long x = value;
|
||||||
|
long y = num;
|
||||||
|
|
||||||
|
// Logic shamelessly borrowed from Math.multiplyExact()
|
||||||
|
long r = x * y;
|
||||||
|
long ax = Math.abs(x);
|
||||||
|
long ay = Math.abs(y);
|
||||||
|
if (((ax | ay) >>> 31 != 0)) {
|
||||||
|
// Some bits greater than 2^31 that might cause overflow
|
||||||
|
// Check the result using the divide operator
|
||||||
|
// and check for the special case of Long.MIN_VALUE * -1
|
||||||
|
if (((y != 0) && (r / y != x)) ||
|
||||||
|
(x == Long.MIN_VALUE && y == -1)) {
|
||||||
|
// Use double math to avoid overflowing
|
||||||
|
return (long) (((double) num / den) * value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r / den;
|
||||||
|
}
|
||||||
|
|
||||||
public int[] getRelevantUids(@NetworkStatsAccess.Level int accessLevel) {
|
public int[] getRelevantUids(@NetworkStatsAccess.Level int accessLevel) {
|
||||||
return getRelevantUids(accessLevel, Binder.getCallingUid());
|
return getRelevantUids(accessLevel, Binder.getCallingUid());
|
||||||
}
|
}
|
||||||
@@ -165,60 +230,110 @@ public class NetworkStatsCollection implements FileRotator.Reader {
|
|||||||
* Combine all {@link NetworkStatsHistory} in this collection which match
|
* Combine all {@link NetworkStatsHistory} in this collection which match
|
||||||
* the requested parameters.
|
* the requested parameters.
|
||||||
*/
|
*/
|
||||||
public NetworkStatsHistory getHistory(
|
public NetworkStatsHistory getHistory(NetworkTemplate template, SubscriptionPlan augmentPlan,
|
||||||
NetworkTemplate template, int uid, int set, int tag, int fields,
|
int uid, int set, int tag, int fields, long start, long end,
|
||||||
@NetworkStatsAccess.Level int accessLevel) {
|
|
||||||
return getHistory(template, uid, set, tag, fields, Long.MIN_VALUE, Long.MAX_VALUE,
|
|
||||||
accessLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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,
|
|
||||||
@NetworkStatsAccess.Level int accessLevel) {
|
|
||||||
return getHistory(template, uid, set, tag, fields, start, end, accessLevel,
|
|
||||||
Binder.getCallingUid());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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,
|
|
||||||
@NetworkStatsAccess.Level int accessLevel, int callerUid) {
|
@NetworkStatsAccess.Level int accessLevel, int callerUid) {
|
||||||
if (!NetworkStatsAccess.isAccessibleToUser(uid, callerUid, accessLevel)) {
|
if (!NetworkStatsAccess.isAccessibleToUser(uid, callerUid, accessLevel)) {
|
||||||
throw new SecurityException("Network stats history of uid " + uid
|
throw new SecurityException("Network stats history of uid " + uid
|
||||||
+ " is forbidden for caller " + callerUid);
|
+ " is forbidden for caller " + callerUid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final int bucketEstimate = (int) ((end - start) / mBucketDuration);
|
||||||
final NetworkStatsHistory combined = new NetworkStatsHistory(
|
final NetworkStatsHistory combined = new NetworkStatsHistory(
|
||||||
mBucketDuration, start == end ? 1 : estimateBuckets(), fields);
|
mBucketDuration, bucketEstimate, fields);
|
||||||
|
|
||||||
// shortcut when we know stats will be empty
|
// shortcut when we know stats will be empty
|
||||||
if (start == end) return combined;
|
if (start == end) return combined;
|
||||||
|
|
||||||
|
// Figure out the window of time that we should be augmenting (if any)
|
||||||
|
long augmentStart = SubscriptionPlan.TIME_UNKNOWN;
|
||||||
|
long augmentEnd = (augmentPlan != null) ? augmentPlan.getDataUsageTime()
|
||||||
|
: SubscriptionPlan.TIME_UNKNOWN;
|
||||||
|
// And if augmenting, we might need to collect more data to adjust with
|
||||||
|
long collectStart = start;
|
||||||
|
long collectEnd = end;
|
||||||
|
|
||||||
|
if (augmentEnd != SubscriptionPlan.TIME_UNKNOWN) {
|
||||||
|
final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = augmentPlan.cycleIterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
final Pair<ZonedDateTime, ZonedDateTime> cycle = it.next();
|
||||||
|
final long cycleStart = cycle.first.toInstant().toEpochMilli();
|
||||||
|
final long cycleEnd = cycle.second.toInstant().toEpochMilli();
|
||||||
|
if (cycleStart <= augmentEnd && augmentEnd < cycleEnd) {
|
||||||
|
augmentStart = cycleStart;
|
||||||
|
collectStart = Long.min(collectStart, augmentStart);
|
||||||
|
collectEnd = Long.max(collectEnd, augmentEnd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (augmentStart != SubscriptionPlan.TIME_UNKNOWN) {
|
||||||
|
// Shrink augmentation window so we don't risk undercounting.
|
||||||
|
augmentStart = roundUp(augmentStart);
|
||||||
|
augmentEnd = roundDown(augmentEnd);
|
||||||
|
// Grow collection window so we get all the stats needed.
|
||||||
|
collectStart = roundDown(collectStart);
|
||||||
|
collectEnd = roundUp(collectEnd);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < mStats.size(); i++) {
|
for (int i = 0; i < mStats.size(); i++) {
|
||||||
final Key key = mStats.keyAt(i);
|
final Key key = mStats.keyAt(i);
|
||||||
if (key.uid == uid && NetworkStats.setMatches(set, key.set) && key.tag == tag
|
if (key.uid == uid && NetworkStats.setMatches(set, key.set) && key.tag == tag
|
||||||
&& templateMatches(template, key.ident)) {
|
&& templateMatches(template, key.ident)) {
|
||||||
final NetworkStatsHistory value = mStats.valueAt(i);
|
final NetworkStatsHistory value = mStats.valueAt(i);
|
||||||
combined.recordHistory(value, start, end);
|
combined.recordHistory(value, collectStart, collectEnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return combined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
if (augmentStart != SubscriptionPlan.TIME_UNKNOWN) {
|
||||||
* Summarize all {@link NetworkStatsHistory} in this collection which match
|
final NetworkStatsHistory.Entry entry = combined.getValues(
|
||||||
* the requested parameters.
|
augmentStart, augmentEnd, null);
|
||||||
*/
|
|
||||||
public NetworkStats getSummary(NetworkTemplate template, long start, long end,
|
// If we don't have any recorded data for this time period, give
|
||||||
@NetworkStatsAccess.Level int accessLevel) {
|
// ourselves something to scale with.
|
||||||
return getSummary(template, start, end, accessLevel, Binder.getCallingUid());
|
if (entry.rxBytes == 0 || entry.txBytes == 0) {
|
||||||
|
combined.recordData(augmentStart, augmentEnd,
|
||||||
|
new NetworkStats.Entry(1, 0, 1, 0, 0));
|
||||||
|
combined.getValues(augmentStart, augmentEnd, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
final long rawBytes = entry.rxBytes + entry.txBytes;
|
||||||
|
final long rawRxBytes = entry.rxBytes;
|
||||||
|
final long rawTxBytes = entry.txBytes;
|
||||||
|
final long targetBytes = augmentPlan.getDataUsageBytes();
|
||||||
|
final long targetRxBytes = multiplySafe(targetBytes, rawRxBytes, rawBytes);
|
||||||
|
final long targetTxBytes = multiplySafe(targetBytes, rawTxBytes, rawBytes);
|
||||||
|
|
||||||
|
// Scale all matching buckets to reach anchor target
|
||||||
|
final long beforeTotal = combined.getTotalBytes();
|
||||||
|
for (int i = 0; i < combined.size(); i++) {
|
||||||
|
combined.getValues(i, entry);
|
||||||
|
if (entry.bucketStart >= augmentStart
|
||||||
|
&& entry.bucketStart + entry.bucketDuration <= augmentEnd) {
|
||||||
|
entry.rxBytes = multiplySafe(targetRxBytes, entry.rxBytes, rawRxBytes);
|
||||||
|
entry.txBytes = multiplySafe(targetTxBytes, entry.txBytes, rawTxBytes);
|
||||||
|
// We purposefully clear out packet counters to indicate
|
||||||
|
// that this data has been augmented.
|
||||||
|
entry.rxPackets = 0;
|
||||||
|
entry.txPackets = 0;
|
||||||
|
combined.setValues(i, entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final long deltaTotal = combined.getTotalBytes() - beforeTotal;
|
||||||
|
if (deltaTotal != 0) {
|
||||||
|
Slog.d(TAG, "Augmented network usage by " + deltaTotal + " bytes");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally we can slice data as originally requested
|
||||||
|
final NetworkStatsHistory sliced = new NetworkStatsHistory(
|
||||||
|
mBucketDuration, bucketEstimate, fields);
|
||||||
|
sliced.recordHistory(combined, start, end);
|
||||||
|
return sliced;
|
||||||
|
} else {
|
||||||
|
return combined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -230,6 +345,7 @@ public class NetworkStatsCollection implements FileRotator.Reader {
|
|||||||
final long now = System.currentTimeMillis();
|
final long now = System.currentTimeMillis();
|
||||||
|
|
||||||
final NetworkStats stats = new NetworkStats(end - start, 24);
|
final NetworkStats stats = new NetworkStats(end - start, 24);
|
||||||
|
|
||||||
// shortcut when we know stats will be empty
|
// shortcut when we know stats will be empty
|
||||||
if (start == end) return stats;
|
if (start == end) return stats;
|
||||||
|
|
||||||
|
|||||||
@@ -17,28 +17,26 @@
|
|||||||
package com.android.server.net;
|
package com.android.server.net;
|
||||||
|
|
||||||
import static android.net.TrafficStats.MB_IN_BYTES;
|
import static android.net.TrafficStats.MB_IN_BYTES;
|
||||||
|
|
||||||
import static com.android.internal.util.Preconditions.checkArgument;
|
import static com.android.internal.util.Preconditions.checkArgument;
|
||||||
|
|
||||||
import android.app.usage.NetworkStatsManager;
|
import android.app.usage.NetworkStatsManager;
|
||||||
import android.net.DataUsageRequest;
|
import android.net.DataUsageRequest;
|
||||||
import android.net.NetworkStats;
|
import android.net.NetworkStats;
|
||||||
import android.net.NetworkStats.NonMonotonicObserver;
|
|
||||||
import android.net.NetworkStatsHistory;
|
import android.net.NetworkStatsHistory;
|
||||||
import android.net.NetworkTemplate;
|
import android.net.NetworkTemplate;
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Looper;
|
|
||||||
import android.os.Message;
|
|
||||||
import android.os.Messenger;
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.os.Messenger;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.IntArray;
|
|
||||||
import android.util.SparseArray;
|
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
import android.util.SparseArray;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.net.VpnInfo;
|
import com.android.internal.net.VpnInfo;
|
||||||
@@ -410,7 +408,7 @@ class NetworkStatsObservers {
|
|||||||
*/
|
*/
|
||||||
private long getTotalBytesForNetworkUid(NetworkTemplate template, int uid) {
|
private long getTotalBytesForNetworkUid(NetworkTemplate template, int uid) {
|
||||||
try {
|
try {
|
||||||
NetworkStatsHistory history = mCollection.getHistory(template, uid,
|
NetworkStatsHistory history = mCollection.getHistory(template, null, uid,
|
||||||
NetworkStats.SET_ALL, NetworkStats.TAG_NONE,
|
NetworkStats.SET_ALL, NetworkStats.TAG_NONE,
|
||||||
NetworkStatsHistory.FIELD_ALL,
|
NetworkStatsHistory.FIELD_ALL,
|
||||||
Long.MIN_VALUE /* start */, Long.MAX_VALUE /* end */,
|
Long.MIN_VALUE /* start */, Long.MAX_VALUE /* end */,
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import static android.net.NetworkStats.TAG_NONE;
|
|||||||
import static android.net.TrafficStats.KB_IN_BYTES;
|
import static android.net.TrafficStats.KB_IN_BYTES;
|
||||||
import static android.net.TrafficStats.MB_IN_BYTES;
|
import static android.net.TrafficStats.MB_IN_BYTES;
|
||||||
import static android.text.format.DateUtils.YEAR_IN_MILLIS;
|
import static android.text.format.DateUtils.YEAR_IN_MILLIS;
|
||||||
|
|
||||||
import static com.android.internal.util.Preconditions.checkNotNull;
|
import static com.android.internal.util.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
@@ -28,6 +29,7 @@ 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.Binder;
|
||||||
import android.os.DropBoxManager;
|
import android.os.DropBoxManager;
|
||||||
import android.service.NetworkStatsRecorderProto;
|
import android.service.NetworkStatsRecorderProto;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -38,6 +40,9 @@ import android.util.proto.ProtoOutputStream;
|
|||||||
import com.android.internal.net.VpnInfo;
|
import com.android.internal.net.VpnInfo;
|
||||||
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 libcore.io.IoUtils;
|
||||||
|
|
||||||
import com.google.android.collect.Sets;
|
import com.google.android.collect.Sets;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
@@ -52,8 +57,6 @@ import java.util.Arrays;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import libcore.io.IoUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logic to record deltas between periodic {@link NetworkStats} snapshots into
|
* Logic to record deltas between periodic {@link NetworkStats} snapshots into
|
||||||
* {@link NetworkStatsHistory} that belong to {@link NetworkStatsCollection}.
|
* {@link NetworkStatsHistory} that belong to {@link NetworkStatsCollection}.
|
||||||
@@ -150,7 +153,7 @@ public class NetworkStatsRecorder {
|
|||||||
|
|
||||||
public NetworkStats.Entry getTotalSinceBootLocked(NetworkTemplate template) {
|
public NetworkStats.Entry getTotalSinceBootLocked(NetworkTemplate template) {
|
||||||
return mSinceBoot.getSummary(template, Long.MIN_VALUE, Long.MAX_VALUE,
|
return mSinceBoot.getSummary(template, Long.MIN_VALUE, Long.MAX_VALUE,
|
||||||
NetworkStatsAccess.Level.DEVICE).getTotal(null);
|
NetworkStatsAccess.Level.DEVICE, Binder.getCallingUid()).getTotal(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NetworkStatsCollection getSinceBoot() {
|
public NetworkStatsCollection getSinceBoot() {
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ package com.android.server.net;
|
|||||||
|
|
||||||
import static android.Manifest.permission.ACCESS_NETWORK_STATE;
|
import static android.Manifest.permission.ACCESS_NETWORK_STATE;
|
||||||
import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
|
import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
|
||||||
import static android.Manifest.permission.MODIFY_NETWORK_ACCOUNTING;
|
|
||||||
import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
|
import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
|
||||||
import static android.content.Intent.ACTION_SHUTDOWN;
|
import static android.content.Intent.ACTION_SHUTDOWN;
|
||||||
import static android.content.Intent.ACTION_UID_REMOVED;
|
import static android.content.Intent.ACTION_UID_REMOVED;
|
||||||
@@ -27,6 +26,8 @@ import static android.content.Intent.EXTRA_UID;
|
|||||||
import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
|
import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
|
||||||
import static android.net.ConnectivityManager.isNetworkTypeMobile;
|
import static android.net.ConnectivityManager.isNetworkTypeMobile;
|
||||||
import static android.net.NetworkStats.IFACE_ALL;
|
import static android.net.NetworkStats.IFACE_ALL;
|
||||||
|
import static android.net.NetworkStats.METERED_ALL;
|
||||||
|
import static android.net.NetworkStats.ROAMING_ALL;
|
||||||
import static android.net.NetworkStats.SET_ALL;
|
import static android.net.NetworkStats.SET_ALL;
|
||||||
import static android.net.NetworkStats.SET_DEFAULT;
|
import static android.net.NetworkStats.SET_DEFAULT;
|
||||||
import static android.net.NetworkStats.SET_FOREGROUND;
|
import static android.net.NetworkStats.SET_FOREGROUND;
|
||||||
@@ -34,10 +35,12 @@ import static android.net.NetworkStats.STATS_PER_IFACE;
|
|||||||
import static android.net.NetworkStats.STATS_PER_UID;
|
import static android.net.NetworkStats.STATS_PER_UID;
|
||||||
import static android.net.NetworkStats.TAG_NONE;
|
import static android.net.NetworkStats.TAG_NONE;
|
||||||
import static android.net.NetworkStats.UID_ALL;
|
import static android.net.NetworkStats.UID_ALL;
|
||||||
|
import static android.net.NetworkStatsHistory.FIELD_ALL;
|
||||||
import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
|
import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
|
||||||
import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
|
import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
|
||||||
import static android.net.TrafficStats.KB_IN_BYTES;
|
import static android.net.TrafficStats.KB_IN_BYTES;
|
||||||
import static android.net.TrafficStats.MB_IN_BYTES;
|
import static android.net.TrafficStats.MB_IN_BYTES;
|
||||||
|
import static android.provider.Settings.Global.NETSTATS_AUGMENT_ENABLED;
|
||||||
import static android.provider.Settings.Global.NETSTATS_DEV_BUCKET_DURATION;
|
import static android.provider.Settings.Global.NETSTATS_DEV_BUCKET_DURATION;
|
||||||
import static android.provider.Settings.Global.NETSTATS_DEV_DELETE_AGE;
|
import static android.provider.Settings.Global.NETSTATS_DEV_DELETE_AGE;
|
||||||
import static android.provider.Settings.Global.NETSTATS_DEV_PERSIST_BYTES;
|
import static android.provider.Settings.Global.NETSTATS_DEV_PERSIST_BYTES;
|
||||||
@@ -66,6 +69,7 @@ import static com.android.server.NetworkManagementSocketTagger.setKernelCounterS
|
|||||||
|
|
||||||
import android.app.AlarmManager;
|
import android.app.AlarmManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
|
import android.app.usage.NetworkStatsManager;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -105,6 +109,8 @@ import android.provider.Settings;
|
|||||||
import android.provider.Settings.Global;
|
import android.provider.Settings.Global;
|
||||||
import android.service.NetworkInterfaceProto;
|
import android.service.NetworkInterfaceProto;
|
||||||
import android.service.NetworkStatsServiceDumpProto;
|
import android.service.NetworkStatsServiceDumpProto;
|
||||||
|
import android.telephony.SubscriptionManager;
|
||||||
|
import android.telephony.SubscriptionPlan;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.text.format.DateUtils;
|
import android.text.format.DateUtils;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
@@ -118,6 +124,7 @@ import android.util.SparseIntArray;
|
|||||||
import android.util.TrustedTime;
|
import android.util.TrustedTime;
|
||||||
import android.util.proto.ProtoOutputStream;
|
import android.util.proto.ProtoOutputStream;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.net.VpnInfo;
|
import com.android.internal.net.VpnInfo;
|
||||||
import com.android.internal.util.ArrayUtils;
|
import com.android.internal.util.ArrayUtils;
|
||||||
@@ -140,8 +147,8 @@ import java.util.List;
|
|||||||
* other system services.
|
* other system services.
|
||||||
*/
|
*/
|
||||||
public class NetworkStatsService extends INetworkStatsService.Stub {
|
public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||||
private static final String TAG = "NetworkStats";
|
static final String TAG = "NetworkStats";
|
||||||
private static final boolean LOGV = false;
|
static final boolean LOGV = false;
|
||||||
|
|
||||||
private static final int MSG_PERFORM_POLL = 1;
|
private static final int MSG_PERFORM_POLL = 1;
|
||||||
private static final int MSG_UPDATE_IFACES = 2;
|
private static final int MSG_UPDATE_IFACES = 2;
|
||||||
@@ -195,6 +202,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 getAugmentEnabled();
|
||||||
|
|
||||||
public static class Config {
|
public static class Config {
|
||||||
public final long bucketDuration;
|
public final long bucketDuration;
|
||||||
@@ -234,12 +242,17 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
|
private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
|
||||||
new DropBoxNonMonotonicObserver();
|
new DropBoxNonMonotonicObserver();
|
||||||
|
|
||||||
|
@GuardedBy("mStatsLock")
|
||||||
private NetworkStatsRecorder mDevRecorder;
|
private NetworkStatsRecorder mDevRecorder;
|
||||||
|
@GuardedBy("mStatsLock")
|
||||||
private NetworkStatsRecorder mXtRecorder;
|
private NetworkStatsRecorder mXtRecorder;
|
||||||
|
@GuardedBy("mStatsLock")
|
||||||
private NetworkStatsRecorder mUidRecorder;
|
private NetworkStatsRecorder mUidRecorder;
|
||||||
|
@GuardedBy("mStatsLock")
|
||||||
private NetworkStatsRecorder mUidTagRecorder;
|
private NetworkStatsRecorder mUidTagRecorder;
|
||||||
|
|
||||||
/** Cached {@link #mXtRecorder} stats. */
|
/** Cached {@link #mXtRecorder} stats. */
|
||||||
|
@GuardedBy("mStatsLock")
|
||||||
private NetworkStatsCollection mXtStatsCached;
|
private NetworkStatsCollection mXtStatsCached;
|
||||||
|
|
||||||
/** Current counter sets for each UID. */
|
/** Current counter sets for each UID. */
|
||||||
@@ -321,15 +334,15 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create data recorders along with historical rotators
|
|
||||||
mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false);
|
|
||||||
mXtRecorder = buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false);
|
|
||||||
mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false);
|
|
||||||
mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true);
|
|
||||||
|
|
||||||
updatePersistThresholds();
|
|
||||||
|
|
||||||
synchronized (mStatsLock) {
|
synchronized (mStatsLock) {
|
||||||
|
// create data recorders along with historical rotators
|
||||||
|
mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false);
|
||||||
|
mXtRecorder = buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false);
|
||||||
|
mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false);
|
||||||
|
mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true);
|
||||||
|
|
||||||
|
updatePersistThresholdsLocked();
|
||||||
|
|
||||||
// upgrade any legacy stats, migrating them to rotated files
|
// upgrade any legacy stats, migrating them to rotated files
|
||||||
maybeUpgradeLegacyStatsLocked();
|
maybeUpgradeLegacyStatsLocked();
|
||||||
|
|
||||||
@@ -467,18 +480,20 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public INetworkStatsSession openSession() {
|
public INetworkStatsSession openSession() {
|
||||||
return createSession(null, /* poll on create */ false);
|
// NOTE: if callers want to get non-augmented data, they should go
|
||||||
|
// through the public API
|
||||||
|
return openSessionInternal(NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public INetworkStatsSession openSessionForUsageStats(final String callingPackage) {
|
public INetworkStatsSession openSessionForUsageStats(int flags, String callingPackage) {
|
||||||
return createSession(callingPackage, /* poll on create */ true);
|
return openSessionInternal(flags, callingPackage);
|
||||||
}
|
}
|
||||||
|
|
||||||
private INetworkStatsSession createSession(final String callingPackage, boolean pollOnCreate) {
|
private INetworkStatsSession openSessionInternal(final int flags, final String callingPackage) {
|
||||||
assertBandwidthControlEnabled();
|
assertBandwidthControlEnabled();
|
||||||
|
|
||||||
if (pollOnCreate) {
|
if ((flags & NetworkStatsManager.FLAG_POLL_ON_OPEN) != 0) {
|
||||||
final long ident = Binder.clearCallingIdentity();
|
final long ident = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
performPoll(FLAG_PERSIST_ALL);
|
performPoll(FLAG_PERSIST_ALL);
|
||||||
@@ -491,9 +506,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
// for its lifetime; when caller closes only weak references remain.
|
// for its lifetime; when caller closes only weak references remain.
|
||||||
|
|
||||||
return new INetworkStatsSession.Stub() {
|
return new INetworkStatsSession.Stub() {
|
||||||
|
private final int mCallingUid = Binder.getCallingUid();
|
||||||
|
private final String mCallingPackage = callingPackage;
|
||||||
|
private final @NetworkStatsAccess.Level int mAccessLevel = checkAccessLevel(
|
||||||
|
callingPackage);
|
||||||
|
|
||||||
private NetworkStatsCollection mUidComplete;
|
private NetworkStatsCollection mUidComplete;
|
||||||
private NetworkStatsCollection mUidTagComplete;
|
private NetworkStatsCollection mUidTagComplete;
|
||||||
private String mCallingPackage = callingPackage;
|
|
||||||
|
|
||||||
private NetworkStatsCollection getUidComplete() {
|
private NetworkStatsCollection getUidComplete() {
|
||||||
synchronized (mStatsLock) {
|
synchronized (mStatsLock) {
|
||||||
@@ -515,55 +534,38 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[] getRelevantUids() {
|
public int[] getRelevantUids() {
|
||||||
return getUidComplete().getRelevantUids(checkAccessLevel(mCallingPackage));
|
return getUidComplete().getRelevantUids(mAccessLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetworkStats getDeviceSummaryForNetwork(NetworkTemplate template, long start,
|
public NetworkStats getDeviceSummaryForNetwork(
|
||||||
long end) {
|
NetworkTemplate template, long start, long end) {
|
||||||
@NetworkStatsAccess.Level int accessLevel = checkAccessLevel(mCallingPackage);
|
return internalGetSummaryForNetwork(template, flags, start, end, mAccessLevel,
|
||||||
if (accessLevel < NetworkStatsAccess.Level.DEVICESUMMARY) {
|
mCallingUid);
|
||||||
throw new SecurityException("Calling package " + mCallingPackage
|
|
||||||
+ " cannot access device summary network stats");
|
|
||||||
}
|
|
||||||
NetworkStats result = new NetworkStats(end - start, 1);
|
|
||||||
final long ident = Binder.clearCallingIdentity();
|
|
||||||
try {
|
|
||||||
// Using access level higher than the one we checked for above.
|
|
||||||
// Reason is that we are combining usage data in a way that is not PII
|
|
||||||
// anymore.
|
|
||||||
result.combineAllValues(
|
|
||||||
internalGetSummaryForNetwork(template, start, end,
|
|
||||||
NetworkStatsAccess.Level.DEVICE));
|
|
||||||
} finally {
|
|
||||||
Binder.restoreCallingIdentity(ident);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetworkStats getSummaryForNetwork(
|
public NetworkStats getSummaryForNetwork(
|
||||||
NetworkTemplate template, long start, long end) {
|
NetworkTemplate template, long start, long end) {
|
||||||
@NetworkStatsAccess.Level int accessLevel = checkAccessLevel(mCallingPackage);
|
return internalGetSummaryForNetwork(template, flags, start, end, mAccessLevel,
|
||||||
return internalGetSummaryForNetwork(template, start, end, accessLevel);
|
mCallingUid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
|
public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
|
||||||
@NetworkStatsAccess.Level int accessLevel = checkAccessLevel(mCallingPackage);
|
return internalGetHistoryForNetwork(template, flags, fields, mAccessLevel,
|
||||||
return internalGetHistoryForNetwork(template, fields, accessLevel);
|
mCallingUid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetworkStats getSummaryForAllUid(
|
public NetworkStats getSummaryForAllUid(
|
||||||
NetworkTemplate template, long start, long end, boolean includeTags) {
|
NetworkTemplate template, long start, long end, boolean includeTags) {
|
||||||
try {
|
try {
|
||||||
@NetworkStatsAccess.Level int accessLevel = checkAccessLevel(mCallingPackage);
|
final NetworkStats stats = getUidComplete()
|
||||||
final NetworkStats stats =
|
.getSummary(template, start, end, mAccessLevel, mCallingUid);
|
||||||
getUidComplete().getSummary(template, start, end, accessLevel);
|
|
||||||
if (includeTags) {
|
if (includeTags) {
|
||||||
final NetworkStats tagStats = getUidTagComplete()
|
final NetworkStats tagStats = getUidTagComplete()
|
||||||
.getSummary(template, start, end, accessLevel);
|
.getSummary(template, start, end, mAccessLevel, mCallingUid);
|
||||||
stats.combineAllValues(tagStats);
|
stats.combineAllValues(tagStats);
|
||||||
}
|
}
|
||||||
return stats;
|
return stats;
|
||||||
@@ -577,13 +579,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
@Override
|
@Override
|
||||||
public NetworkStatsHistory getHistoryForUid(
|
public NetworkStatsHistory getHistoryForUid(
|
||||||
NetworkTemplate template, int uid, int set, int tag, int fields) {
|
NetworkTemplate template, int uid, int set, int tag, int fields) {
|
||||||
@NetworkStatsAccess.Level int accessLevel = checkAccessLevel(mCallingPackage);
|
// NOTE: We don't augment UID-level statistics
|
||||||
if (tag == TAG_NONE) {
|
if (tag == TAG_NONE) {
|
||||||
return getUidComplete().getHistory(template, uid, set, tag, fields,
|
return getUidComplete().getHistory(template, null, uid, set, tag, fields,
|
||||||
accessLevel);
|
Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
|
||||||
} else {
|
} else {
|
||||||
return getUidTagComplete().getHistory(template, uid, set, tag, fields,
|
return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
|
||||||
accessLevel);
|
Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -591,13 +593,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
public NetworkStatsHistory getHistoryIntervalForUid(
|
public NetworkStatsHistory getHistoryIntervalForUid(
|
||||||
NetworkTemplate template, int uid, int set, int tag, int fields,
|
NetworkTemplate template, int uid, int set, int tag, int fields,
|
||||||
long start, long end) {
|
long start, long end) {
|
||||||
@NetworkStatsAccess.Level int accessLevel = checkAccessLevel(mCallingPackage);
|
// NOTE: We don't augment UID-level statistics
|
||||||
if (tag == TAG_NONE) {
|
if (tag == TAG_NONE) {
|
||||||
return getUidComplete().getHistory(template, uid, set, tag, fields, start, end,
|
return getUidComplete().getHistory(template, null, uid, set, tag, fields,
|
||||||
accessLevel);
|
start, end, mAccessLevel, mCallingUid);
|
||||||
} else if (uid == Binder.getCallingUid()) {
|
} else if (uid == Binder.getCallingUid()) {
|
||||||
return getUidTagComplete().getHistory(template, uid, set, tag, fields,
|
return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
|
||||||
start, end, accessLevel);
|
start, end, mAccessLevel, mCallingUid);
|
||||||
} else {
|
} else {
|
||||||
throw new SecurityException("Calling package " + mCallingPackage
|
throw new SecurityException("Calling package " + mCallingPackage
|
||||||
+ " cannot access tag information from a different uid");
|
+ " cannot access tag information from a different uid");
|
||||||
@@ -617,37 +619,88 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
mContext, Binder.getCallingUid(), callingPackage);
|
mContext, Binder.getCallingUid(), callingPackage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the most relevant {@link SubscriptionPlan} for the given
|
||||||
|
* {@link NetworkTemplate} and flags. This is typically used to augment
|
||||||
|
* local measurement results to match a known anchor from the carrier.
|
||||||
|
*/
|
||||||
|
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)
|
||||||
|
&& mSettings.getAugmentEnabled()) {
|
||||||
|
Slog.d(TAG, "Resolving plan for " + template);
|
||||||
|
final long token = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
final SubscriptionManager sm = mContext.getSystemService(SubscriptionManager.class);
|
||||||
|
final TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
|
||||||
|
for (int subId : sm.getActiveSubscriptionIdList()) {
|
||||||
|
if (template.matchesSubscriberId(tm.getSubscriberId(subId))) {
|
||||||
|
Slog.d(TAG, "Found active matching subId " + subId);
|
||||||
|
final List<SubscriptionPlan> plans = sm.getSubscriptionPlans(subId);
|
||||||
|
if (!plans.isEmpty()) {
|
||||||
|
plan = plans.get(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(token);
|
||||||
|
}
|
||||||
|
Slog.d(TAG, "Resolved to plan " + plan);
|
||||||
|
}
|
||||||
|
return plan;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return network summary, splicing between DEV and XT stats when
|
* Return network summary, splicing between DEV and XT stats when
|
||||||
* appropriate.
|
* appropriate.
|
||||||
*/
|
*/
|
||||||
private NetworkStats internalGetSummaryForNetwork(
|
private NetworkStats internalGetSummaryForNetwork(NetworkTemplate template, int flags,
|
||||||
NetworkTemplate template, long start, long end,
|
long start, long end, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
|
||||||
@NetworkStatsAccess.Level int accessLevel) {
|
|
||||||
// We've been using pure XT stats long enough that we no longer need to
|
// We've been using pure XT stats long enough that we no longer need to
|
||||||
// splice DEV and XT together.
|
// splice DEV and XT together.
|
||||||
return mXtStatsCached.getSummary(template, start, end, accessLevel);
|
final NetworkStatsHistory history = internalGetHistoryForNetwork(template, flags, FIELD_ALL,
|
||||||
|
accessLevel, callingUid);
|
||||||
|
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
final NetworkStatsHistory.Entry entry = history.getValues(start, end, now, null);
|
||||||
|
|
||||||
|
final NetworkStats stats = new NetworkStats(end - start, 1);
|
||||||
|
stats.addValues(new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE, METERED_ALL,
|
||||||
|
ROAMING_ALL, entry.rxBytes, entry.rxPackets, entry.txBytes, entry.txPackets,
|
||||||
|
entry.operations));
|
||||||
|
return stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return network history, splicing between DEV and XT stats when
|
* Return network history, splicing between DEV and XT stats when
|
||||||
* appropriate.
|
* appropriate.
|
||||||
*/
|
*/
|
||||||
private NetworkStatsHistory internalGetHistoryForNetwork(NetworkTemplate template, int fields,
|
private NetworkStatsHistory internalGetHistoryForNetwork(NetworkTemplate template,
|
||||||
@NetworkStatsAccess.Level int accessLevel) {
|
int flags, int fields, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
|
||||||
// We've been using pure XT stats long enough that we no longer need to
|
// We've been using pure XT stats long enough that we no longer need to
|
||||||
// splice DEV and XT together.
|
// splice DEV and XT together.
|
||||||
return mXtStatsCached.getHistory(template, UID_ALL, SET_ALL, TAG_NONE, fields, accessLevel);
|
final SubscriptionPlan augmentPlan = resolveSubscriptionPlan(template, flags);
|
||||||
|
synchronized (mStatsLock) {
|
||||||
|
return mXtStatsCached.getHistory(template, augmentPlan,
|
||||||
|
UID_ALL, SET_ALL, TAG_NONE, fields, Long.MIN_VALUE, Long.MAX_VALUE,
|
||||||
|
accessLevel, callingUid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
|
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
|
// Special case - since this is for internal use only, don't worry about
|
||||||
// check and just require the signature/privileged permission.
|
// a full access level check and just require the signature/privileged
|
||||||
|
// permission.
|
||||||
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
|
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
|
||||||
assertBandwidthControlEnabled();
|
assertBandwidthControlEnabled();
|
||||||
return internalGetSummaryForNetwork(template, start, end, NetworkStatsAccess.Level.DEVICE)
|
|
||||||
.getTotalBytes();
|
// NOTE: if callers want to get non-augmented data, they should go
|
||||||
|
// through the public API
|
||||||
|
return internalGetSummaryForNetwork(template,
|
||||||
|
NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, start, end,
|
||||||
|
NetworkStatsAccess.Level.DEVICE, Binder.getCallingUid()).getTotalBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -691,7 +744,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
@Override
|
@Override
|
||||||
public void incrementOperationCount(int uid, int tag, int operationCount) {
|
public void incrementOperationCount(int uid, int tag, int operationCount) {
|
||||||
if (Binder.getCallingUid() != uid) {
|
if (Binder.getCallingUid() != uid) {
|
||||||
mContext.enforceCallingOrSelfPermission(MODIFY_NETWORK_ACCOUNTING, TAG);
|
mContext.enforceCallingOrSelfPermission(
|
||||||
|
android.Manifest.permission.UPDATE_DEVICE_STATS, TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (operationCount < 0) {
|
if (operationCount < 0) {
|
||||||
@@ -712,7 +766,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setUidForeground(int uid, boolean uidForeground) {
|
public void setUidForeground(int uid, boolean uidForeground) {
|
||||||
mContext.enforceCallingOrSelfPermission(MODIFY_NETWORK_ACCOUNTING, TAG);
|
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;
|
||||||
@@ -752,7 +806,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void advisePersistThreshold(long thresholdBytes) {
|
public void advisePersistThreshold(long thresholdBytes) {
|
||||||
mContext.enforceCallingOrSelfPermission(MODIFY_NETWORK_ACCOUNTING, TAG);
|
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
|
||||||
assertBandwidthControlEnabled();
|
assertBandwidthControlEnabled();
|
||||||
|
|
||||||
// clamp threshold into safe range
|
// clamp threshold into safe range
|
||||||
@@ -768,7 +822,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
synchronized (mStatsLock) {
|
synchronized (mStatsLock) {
|
||||||
if (!mSystemReady) return;
|
if (!mSystemReady) return;
|
||||||
|
|
||||||
updatePersistThresholds();
|
updatePersistThresholdsLocked();
|
||||||
|
|
||||||
mDevRecorder.maybePersistLocked(currentTime);
|
mDevRecorder.maybePersistLocked(currentTime);
|
||||||
mXtRecorder.maybePersistLocked(currentTime);
|
mXtRecorder.maybePersistLocked(currentTime);
|
||||||
@@ -824,7 +878,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
* reflect current {@link #mPersistThreshold} value. Always defers to
|
* reflect current {@link #mPersistThreshold} value. Always defers to
|
||||||
* {@link Global} values when defined.
|
* {@link Global} values when defined.
|
||||||
*/
|
*/
|
||||||
private void updatePersistThresholds() {
|
private void updatePersistThresholdsLocked() {
|
||||||
mDevRecorder.setPersistThreshold(mSettings.getDevPersistBytes(mPersistThreshold));
|
mDevRecorder.setPersistThreshold(mSettings.getDevPersistBytes(mPersistThreshold));
|
||||||
mXtRecorder.setPersistThreshold(mSettings.getXtPersistBytes(mPersistThreshold));
|
mXtRecorder.setPersistThreshold(mSettings.getXtPersistBytes(mPersistThreshold));
|
||||||
mUidRecorder.setPersistThreshold(mSettings.getUidPersistBytes(mPersistThreshold));
|
mUidRecorder.setPersistThreshold(mSettings.getUidPersistBytes(mPersistThreshold));
|
||||||
@@ -1266,7 +1320,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
synchronized (mStatsLock) {
|
synchronized (mStatsLock) {
|
||||||
if (args.length > 0 && "--proto".equals(args[0])) {
|
if (args.length > 0 && "--proto".equals(args[0])) {
|
||||||
// In this case ignore all other arguments.
|
// In this case ignore all other arguments.
|
||||||
dumpProto(fd);
|
dumpProtoLocked(fd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1342,7 +1396,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dumpProto(FileDescriptor fd) {
|
private void dumpProtoLocked(FileDescriptor fd) {
|
||||||
final ProtoOutputStream proto = new ProtoOutputStream(fd);
|
final ProtoOutputStream proto = new ProtoOutputStream(fd);
|
||||||
|
|
||||||
// TODO Right now it writes all history. Should it limit to the "since-boot" log?
|
// TODO Right now it writes all history. Should it limit to the "since-boot" log?
|
||||||
@@ -1530,6 +1584,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
return getGlobalBoolean(NETSTATS_SAMPLE_ENABLED, true);
|
return getGlobalBoolean(NETSTATS_SAMPLE_ENABLED, true);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
public boolean getAugmentEnabled() {
|
||||||
|
return getGlobalBoolean(NETSTATS_AUGMENT_ENABLED, true);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
public Config getDevConfig() {
|
public Config getDevConfig() {
|
||||||
return new Config(getGlobalLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
|
return new Config(getGlobalLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
|
||||||
getGlobalLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
|
getGlobalLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
|
||||||
|
|||||||
Reference in New Issue
Block a user