summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/net/INetworkStatsService.aidl1
-rw-r--r--services/core/java/com/android/server/net/NetworkStatsCollection.java15
-rw-r--r--services/core/java/com/android/server/net/NetworkStatsRecorder.java61
-rw-r--r--services/core/java/com/android/server/net/NetworkStatsService.java32
4 files changed, 109 insertions, 0 deletions
diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl
index 6436e42..17033c4 100644
--- a/core/java/android/net/INetworkStatsService.aidl
+++ b/core/java/android/net/INetworkStatsService.aidl
@@ -57,4 +57,5 @@ interface INetworkStatsService {
/** Advise persistance threshold; may be overridden internally. */
void advisePersistThreshold(long thresholdBytes);
+ void resetDataUsageHistoryForAllUid(in NetworkTemplate template);
}
diff --git a/services/core/java/com/android/server/net/NetworkStatsCollection.java b/services/core/java/com/android/server/net/NetworkStatsCollection.java
index 15b68c7..0176ec4 100644
--- a/services/core/java/com/android/server/net/NetworkStatsCollection.java
+++ b/services/core/java/com/android/server/net/NetworkStatsCollection.java
@@ -491,6 +491,21 @@ public class NetworkStatsCollection implements FileRotator.Reader {
}
}
+ /**
+ * Replace data usage history for each matching identity in the template with empty values
+ */
+ public void resetDataUsage(NetworkTemplate template) {
+ final ArrayList<Key> knownKeys = Lists.newArrayList();
+ knownKeys.addAll(mStats.keySet());
+
+ for (Key key : knownKeys) {
+ if (templateMatches(template, key.ident)) {
+ mStats.put(key, new NetworkStatsHistory(mBucketDuration, 10));
+ mDirty = true;
+ }
+ }
+ }
+
private void noteRecordedHistory(long startMillis, long endMillis, long totalBytes) {
if (startMillis < mStartMillis) mStartMillis = startMillis;
if (endMillis > mEndMillis) mEndMillis = endMillis;
diff --git a/services/core/java/com/android/server/net/NetworkStatsRecorder.java b/services/core/java/com/android/server/net/NetworkStatsRecorder.java
index 6490865..3201981 100644
--- a/services/core/java/com/android/server/net/NetworkStatsRecorder.java
+++ b/services/core/java/com/android/server/net/NetworkStatsRecorder.java
@@ -290,6 +290,31 @@ public class NetworkStatsRecorder {
}
/**
+ * Reset data usage for all matching identities in {@link FileRotator} history,
+ */
+ public void resetDataUsageLocked(NetworkTemplate template) {
+ try {
+ // Reset all persisted data to empty values
+ mRotator.rewriteAll(new ResetDataUsageRewriter(mBucketDuration, template));
+ } catch (IOException e) {
+ Log.wtf(TAG, "problem resetting data stats " + e);
+ recoverFromWtf();
+ } catch (OutOfMemoryError e) {
+ Log.wtf(TAG, "problem resetting data stats " + e);
+ recoverFromWtf();
+ }
+
+ // Reset any pending stats
+ mPending.resetDataUsage(template);
+ mSinceBoot.resetDataUsage(template);
+
+ final NetworkStatsCollection complete = mComplete != null ? mComplete.get() : null;
+ if (complete != null) {
+ complete.resetDataUsage(template);
+ }
+ }
+
+ /**
* Rewriter that will combine current {@link NetworkStatsCollection} values
* with anything read from disk, and write combined set to disk. Clears the
* original {@link NetworkStatsCollection} when finished writing.
@@ -359,6 +384,42 @@ public class NetworkStatsRecorder {
}
}
+ /**
+ * Rewriter that will remove any {@link NetworkStatsHistory} attributed to
+ * identities in input template, replacing it with empty values.
+ */
+ public static class ResetDataUsageRewriter implements FileRotator.Rewriter {
+ private final NetworkStatsCollection mTemp;
+ private NetworkTemplate mTemplate;
+
+ public ResetDataUsageRewriter(long bucketDuration, NetworkTemplate template) {
+ mTemp = new NetworkStatsCollection(bucketDuration);
+ mTemplate = template;
+ }
+
+ @Override
+ public void reset() {
+ mTemp.reset();
+ }
+
+ @Override
+ public void read(InputStream in) throws IOException {
+ mTemp.read(in);
+ mTemp.clearDirty();
+ mTemp.resetDataUsage(mTemplate);
+ }
+
+ @Override
+ public boolean shouldWrite() {
+ return mTemp.isDirty();
+ }
+
+ @Override
+ public void write(OutputStream out) throws IOException {
+ mTemp.write(new DataOutputStream(out));
+ }
+ }
+
public void importLegacyNetworkLocked(File file) throws IOException {
// legacy file still exists; start empty to avoid double importing
mRotator.deleteAll();
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index acd05f7..dce601b 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -628,6 +628,26 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
return mXtStatsCached.getHistory(template, UID_ALL, SET_ALL, TAG_NONE, fields);
}
+ /**
+ * Reset entire data usage history for all the uids in the template and update global
+ * data stats
+ */
+ @Override
+ public void resetDataUsageHistoryForAllUid(NetworkTemplate template) {
+ mContext.enforceCallingOrSelfPermission(MODIFY_NETWORK_ACCOUNTING, TAG);
+
+ synchronized (mStatsLock) {
+ mWakeLock.acquire();
+ try {
+ resetDataUsageLocked(template);
+ } catch (Exception e) {
+ // ignored; service lives in system_server
+ } finally {
+ mWakeLock.release();
+ }
+ }
+ }
+
@Override
public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
@@ -1148,6 +1168,18 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
removeUidsLocked(uids);
}
+ /**
+ * Reset data usage history for all uids, uid tags, and global transfer data for the input template
+ */
+ private void resetDataUsageLocked(NetworkTemplate template) {
+ // Perform one last poll before removing
+ performPollLocked(FLAG_PERSIST_ALL);
+
+ mUidRecorder.resetDataUsageLocked(template);
+ mUidTagRecorder.resetDataUsageLocked(template);
+ mXtRecorder.resetDataUsageLocked(template);
+ }
+
@Override
protected void dump(FileDescriptor fd, PrintWriter rawWriter, String[] args) {
mContext.enforceCallingOrSelfPermission(DUMP, TAG);