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

Commit 70c70530 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Transition from DEV network stats to XT.

When XT stats are available, transition to prefer them over DEV,
since they aren't subject to hardware driver bugs.  Only switches at
the first atomic XT bucket, and adds a Settings.Secure flag to force
back to DEV if needed.  Includes tests to cover transition.

Fix tests where device overlay would change which network types
reflected data usage.  Test both history and summary APIs.  Fixed
collection timestamps to reflect full buckets.

Bug: 6504744
Change-Id: Idd7f3b2fdb064c36547c85c51c214fd938c59b7e
parent 559146fc
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -111,6 +111,14 @@ public class NetworkStats implements Parcelable {
                    && operations == 0;
        }

        public void add(Entry another) {
            this.rxBytes += another.rxBytes;
            this.rxPackets += another.rxPackets;
            this.txBytes += another.txBytes;
            this.txPackets += another.txPackets;
            this.operations += another.operations;
        }

        @Override
        public String toString() {
            final StringBuilder builder = new StringBuilder();
+15 −3
Original line number Diff line number Diff line
@@ -342,11 +342,23 @@ public class NetworkStatsHistory implements Parcelable {
     * for combining together stats for external reporting.
     */
    public void recordEntireHistory(NetworkStatsHistory input) {
        recordHistory(input, Long.MIN_VALUE, Long.MAX_VALUE);
    }

    /**
     * Record given {@link NetworkStatsHistory} into this history, copying only
     * buckets that atomically occur in the inclusive time range. Doesn't
     * interpolate across partial buckets.
     */
    public void recordHistory(NetworkStatsHistory input, long start, long end) {
        final NetworkStats.Entry entry = new NetworkStats.Entry(
                IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0L);
        for (int i = 0; i < input.bucketCount; i++) {
            final long start = input.bucketStart[i];
            final long end = start + input.bucketDuration;
            final long bucketStart = input.bucketStart[i];
            final long bucketEnd = bucketStart + input.bucketDuration;

            // skip when bucket is outside requested range
            if (bucketStart < start || bucketEnd > end) continue;

            entry.rxBytes = getLong(input.rxBytes, i, 0L);
            entry.rxPackets = getLong(input.rxPackets, i, 0L);
@@ -354,7 +366,7 @@ public class NetworkStatsHistory implements Parcelable {
            entry.txPackets = getLong(input.txPackets, i, 0L);
            entry.operations = getLong(input.operations, i, 0L);

            recordData(start, end, entry);
            recordData(bucketStart, bucketEnd, entry);
        }
    }

+9 −2
Original line number Diff line number Diff line
@@ -61,6 +61,13 @@ public class NetworkTemplate implements Parcelable {
                com.android.internal.R.array.config_data_usage_network_types);
    }

    private static boolean sForceAllNetworkTypes = false;

    // @VisibleForTesting
    public static void forceAllNetworkTypes() {
        sForceAllNetworkTypes = true;
    }

    /**
     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
     * the given IMSI.
@@ -225,7 +232,7 @@ public class NetworkTemplate implements Parcelable {
            // TODO: consider matching against WiMAX subscriber identity
            return true;
        } else {
            return (contains(DATA_USAGE_NETWORK_TYPES, ident.mType)
            return ((sForceAllNetworkTypes || contains(DATA_USAGE_NETWORK_TYPES, ident.mType))
                    && Objects.equal(mSubscriberId, ident.mSubscriberId));
        }
    }
@@ -291,7 +298,7 @@ public class NetworkTemplate implements Parcelable {
        if (ident.mType == TYPE_WIMAX) {
            return true;
        } else {
            return contains(DATA_USAGE_NETWORK_TYPES, ident.mType);
            return sForceAllNetworkTypes || contains(DATA_USAGE_NETWORK_TYPES, ident.mType);
        }
    }

+2 −0
Original line number Diff line number Diff line
@@ -4210,6 +4210,8 @@ public final class Settings {
        public static final String NETSTATS_GLOBAL_ALERT_BYTES = "netstats_global_alert_bytes";
        /** {@hide} */
        public static final String NETSTATS_SAMPLE_ENABLED = "netstats_sample_enabled";
        /** {@hide} */
        public static final String NETSTATS_REPORT_XT_OVER_DEV = "netstats_report_xt_over_dev";

        /** {@hide} */
        public static final String NETSTATS_DEV_BUCKET_DURATION = "netstats_dev_bucket_duration";
+29 −4
Original line number Diff line number Diff line
@@ -71,7 +71,7 @@ public class NetworkStatsCollection implements FileRotator.Reader {

    private HashMap<Key, NetworkStatsHistory> mStats = Maps.newHashMap();

    private long mBucketDuration;
    private final long mBucketDuration;

    private long mStartMillis;
    private long mEndMillis;
@@ -95,6 +95,18 @@ public class NetworkStatsCollection implements FileRotator.Reader {
        return mStartMillis;
    }

    /**
     * Return first atomic bucket in this collection, which is more conservative
     * than {@link #mStartMillis}.
     */
    public long getFirstAtomicBucketMillis() {
        if (mStartMillis == Long.MAX_VALUE) {
            return Long.MAX_VALUE;
        } else {
            return mStartMillis + mBucketDuration;
        }
    }

    public long getEndMillis() {
        return mEndMillis;
    }
@@ -121,6 +133,15 @@ public class NetworkStatsCollection implements FileRotator.Reader {
     */
    public NetworkStatsHistory getHistory(
            NetworkTemplate template, int uid, int set, int tag, int fields) {
        return getHistory(template, uid, set, tag, fields, Long.MIN_VALUE, Long.MAX_VALUE);
    }

    /**
     * Combine all {@link NetworkStatsHistory} in this collection which match
     * the requested parameters.
     */
    public NetworkStatsHistory getHistory(
            NetworkTemplate template, int uid, int set, int tag, int fields, long start, long end) {
        final NetworkStatsHistory combined = new NetworkStatsHistory(
                mBucketDuration, estimateBuckets(), fields);
        for (Map.Entry<Key, NetworkStatsHistory> entry : mStats.entrySet()) {
@@ -128,7 +149,7 @@ public class NetworkStatsCollection implements FileRotator.Reader {
            final boolean setMatches = set == SET_ALL || key.set == set;
            if (key.uid == uid && setMatches && key.tag == tag
                    && templateMatches(template, key.ident)) {
                combined.recordEntireHistory(entry.getValue());
                combined.recordHistory(entry.getValue(), start, end);
            }
        }
        return combined;
@@ -145,6 +166,9 @@ public class NetworkStatsCollection implements FileRotator.Reader {
        final NetworkStats.Entry entry = new NetworkStats.Entry();
        NetworkStatsHistory.Entry historyEntry = null;

        // shortcut when we know stats will be empty
        if (start == end) return stats;

        for (Map.Entry<Key, NetworkStatsHistory> mapEntry : mStats.entrySet()) {
            final Key key = mapEntry.getKey();
            if (templateMatches(template, key.ident)) {
@@ -175,8 +199,9 @@ public class NetworkStatsCollection implements FileRotator.Reader {
     */
    public void recordData(NetworkIdentitySet ident, int uid, int set, int tag, long start,
            long end, NetworkStats.Entry entry) {
        noteRecordedHistory(start, end, entry.rxBytes + entry.txBytes);
        findOrCreateHistory(ident, uid, set, tag).recordData(start, end, entry);
        final NetworkStatsHistory history = findOrCreateHistory(ident, uid, set, tag);
        history.recordData(start, end, entry);
        noteRecordedHistory(history.getStart(), history.getEnd(), entry.rxBytes + entry.txBytes);
    }

    /**
Loading