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

Commit 5eaa2262 authored by Remi NGUYEN VAN's avatar Remi NGUYEN VAN Committed by android-build-merger
Browse files

Merge "Add method to NetworkStatsService for UID stats." am: db89ca3c

am: af2fafe7

Change-Id: I2527d95000c7500c824ede70f87ecb38e21ed323
parents a9f6576c af2fafe7
Loading
Loading
Loading
Loading
+10 −0
Original line number Original line Diff line number Diff line
@@ -41,6 +41,16 @@ interface INetworkStatsService {


    /** Return data layer snapshot of UID network usage. */
    /** Return data layer snapshot of UID network usage. */
    NetworkStats getDataLayerSnapshotForUid(int uid);
    NetworkStats getDataLayerSnapshotForUid(int uid);

    /** Get a detailed snapshot of stats since boot for all UIDs.
    *
    * <p>Results will not always be limited to stats on requiredIfaces when specified: stats for
    * interfaces stacked on the specified interfaces, or for interfaces on which the specified
    * interfaces are stacked on, will also be included.
    * @param requiredIfaces Interface names to get data for, or {@link NetworkStats#INTERFACES_ALL}.
    */
    NetworkStats getDetailedUidStats(in String[] requiredIfaces);

    /** Return set of any ifaces associated with mobile networks since boot. */
    /** Return set of any ifaces associated with mobile networks since boot. */
    String[] getMobileIfaces();
    String[] getMobileIfaces();


+52 −12
Original line number Original line Diff line number Diff line
@@ -64,6 +64,9 @@ public class NetworkStats implements Parcelable {
    /** Debug {@link #set} value when the VPN stats are moved out of a vpn UID. */
    /** Debug {@link #set} value when the VPN stats are moved out of a vpn UID. */
    public static final int SET_DBG_VPN_OUT = 1002;
    public static final int SET_DBG_VPN_OUT = 1002;


    /** Include all interfaces when filtering */
    public static final String[] INTERFACES_ALL = null;

    /** {@link #tag} value for total data across all tags. */
    /** {@link #tag} value for total data across all tags. */
    // TODO: Rename TAG_NONE to TAG_ALL.
    // TODO: Rename TAG_NONE to TAG_ALL.
    public static final int TAG_NONE = 0;
    public static final int TAG_NONE = 0;
@@ -366,23 +369,27 @@ public class NetworkStats implements Parcelable {
            capacity = newLength;
            capacity = newLength;
        }
        }


        iface[size] = entry.iface;
        setValues(size, entry);
        uid[size] = entry.uid;
        set[size] = entry.set;
        tag[size] = entry.tag;
        metered[size] = entry.metered;
        roaming[size] = entry.roaming;
        defaultNetwork[size] = entry.defaultNetwork;
        rxBytes[size] = entry.rxBytes;
        rxPackets[size] = entry.rxPackets;
        txBytes[size] = entry.txBytes;
        txPackets[size] = entry.txPackets;
        operations[size] = entry.operations;
        size++;
        size++;


        return this;
        return this;
    }
    }


    private void setValues(int i, Entry entry) {
        iface[i] = entry.iface;
        uid[i] = entry.uid;
        set[i] = entry.set;
        tag[i] = entry.tag;
        metered[i] = entry.metered;
        roaming[i] = entry.roaming;
        defaultNetwork[i] = entry.defaultNetwork;
        rxBytes[i] = entry.rxBytes;
        rxPackets[i] = entry.rxPackets;
        txBytes[i] = entry.txBytes;
        txPackets[i] = entry.txPackets;
        operations[i] = entry.operations;
    }

    /**
    /**
     * Return specific stats entry.
     * Return specific stats entry.
     */
     */
