diff options
author | Jeff Sharkey <jsharkey@android.com> | 2011-05-17 14:55:15 -0700 |
---|---|---|
committer | Jeff Sharkey <jsharkey@android.com> | 2011-05-21 15:02:58 -0700 |
commit | eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3 (patch) | |
tree | 2753882abd3cd277dce4c30a1d6a59172f2c6f46 /services | |
parent | 850ae9acda0d062f9a1836d159bdce819e0f8066 (diff) | |
download | frameworks_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')
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"; |