summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2011-05-17 14:55:15 -0700
committerJeff Sharkey <jsharkey@android.com>2011-05-21 15:02:58 -0700
commiteedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3 (patch)
tree2753882abd3cd277dce4c30a1d6a59172f2c6f46 /services
parent850ae9acda0d062f9a1836d159bdce819e0f8066 (diff)
downloadframeworks_base-eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3.zip
frameworks_base-eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3.tar.gz
frameworks_base-eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3.tar.bz2
APIs to profile network usage for current UID.
Added startDataProfiling() and stopDataProfiling() to TrafficStats, which can be used by apps to measure network usage delta between two points in time. Currently takes two NetworkStats snapshots and returns delta, which will eventually include tag-level granularity. Added tests for NetworkStats delta subtraction. Added NMS.getNetworkStatsUidDetail() that returns stats for specific UID. Always gives stats access for the calling UID, otherwise enforces that caller has permission. Fix readSingleLongFromFile(), since /proc/ files don't have well-defined lengths. Change-Id: Ic5b6414d8effbd66846e275b00d4b8a82c74589d
Diffstat (limited to 'services')
-rw-r--r--services/java/com/android/server/NetworkManagementService.java89
-rw-r--r--services/java/com/android/server/net/NetworkPolicyManagerService.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java2
3 files changed, 45 insertions, 50 deletions
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 7c613c1..8f179f5 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -16,51 +16,34 @@
package com.android.server;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
import android.content.pm.PackageManager;
-import android.net.NetworkStats;
-import android.net.Uri;
-import android.net.InterfaceConfiguration;
import android.net.INetworkManagementEventObserver;
+import android.net.InterfaceConfiguration;
import android.net.LinkAddress;
+import android.net.NetworkStats;
import android.net.NetworkUtils;
import android.net.RouteInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.KeyMgmt;
+import android.os.Binder;
import android.os.INetworkManagementService;
-import android.os.Handler;
-import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemProperties;
-import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
-import java.util.ArrayList;
-import java.util.NoSuchElementException;
-import java.util.StringTokenizer;
-import android.provider.Settings;
-import android.content.ContentResolver;
-import android.database.ContentObserver;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileReader;
import java.io.IOException;
-import java.io.InputStream;
import java.io.InputStreamReader;
-import java.io.RandomAccessFile;
-import java.io.Reader;
-import java.lang.IllegalStateException;
-import java.net.InetAddress;
import java.net.Inet4Address;
-import java.net.UnknownHostException;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
import java.util.concurrent.CountDownLatch;
import libcore.io.IoUtils;
@@ -69,14 +52,16 @@ import libcore.io.IoUtils;
* @hide
*/
class NetworkManagementService extends INetworkManagementService.Stub {
-
- private static final String TAG = "NetworkManagmentService";
+ private static final String TAG = "NetworkManagementService";
private static final boolean DBG = false;
private static final String NETD_TAG = "NetdConnector";
private static final int ADD = 1;
private static final int REMOVE = 2;
+ /** Base path to UID-granularity network statistics. */
+ private static final File PATH_PROC_UID_STAT = new File("/proc/uid_stat");
+
class NetdResponseCode {
public static final int InterfaceListResult = 110;
public static final int TetherInterfaceListResult = 111;
@@ -891,7 +876,7 @@ class NetworkManagementService extends INetworkManagementService.Stub {
return -1;
}
- /** {@inheritDoc} */
+ @Override
public NetworkStats getNetworkStatsSummary() {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
@@ -909,31 +894,46 @@ class NetworkManagementService extends INetworkManagementService.Stub {
return stats.build();
}
- /** {@inheritDoc} */
+ @Override
public NetworkStats getNetworkStatsDetail() {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
- final File procPath = new File("/proc/uid_stat");
- final String[] knownUids = procPath.list();
+ final String[] knownUids = PATH_PROC_UID_STAT.list();
final NetworkStats.Builder stats = new NetworkStats.Builder(
SystemClock.elapsedRealtime(), knownUids.length);
- // TODO: kernel module will provide interface-level stats in future
- // TODO: migrate these stats to come across netd in bulk, instead of all
- // these individual file reads.
for (String uid : knownUids) {
- final File uidPath = new File(procPath, uid);
- final int rx = readSingleIntFromFile(new File(uidPath, "tcp_rcv"));
- final int tx = readSingleIntFromFile(new File(uidPath, "tcp_snd"));
-
final int uidInt = Integer.parseInt(uid);
- stats.addEntry(NetworkStats.IFACE_ALL, uidInt, rx, tx);
+ collectNetworkStatsDetail(stats, uidInt);
}
return stats.build();
}
+ @Override
+ public NetworkStats getNetworkStatsUidDetail(int uid) {
+ if (Binder.getCallingUid() != uid) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
+ }
+
+ final NetworkStats.Builder stats = new NetworkStats.Builder(
+ SystemClock.elapsedRealtime(), 1);
+ collectNetworkStatsDetail(stats, uid);
+ return stats.build();
+ }
+
+ private void collectNetworkStatsDetail(NetworkStats.Builder stats, int uid) {
+ // TODO: kernel module will provide interface-level stats in future
+ // TODO: migrate these stats to come across netd in bulk, instead of all
+ // these individual file reads.
+ final File uidPath = new File(PATH_PROC_UID_STAT, Integer.toString(uid));
+ final long rx = readSingleLongFromFile(new File(uidPath, "tcp_rcv"));
+ final long tx = readSingleLongFromFile(new File(uidPath, "tcp_snd"));
+ stats.addEntry(NetworkStats.IFACE_ALL, uid, rx, tx);
+ }
+
public void setInterfaceThrottle(String iface, int rxKbps, int txKbps) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
@@ -994,22 +994,17 @@ class NetworkManagementService extends INetworkManagementService.Stub {
}
/**
- * Utility method to read a single plain-text {@link Integer} from the given
+ * Utility method to read a single plain-text {@link Long} from the given
* {@link File}, usually from a {@code /proc/} filesystem.
*/
- private static int readSingleIntFromFile(File file) {
- RandomAccessFile f = null;
+ private static long readSingleLongFromFile(File file) {
try {
- f = new RandomAccessFile(file, "r");
- byte[] buffer = new byte[(int) f.length()];
- f.readFully(buffer);
- return Integer.parseInt(new String(buffer).trim());
+ final byte[] buffer = IoUtils.readFileAsByteArray(file.toString());
+ return Long.parseLong(new String(buffer).trim());
} catch (NumberFormatException e) {
return -1;
} catch (IOException e) {
return -1;
- } finally {
- IoUtils.closeQuietly(f);
}
}
}
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index a7a4f07..312c32b 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -38,8 +38,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private static final String TAG = "NetworkPolicy";
private static final boolean LOGD = true;
- private static final String SERVICE_NAME = "netpolicy";
-
private Context mContext;
/** Current network policy for each UID. */
@@ -56,7 +54,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
public void publish(Context context) {
mContext = context;
- ServiceManager.addService(SERVICE_NAME, asBinder());
+ ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, asBinder());
mUidPolicy = new SparseIntArray();
mUidForeground = new SparseBooleanArray();
diff --git a/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java b/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java
index f20d5e5..ca33d32 100644
--- a/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java
@@ -42,6 +42,7 @@ import android.os.ServiceManager;
import android.os.SystemClock;
import android.provider.Settings;
import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.Suppress;
import android.text.format.DateUtils;
import android.util.Log;
@@ -54,6 +55,7 @@ import java.util.concurrent.Future;
/**
* Tests for {@link ThrottleService}.
*/
+@LargeTest
public class ThrottleServiceTest extends AndroidTestCase {
private static final String TAG = "ThrottleServiceTest";