@@ -831,6 +838,39 @@ public class NetworkStats implements Parcelable {
        return stats;
        return stats;
    }
    }


    /**
     * Only keep entries that match all specified filters.
     *
     * <p>This mutates the original structure in place. After this method is called,
     * size is the number of matching entries, and capacity is the previous capacity.
     * @param limitUid UID to filter for, or {@link #UID_ALL}.
     * @param limitIfaces Interfaces to filter for, or {@link #INTERFACES_ALL}.
     * @param limitTag Tag to filter for, or {@link #TAG_ALL}.
     */
    public void filter(int limitUid, String[] limitIfaces, int limitTag) {
        if (limitUid == UID_ALL && limitTag == TAG_ALL && limitIfaces == INTERFACES_ALL) {
            return;
        }

        Entry entry = new Entry();
        int nextOutputEntry = 0;
        for (int i = 0; i < size; i++) {
            entry = getValues(i, entry);
            final boolean matches =
                    (limitUid == UID_ALL || limitUid == entry.uid)
                    && (limitTag == TAG_ALL || limitTag == entry.tag)
                    && (limitIfaces == INTERFACES_ALL
                            || ArrayUtils.contains(limitIfaces, entry.iface));

            if (matches) {
                setValues(nextOutputEntry, entry);
                nextOutputEntry++;
            }
        }

        size = nextOutputEntry;
    }

    public void dump(String prefix, PrintWriter pw) {
    public void dump(String prefix, PrintWriter pw) {
        pw.print(prefix);
        pw.print(prefix);
        pw.print("NetworkStats: elapsedRealtime="); pw.println(elapsedRealtime);
        pw.print("NetworkStats: elapsedRealtime="); pw.println(elapsedRealtime);
+4 −2
Original line number Original line Diff line number Diff line
@@ -268,10 +268,12 @@ interface INetworkManagementService
    NetworkStats getNetworkStatsDetail();
    NetworkStats getNetworkStatsDetail();


    /**
    /**
     * Return detailed network statistics for the requested UID,
     * Return detailed network statistics for the requested UID and interfaces,
     * including interface and tag details.
     * including interface and tag details.
     * @param uid UID to obtain statistics for, or {@link NetworkStats#UID_ALL}.
     * @param ifaces Interfaces to obtain statistics for, or {@link NetworkStats#INTERFACES_ALL}.
     */
     */
    NetworkStats getNetworkStatsUidDetail(int uid);
    NetworkStats getNetworkStatsUidDetail(int uid, in String[] ifaces);


    /**
    /**
     * Return summary of network statistics all tethering interfaces.
     * Return summary of network statistics all tethering interfaces.
+53 −19
Original line number Original line Diff line number Diff line
@@ -22,16 +22,14 @@ import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkStats.UID_ALL;
import static com.android.server.NetworkManagementSocketTagger.kernelToTag;
import static com.android.server.NetworkManagementSocketTagger.kernelToTag;


import android.annotation.Nullable;
import android.net.NetworkStats;
import android.net.NetworkStats;
import android.os.StrictMode;
import android.os.StrictMode;
import android.os.SystemClock;
import android.os.SystemClock;
import android.util.ArrayMap;


import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.ProcFileReader;
import com.android.internal.util.ProcFileReader;
import com.google.android.collect.Lists;


import libcore.io.IoUtils;
import libcore.io.IoUtils;


@@ -41,8 +39,10 @@ import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.IOException;
import java.net.ProtocolException;
import java.net.ProtocolException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Objects;
import java.util.HashSet;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/**
/**
 * Creates {@link NetworkStats} instances by parsing various {@code /proc/}
 * Creates {@link NetworkStats} instances by parsing various {@code /proc/}
@@ -72,18 +72,55 @@ public class NetworkStatsFactory {


    private boolean mUseBpfStats;
    private boolean mUseBpfStats;


    // TODO: to improve testability and avoid global state, do not use a static variable.
    // TODO: only do adjustments in NetworkStatsService and remove this.
    @GuardedBy("sStackedIfaces")
    /**
    private static final ArrayMap<String, String> sStackedIfaces = new ArrayMap<>();
     * (Stacked interface) -> (base interface) association for all connected ifaces since boot.
     *
     * Because counters must never roll backwards, once a given interface is stacked on top of an
     * underlying interface, the stacked interface can never be stacked on top of
     * another interface. */
    private static final ConcurrentHashMap<String, String> sStackedIfaces
            = new ConcurrentHashMap<>();


    public static void noteStackedIface(String stackedIface, String baseIface) {
    public static void noteStackedIface(String stackedIface, String baseIface) {
        synchronized (sStackedIfaces) {
        if (stackedIface != null && baseIface != null) {
            if (baseIface != null) {
            sStackedIfaces.put(stackedIface, baseIface);
            sStackedIfaces.put(stackedIface, baseIface);
            } else {
                sStackedIfaces.remove(stackedIface);
        }
        }
    }
    }

    /**
     * Get a set of interfaces containing specified ifaces and stacked interfaces.
     *
     * <p>The added stacked interfaces are ifaces stacked on top of the specified ones, or ifaces
     * on which the specified ones are stacked. Stacked interfaces are those noted with
     * {@link #noteStackedIface(String, String)}, but only interfaces noted before this method
     * is called are guaranteed to be included.
     */
    public static String[] augmentWithStackedInterfacesLocked(@Nullable String[] requiredIfaces) {
        if (requiredIfaces == NetworkStats.INTERFACES_ALL) {
            return null;
        }

        HashSet<String> relatedIfaces = new HashSet<>(Arrays.asList(requiredIfaces));
        // ConcurrentHashMap's EntrySet iterators are "guaranteed to traverse
        // elements as they existed upon construction exactly once, and may
        // (but are not guaranteed to) reflect any modifications subsequent to construction".
        // This is enough here.
        for (Map.Entry<String, String> entry : sStackedIfaces.entrySet()) {
            if (relatedIfaces.contains(entry.getKey())) {
                relatedIfaces.add(entry.getValue());
            } else if (relatedIfaces.contains(entry.getValue())) {
                relatedIfaces.add(entry.getKey());
            }
        }

        String[] outArray = new String[relatedIfaces.size()];
        return relatedIfaces.toArray(outArray);
    }

    @VisibleForTesting
    public static void clearStackedIfaces() {
        sStackedIfaces.clear();
    }
    }


    public NetworkStatsFactory() {
    public NetworkStatsFactory() {
@@ -252,12 +289,9 @@ public class NetworkStatsFactory {
            NetworkStats lastStats) throws IOException {
            NetworkStats lastStats) throws IOException {
        final NetworkStats stats =
        final NetworkStats stats =
              readNetworkStatsDetailInternal(limitUid, limitIfaces, limitTag, lastStats);
              readNetworkStatsDetailInternal(limitUid, limitIfaces, limitTag, lastStats);
        final ArrayMap<String, String> stackedIfaces;
        synchronized (sStackedIfaces) {
            stackedIfaces = new ArrayMap<>(sStackedIfaces);
        }
        // Total 464xlat traffic to subtract from uid 0 on all base interfaces.
        // Total 464xlat traffic to subtract from uid 0 on all base interfaces.
        final NetworkStats adjustments = new NetworkStats(0, stackedIfaces.size());
        // sStackedIfaces may grow afterwards, but NetworkStats will just be resized automatically.
        final NetworkStats adjustments = new NetworkStats(0, sStackedIfaces.size());


        NetworkStats.Entry entry = null; // For recycling
        NetworkStats.Entry entry = null; // For recycling


@@ -271,7 +305,7 @@ public class NetworkStatsFactory {
            if (entry.iface == null || !entry.iface.startsWith(CLATD_INTERFACE_PREFIX)) {
            if (entry.iface == null || !entry.iface.startsWith(CLATD_INTERFACE_PREFIX)) {
                continue;
                continue;
            }
            }
            final String baseIface = stackedIfaces.get(entry.iface);
            final String baseIface = sStackedIfaces.get(entry.iface);
            if (baseIface == null) {
            if (baseIface == null) {
                continue;
                continue;
            }
            }
+0 −1
Original line number Original line Diff line number Diff line
@@ -5314,7 +5314,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
                for (LinkProperties stacked : newNetwork.linkProperties.getStackedLinks()) {
                for (LinkProperties stacked : newNetwork.linkProperties.getStackedLinks()) {
                    final String stackedIface = stacked.getInterfaceName();
                    final String stackedIface = stacked.getInterfaceName();
                    bs.noteNetworkInterfaceType(stackedIface, type);
                    bs.noteNetworkInterfaceType(stackedIface, type);
                    NetworkStatsFactory.noteStackedIface(stackedIface, baseIface);
                }
                }
            } catch (RemoteException ignored) {
            } catch (RemoteException ignored) {
            }
            }
Loading