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(); + } } /**