Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3f391355 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Persist network stats using AtomicFile.

Implements read/write of network stats using AtomicFile, along with
magic number and versioning.  Stores in "/data/system/netstats.bin"
for now.  Tests to verify that stats are persisted across a simulated
reboot, and to verify that TEMPLATE_WIFI is working.

Fixed bug where kernel counters rolling backwards would cause negative
stats to be recorded; now we clamp deltas at 0.

Change-Id: I53bce26fc8fd3f4ab1e34ce135d302edfa34db34
parent f24ed1c2
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -28,6 +28,6 @@ interface INetworkStatsService {
    NetworkStatsHistory getHistoryForUid(int uid, int networkTemplate);

    /** Return usage summary per UID for traffic that matches template. */
    NetworkStats getSummaryPerUid(long start, long end, int networkTemplate);
    NetworkStats getSummaryForAllUid(long start, long end, int networkTemplate);

}
+34 −3
Original line number Diff line number Diff line
@@ -153,6 +153,30 @@ public class NetworkStats implements Parcelable {
        return result;
    }

    /**
     * Subtract the given {@link NetworkStats}, effectively leaving the delta
     * between two snapshots in time. Assumes that statistics rows collect over
     * time, and that none of them have disappeared.
     *
     * @throws IllegalArgumentException when given {@link NetworkStats} is
     *             non-monotonic.
     */
    public NetworkStats subtract(NetworkStats value) {
        return subtract(value, true, false);
    }

    /**
     * Subtract the given {@link NetworkStats}, effectively leaving the delta
     * between two snapshots in time. Assumes that statistics rows collect over
     * time, and that none of them have disappeared.
     * <p>
     * Instead of throwing when counters are non-monotonic, this variant clamps
     * results to never be negative.
     */
    public NetworkStats subtractClamped(NetworkStats value) {
        return subtract(value, false, true);
    }

    /**
     * Subtract the given {@link NetworkStats}, effectively leaving the delta
     * between two snapshots in time. Assumes that statistics rows collect over
@@ -160,8 +184,11 @@ public class NetworkStats implements Parcelable {
     *
     * @param enforceMonotonic Validate that incoming value is strictly
     *            monotonic compared to this object.
     * @param clampNegative Instead of throwing like {@code enforceMonotonic},
     *            clamp resulting counters at 0 to prevent negative values.
     */
    public NetworkStats subtract(NetworkStats value, boolean enforceMonotonic) {
    private NetworkStats subtract(
            NetworkStats value, boolean enforceMonotonic, boolean clampNegative) {
        final long deltaRealtime = this.elapsedRealtime - value.elapsedRealtime;
        if (enforceMonotonic && deltaRealtime < 0) {
            throw new IllegalArgumentException("found non-monotonic realtime");
@@ -181,11 +208,15 @@ public class NetworkStats implements Parcelable {
                result.addEntry(iface, uid, this.rx[i], this.tx[i]);
            } else {
                // existing row, subtract remote value
                final long rx = this.rx[i] - value.rx[j];
                final long tx = this.tx[i] - value.tx[j];
                long rx = this.rx[i] - value.rx[j];
                long tx = this.tx[i] - value.tx[j];
                if (enforceMonotonic && (rx < 0 || tx < 0)) {
                    throw new IllegalArgumentException("found non-monotonic values");
                }
                if (clampNegative) {
                    rx = Math.max(0, rx);
                    tx = Math.max(0, tx);
                }
                result.addEntry(iface, uid, rx, tx);
            }
        }
+5 −1
Original line number Diff line number Diff line
@@ -218,7 +218,7 @@ 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) {
    public long[] getTotalData(long start, long end, long[] outTotal) {
        long rx = 0;
        long tx = 0;

@@ -238,8 +238,12 @@ public class NetworkStatsHistory implements Parcelable {
            }
        }

        if (outTotal == null || outTotal.length != 2) {
            outTotal = new long[2];
        }
        outTotal[0] = rx;
        outTotal[1] = tx;
        return outTotal;
    }

    /**
+2 −2
Original line number Diff line number Diff line
@@ -177,8 +177,8 @@ public class TrafficStats {

            // subtract starting values and return delta
            final NetworkStats profilingStop = getNetworkStatsForUid(context);
            final NetworkStats profilingDelta = profilingStop.subtract(
                    sActiveProfilingStart, false);
            final NetworkStats profilingDelta = profilingStop.subtractClamped(
                    sActiveProfilingStart);
            sActiveProfilingStart = null;
            return profilingDelta;
        }
+3 −3
Original line number Diff line number Diff line
@@ -47,7 +47,7 @@ public class NetworkStatsTest extends TestCase {
                .addEntry(TEST_IFACE, 100, 1024, 0)
                .addEntry(TEST_IFACE, 101, 0, 1024).build();

        final NetworkStats result = after.subtract(before, true);
        final NetworkStats result = after.subtract(before);

        // identical data should result in zero delta
        assertEquals(0, result.rx[0]);
@@ -65,7 +65,7 @@ public class NetworkStatsTest extends TestCase {
                .addEntry(TEST_IFACE, 100, 1025, 2)
                .addEntry(TEST_IFACE, 101, 3, 1028).build();

        final NetworkStats result = after.subtract(before, true);
        final NetworkStats result = after.subtract(before);

        // expect delta between measurements
        assertEquals(1, result.rx[0]);
@@ -84,7 +84,7 @@ public class NetworkStatsTest extends TestCase {
                .addEntry(TEST_IFACE, 101, 0, 1024)
                .addEntry(TEST_IFACE, 102, 1024, 1024).build();

        final NetworkStats result = after.subtract(before, true);
        final NetworkStats result = after.subtract(before);

        // its okay to have new rows
        assertEquals(0, result.rx[0]);
Loading