Add rate limiting and logging for NetworkStats.
Bug: 77908520, 77808546, 77853238, 77154412 Test: atest com.android.server.net.NetworkStatsServiceTest Test: manual: flashed, verified network usage updated Change-Id: I905dbea85e00f80103916939f6d4bf8cab931d03
This commit is contained in:
committed by
Jeff Sharkey
parent
8732487ce6
commit
3d55d4c02e
@@ -286,6 +286,16 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
private long mPersistThreshold = 2 * MB_IN_BYTES;
|
private long mPersistThreshold = 2 * MB_IN_BYTES;
|
||||||
private long mGlobalAlertBytes;
|
private long mGlobalAlertBytes;
|
||||||
|
|
||||||
|
private static final long POLL_RATE_LIMIT_MS = 15_000;
|
||||||
|
|
||||||
|
private long mLastStatsSessionPoll;
|
||||||
|
|
||||||
|
/** Map from UID to number of opened sessions */
|
||||||
|
@GuardedBy("mOpenSessionCallsPerUid")
|
||||||
|
private final SparseIntArray mOpenSessionCallsPerUid = new SparseIntArray();
|
||||||
|
|
||||||
|
private final static int DUMP_STATS_SESSION_COUNT = 20;
|
||||||
|
|
||||||
private static @NonNull File getDefaultSystemDir() {
|
private static @NonNull File getDefaultSystemDir() {
|
||||||
return new File(Environment.getDataDirectory(), "system");
|
return new File(Environment.getDataDirectory(), "system");
|
||||||
}
|
}
|
||||||
@@ -509,10 +519,31 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
return openSessionInternal(flags, callingPackage);
|
return openSessionInternal(flags, callingPackage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isRateLimitedForPoll(int callingUid) {
|
||||||
|
if (callingUid == android.os.Process.SYSTEM_UID) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final long lastCallTime;
|
||||||
|
final long now = SystemClock.elapsedRealtime();
|
||||||
|
synchronized (mOpenSessionCallsPerUid) {
|
||||||
|
int calls = mOpenSessionCallsPerUid.get(callingUid, 0);
|
||||||
|
mOpenSessionCallsPerUid.put(callingUid, calls + 1);
|
||||||
|
lastCallTime = mLastStatsSessionPoll;
|
||||||
|
mLastStatsSessionPoll = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
return now - lastCallTime < POLL_RATE_LIMIT_MS;
|
||||||
|
}
|
||||||
|
|
||||||
private INetworkStatsSession openSessionInternal(final int flags, final String callingPackage) {
|
private INetworkStatsSession openSessionInternal(final int flags, final String callingPackage) {
|
||||||
assertBandwidthControlEnabled();
|
assertBandwidthControlEnabled();
|
||||||
|
|
||||||
if ((flags & NetworkStatsManager.FLAG_POLL_ON_OPEN) != 0) {
|
final int callingUid = Binder.getCallingUid();
|
||||||
|
final int usedFlags = isRateLimitedForPoll(callingUid)
|
||||||
|
? flags & (~NetworkStatsManager.FLAG_POLL_ON_OPEN)
|
||||||
|
: flags;
|
||||||
|
if ((usedFlags & 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);
|
||||||
@@ -525,7 +556,7 @@ 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 int mCallingUid = callingUid;
|
||||||
private final String mCallingPackage = callingPackage;
|
private final String mCallingPackage = callingPackage;
|
||||||
private final @NetworkStatsAccess.Level int mAccessLevel = checkAccessLevel(
|
private final @NetworkStatsAccess.Level int mAccessLevel = checkAccessLevel(
|
||||||
callingPackage);
|
callingPackage);
|
||||||
@@ -559,20 +590,20 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
@Override
|
@Override
|
||||||
public NetworkStats getDeviceSummaryForNetwork(
|
public NetworkStats getDeviceSummaryForNetwork(
|
||||||
NetworkTemplate template, long start, long end) {
|
NetworkTemplate template, long start, long end) {
|
||||||
return internalGetSummaryForNetwork(template, flags, start, end, mAccessLevel,
|
return internalGetSummaryForNetwork(template, usedFlags, start, end, mAccessLevel,
|
||||||
mCallingUid);
|
mCallingUid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetworkStats getSummaryForNetwork(
|
public NetworkStats getSummaryForNetwork(
|
||||||
NetworkTemplate template, long start, long end) {
|
NetworkTemplate template, long start, long end) {
|
||||||
return internalGetSummaryForNetwork(template, flags, start, end, mAccessLevel,
|
return internalGetSummaryForNetwork(template, usedFlags, start, end, mAccessLevel,
|
||||||
mCallingUid);
|
mCallingUid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
|
public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
|
||||||
return internalGetHistoryForNetwork(template, flags, fields, mAccessLevel,
|
return internalGetHistoryForNetwork(template, usedFlags, fields, mAccessLevel,
|
||||||
mCallingUid);
|
mCallingUid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1461,6 +1492,30 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
}
|
}
|
||||||
pw.decreaseIndent();
|
pw.decreaseIndent();
|
||||||
|
|
||||||
|
// Get the top openSession callers
|
||||||
|
final SparseIntArray calls;
|
||||||
|
synchronized (mOpenSessionCallsPerUid) {
|
||||||
|
calls = mOpenSessionCallsPerUid.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
final int N = calls.size();
|
||||||
|
final long[] values = new long[N];
|
||||||
|
for (int j = 0; j < N; j++) {
|
||||||
|
values[j] = ((long) calls.valueAt(j) << 32) | calls.keyAt(j);
|
||||||
|
}
|
||||||
|
Arrays.sort(values);
|
||||||
|
|
||||||
|
pw.println("Top openSession callers (uid=count):");
|
||||||
|
pw.increaseIndent();
|
||||||
|
final int end = Math.max(0, N - DUMP_STATS_SESSION_COUNT);
|
||||||
|
for (int j = N - 1; j >= end; j--) {
|
||||||
|
final int uid = (int) (values[j] & 0xffffffff);
|
||||||
|
final int count = (int) (values[j] >> 32);
|
||||||
|
pw.print(uid); pw.print("="); pw.println(count);
|
||||||
|
}
|
||||||
|
pw.decreaseIndent();
|
||||||
|
pw.println();
|
||||||
|
|
||||||
pw.println("Dev stats:");
|
pw.println("Dev stats:");
|
||||||
pw.increaseIndent();
|
pw.increaseIndent();
|
||||||
mDevRecorder.dumpLocked(pw, fullHistory);
|
mDevRecorder.dumpLocked(pw, fullHistory);
|
||||||
|
|||||||
Reference in New Issue
Block a user