summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKamaljeet Maini <kmaini@cyngn.com>2016-02-18 17:49:48 -0800
committerGerrit Code Review <gerrit@cyanogenmod.org>2016-04-01 13:29:23 -0700
commita3bc0853871143db31f2fc5b91b5bad88e36a82b (patch)
treec3dc4cfa4379ab3d1636bca8a4877bbe5482e7a4
parent39aa78bbf20b7bd83eaf68a6d24621662944c50f (diff)
downloadframeworks_base-a3bc0853871143db31f2fc5b91b5bad88e36a82b.zip
frameworks_base-a3bc0853871143db31f2fc5b91b5bad88e36a82b.tar.gz
frameworks_base-a3bc0853871143db31f2fc5b91b5bad88e36a82b.tar.bz2
Framework changes for resetting data usage statistics
As part of data management experience enhancements in Settings application, a new feature is added. This feature allows users to fully reset all data usage stats of currently selected network interface. When data stats are reset for a specific network interface, the total data usage and per app data usage for that interface is reset to zero. There is no way to revert this reset. Prior to this feature, users could only change the data stats cycle to hide older data usage history. Alternatively, users could perform fully factory reset to remove the usage history. This feature allows fully clearing data usage stats history without any other changes. Change-Id: I242331cf85cec00997a8aa34e8bdcbccf0917864
-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);