diff options
author | Kamaljeet Maini <kmaini@cyngn.com> | 2016-02-18 17:49:48 -0800 |
---|---|---|
committer | Gerrit Code Review <gerrit@cyanogenmod.org> | 2016-04-01 13:29:23 -0700 |
commit | a3bc0853871143db31f2fc5b91b5bad88e36a82b (patch) | |
tree | c3dc4cfa4379ab3d1636bca8a4877bbe5482e7a4 | |
parent | 39aa78bbf20b7bd83eaf68a6d24621662944c50f (diff) | |
download | frameworks_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
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); |