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

Commit 442fa21e authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android (Google) Code Review
Browse files

Merge "APIs to profile network usage for current UID."

parents 9ddcdd98 eedcb952
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1544,6 +1544,9 @@ public abstract class Context {
     */
    public static final String NETWORKMANAGEMENT_SERVICE = "network_management";

    /** {@hide} */
    public static final String NETWORK_POLICY_SERVICE = "netpolicy";

    /**
     * Use with {@link #getSystemService} to retrieve a {@link
     * android.net.wifi.WifiManager} for handling management of
+5 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.net;

import android.content.Context;
import android.os.RemoteException;

/**
@@ -43,6 +44,10 @@ public class NetworkPolicyManager {
        mService = service;
    }

    public static NetworkPolicyManager getSystemService(Context context) {
        return (NetworkPolicyManager) context.getSystemService(Context.NETWORK_POLICY_SERVICE);
    }

    /**
     * Set policy flags for specific UID.
     *
+47 −7
Original line number Diff line number Diff line
@@ -36,6 +36,9 @@ public class NetworkStats implements Parcelable {
    /** {@link #uid} value when entry is summarized over all UIDs. */
    public static final int UID_ALL = 0;

    // NOTE: data should only be accounted for once in this structure; if data
    // is broken out, the summarized version should not be included.

    /**
     * {@link SystemClock#elapsedRealtime()} timestamp when this data was
     * generated.
@@ -81,12 +84,13 @@ public class NetworkStats implements Parcelable {
            mTx = new long[size];
        }

        public void addEntry(String iface, int uid, long rx, long tx) {
        public Builder addEntry(String iface, int uid, long rx, long tx) {
            mIface[mIndex] = iface;
            mUid[mIndex] = uid;
            mRx[mIndex] = rx;
            mTx[mIndex] = tx;
            mIndex++;
            return this;
        }

        public NetworkStats build() {
@@ -97,11 +101,17 @@ public class NetworkStats implements Parcelable {
        }
    }

    public int length() {
        // length is identical for all fields
        return iface.length;
    }

    /**
     * Find first stats index that matches the requested parameters.
     */
    public int findIndex(String iface, int uid) {
        for (int i = 0; i < this.iface.length; i++) {
        final int length = length();
        for (int i = 0; i < length; i++) {
            if (equal(iface, this.iface[i]) && uid == this.uid[i]) {
                return i;
            }
@@ -109,13 +119,38 @@ public class NetworkStats implements Parcelable {
        return -1;
    }

    private static boolean equal(Object a, Object b) {
        return a == b || (a != null && a.equals(b));
    /**
     * 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.
     */
    public NetworkStats subtract(NetworkStats value) {
        // result will have our rows, but no meaningful timestamp
        final int length = length();
        final NetworkStats.Builder result = new NetworkStats.Builder(-1, length);

        for (int i = 0; i < length; i++) {
            final String iface = this.iface[i];
            final int uid = this.uid[i];

            // find remote row that matches, and subtract
            final int j = value.findIndex(iface, uid);
            if (j == -1) {
                // newly appearing row, return entire value
                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];
                result.addEntry(iface, uid, rx, tx);
            }
        }

    /** {@inheritDoc} */
    public int describeContents() {
        return 0;
        return result.build();
    }

    private static boolean equal(Object a, Object b) {
        return a == b || (a != null && a.equals(b));
    }

    public void dump(String prefix, PrintWriter pw) {
@@ -137,6 +172,11 @@ public class NetworkStats implements Parcelable {
        return writer.toString();
    }

    /** {@inheritDoc} */
    public int describeContents() {
        return 0;
    }

    /** {@inheritDoc} */
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeLong(elapsedRealtime);
+72 −0
Original line number Diff line number Diff line
@@ -16,6 +16,12 @@

package android.net;

import android.content.Context;
import android.os.IBinder;
import android.os.INetworkManagementService;
import android.os.RemoteException;
import android.os.ServiceManager;

import dalvik.system.BlockGuard;

import java.net.Socket;
@@ -35,6 +41,17 @@ public class TrafficStats {
     */
    public final static int UNSUPPORTED = -1;

    /**
     * Snapshot of {@link NetworkStats} when the currently active profiling
     * session started, or {@code null} if no session active.
     *
     * @see #startDataProfiling(Context)
     * @see #stopDataProfiling(Context)
     */
    private static NetworkStats sActiveProfilingStart;

    private static Object sProfilingLock = new Object();

    /**
     * Set active tag to use when accounting {@link Socket} traffic originating
     * from the current thread. Only one active tag per thread is supported.
@@ -92,6 +109,44 @@ public class TrafficStats {
        BlockGuard.untagSocketFd(socket.getFileDescriptor$());
    }

    /**
     * Start profiling data usage for current UID. Only one profiling session
     * can be active at a time.
     *
     * @hide
     */
    public static void startDataProfiling(Context context) {
        synchronized (sProfilingLock) {
            if (sActiveProfilingStart != null) {
                throw new IllegalStateException("already profiling data");
            }

            // take snapshot in time; we calculate delta later
            sActiveProfilingStart = getNetworkStatsForUid(context);
        }
    }

    /**
     * Stop profiling data usage for current UID.
     *
     * @return Detailed {@link NetworkStats} of data that occurred since last
     *         {@link #startDataProfiling(Context)} call.
     * @hide
     */
    public static NetworkStats stopDataProfiling(Context context) {
        synchronized (sProfilingLock) {
            if (sActiveProfilingStart == null) {
                throw new IllegalStateException("not profiling data");
            }

            // subtract starting values and return delta
            final NetworkStats profilingStop = getNetworkStatsForUid(context);
            final NetworkStats profilingDelta = profilingStop.subtract(sActiveProfilingStart);
            sActiveProfilingStart = null;
            return profilingDelta;
        }
    }

    /**
     * Get the total number of packets transmitted through the mobile interface.
     *
@@ -350,4 +405,21 @@ public class TrafficStats {
     * {@link #UNSUPPORTED} will be returned.
     */
    public static native long getUidUdpRxPackets(int uid);

    /**
     * Return detailed {@link NetworkStats} for the current UID. Requires no
     * special permission.
     */
    private static NetworkStats getNetworkStatsForUid(Context context) {
        final IBinder binder = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
        final INetworkManagementService service = INetworkManagementService.Stub.asInterface(
                binder);

        final int uid = android.os.Process.myUid();
        try {
            return service.getNetworkStatsUidDetail(uid);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    }
}
+6 −0
Original line number Diff line number Diff line
@@ -213,6 +213,12 @@ interface INetworkManagementService
     */
    NetworkStats getNetworkStatsDetail();

    /**
     * Return detailed network statistics for the requested UID,
     * including interface and tag details.
     */
    NetworkStats getNetworkStatsUidDetail(int uid);

    /**
     * Configures bandwidth throttling on an interface.
     */
Loading