From 0b1cfc0d552a548cd232f2a60f18615b7accd170 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Thu, 2 Jun 2011 17:38:22 -0700 Subject: [PATCH] Compute range-based usage in NetworkStatsHistory. When given a start/end range, interpolate between buckets to return the total network usage. Used to summarize detailed UID stats. Method to combine NetworkStatsHistory regardless of bucket size. Used to combine all histories matching a template. Added tests for both methods. Change-Id: Ia463910c0ecf7cf08dcf97c658ad99742bd6b882 --- .../java/android/net/NetworkStatsHistory.java | 40 +++++++++++++++++++ .../server/net/NetworkStatsService.java | 19 +++++++-- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java index 45d8e27645..5edbf5830d 100644 --- a/core/java/android/net/NetworkStatsHistory.java +++ b/core/java/android/net/NetworkStatsHistory.java @@ -133,6 +133,18 @@ public class NetworkStatsHistory implements Parcelable { } } + /** + * Record an entire {@link NetworkStatsHistory} into this history. Usually + * for combining together stats for external reporting. + */ + public void recordEntireHistory(NetworkStatsHistory input) { + for (int i = 0; i < input.bucketCount; i++) { + final long start = input.bucketStart[i]; + final long end = start + input.bucketDuration; + recordData(start, end, input.rx[i], input.tx[i]); + } + } + /** * Ensure that buckets exist for given time range, creating as needed. */ @@ -202,6 +214,34 @@ public class NetworkStatsHistory implements Parcelable { } } + /** + * Return interpolated data usage across the requested range. Interpolates + * across buckets, so values may be rounded slightly. + */ + public void getTotalData(long start, long end, long[] outTotal) { + long rx = 0; + long tx = 0; + + for (int i = bucketCount - 1; i >= 0; i--) { + final long curStart = bucketStart[i]; + final long curEnd = curStart + bucketDuration; + + // bucket is older than record; we're finished + if (curEnd < start) break; + // bucket is newer than record; keep looking + if (curStart > end) continue; + + final long overlap = Math.min(curEnd, end) - Math.max(curStart, start); + if (overlap > 0) { + rx += this.rx[i] * overlap / bucketDuration; + tx += this.tx[i] * overlap / bucketDuration; + } + } + + outTotal[0] = rx; + outTotal[1] = tx; + } + /** * @deprecated only for temporary testing */ diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java index 967e491449..3892de8131 100644 --- a/services/java/com/android/server/net/NetworkStatsService.java +++ b/services/java/com/android/server/net/NetworkStatsService.java @@ -210,7 +210,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { for (InterfaceIdentity ident : mSummaryStats.keySet()) { final NetworkStatsHistory history = mSummaryStats.get(ident); if (ident.matchesTemplate(networkTemplate, subscriberId)) { - // TODO: combine all matching history data into a single history + combined.recordEntireHistory(history); } } return combined; @@ -231,8 +231,21 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // TODO: create relaxed permission for reading stats mContext.enforceCallingOrSelfPermission(UPDATE_DEVICE_STATS, TAG); - // TODO: total UID-granularity usage between time range - return null; + // TODO: apply networktemplate once granular uid stats are stored. + + synchronized (mStatsLock) { + final int size = mDetailStats.size(); + final NetworkStats.Builder stats = new NetworkStats.Builder(end - start, size); + + final long[] total = new long[2]; + for (int i = 0; i < size; i++) { + final int uid = mDetailStats.keyAt(i); + final NetworkStatsHistory history = mDetailStats.valueAt(i); + history.getTotalData(start, end, total); + stats.addEntry(IFACE_ALL, uid, total[0], total[1]); + } + return stats.build(); + } } /**