Loading core/java/android/content/Context.java +3 −0 Original line number Diff line number Diff line Loading @@ -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 Loading core/java/android/net/NetworkPolicyManager.java +5 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.net; import android.content.Context; import android.os.RemoteException; /** Loading Loading @@ -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. * Loading core/java/android/net/NetworkStats.java +47 −7 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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() { Loading @@ -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; } Loading @@ -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) { Loading @@ -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); Loading core/java/android/net/TrafficStats.java +72 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. Loading Loading @@ -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. * Loading Loading @@ -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); } } } core/java/android/os/INetworkManagementService.aidl +6 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
core/java/android/content/Context.java +3 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
core/java/android/net/NetworkPolicyManager.java +5 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.net; import android.content.Context; import android.os.RemoteException; /** Loading Loading @@ -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. * Loading
core/java/android/net/NetworkStats.java +47 −7 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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() { Loading @@ -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; } Loading @@ -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) { Loading @@ -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); Loading
core/java/android/net/TrafficStats.java +72 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. Loading Loading @@ -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. * Loading Loading @@ -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); } } }
core/java/android/os/INetworkManagementService.aidl +6 −0 Original line number Diff line number Diff line Loading @@ -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