diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/net/TrafficStats.java | 230 | ||||
-rw-r--r-- | core/jni/android_net_TrafficStats.cpp | 219 | ||||
-rw-r--r-- | core/tests/benchmarks/src/android/net/TrafficStatsBenchmark.java | 39 |
3 files changed, 191 insertions, 297 deletions
diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java index a014cec..a282910 100644 --- a/core/java/android/net/TrafficStats.java +++ b/core/java/android/net/TrafficStats.java @@ -424,161 +424,156 @@ public class TrafficStats { } /** - * Get the number of bytes sent through the network for this UID. - * The statistics are across all interfaces. - * - * {@see android.os.Process#myUid()}. + * Return number of bytes transmitted by the given UID since device boot. + * Counts packets across all network interfaces, and always increases + * monotonically since device boot. Statistics are measured at the network + * layer, so they include both TCP and UDP usage. + * <p> + * Before {@link android.os.Build.VERSION_CODES#K}, this may return + * {@link #UNSUPPORTED} on devices where statistics aren't available. * - * @param uid The UID of the process to examine. - * @return number of bytes. If the statistics are not supported by this device, - * {@link #UNSUPPORTED} will be returned. + * @see android.os.Process#myUid() + * @see android.content.pm.ApplicationInfo#uid */ - public static native long getUidTxBytes(int uid); + public static long getUidTxBytes(int uid) { + return nativeGetUidStat(uid, TYPE_TX_BYTES); + } /** - * Get the number of bytes received through the network for this UID. - * The statistics are across all interfaces. - * - * {@see android.os.Process#myUid()}. + * Return number of bytes received by the given UID since device boot. + * Counts packets across all network interfaces, and always increases + * monotonically since device boot. Statistics are measured at the network + * layer, so they include both TCP and UDP usage. + * <p> + * Before {@link android.os.Build.VERSION_CODES#K}, this may return + * {@link #UNSUPPORTED} on devices where statistics aren't available. * - * @param uid The UID of the process to examine. - * @return number of bytes + * @see android.os.Process#myUid() + * @see android.content.pm.ApplicationInfo#uid */ - public static native long getUidRxBytes(int uid); + public static long getUidRxBytes(int uid) { + return nativeGetUidStat(uid, TYPE_RX_BYTES); + } /** - * Get the number of packets (TCP segments + UDP) sent through - * the network for this UID. - * The statistics are across all interfaces. - * - * {@see android.os.Process#myUid()}. + * Return number of packets transmitted by the given UID since device boot. + * Counts packets across all network interfaces, and always increases + * monotonically since device boot. Statistics are measured at the network + * layer, so they include both TCP and UDP usage. + * <p> + * Before {@link android.os.Build.VERSION_CODES#K}, this may return + * {@link #UNSUPPORTED} on devices where statistics aren't available. * - * @param uid The UID of the process to examine. - * @return number of packets. - * If the statistics are not supported by this device, - * {@link #UNSUPPORTED} will be returned. + * @see android.os.Process#myUid() + * @see android.content.pm.ApplicationInfo#uid */ - public static native long getUidTxPackets(int uid); + public static long getUidTxPackets(int uid) { + return nativeGetUidStat(uid, TYPE_TX_PACKETS); + } /** - * Get the number of packets (TCP segments + UDP) received through - * the network for this UID. - * The statistics are across all interfaces. - * - * {@see android.os.Process#myUid()}. + * Return number of packets received by the given UID since device boot. + * Counts packets across all network interfaces, and always increases + * monotonically since device boot. Statistics are measured at the network + * layer, so they include both TCP and UDP usage. + * <p> + * Before {@link android.os.Build.VERSION_CODES#K}, this may return + * {@link #UNSUPPORTED} on devices where statistics aren't available. * - * @param uid The UID of the process to examine. - * @return number of packets + * @see android.os.Process#myUid() + * @see android.content.pm.ApplicationInfo#uid */ - public static native long getUidRxPackets(int uid); + public static long getUidRxPackets(int uid) { + return nativeGetUidStat(uid, TYPE_RX_PACKETS); + } /** - * Get the number of TCP payload bytes sent for this UID. - * This total does not include protocol and control overheads at - * the transport and the lower layers of the networking stack. - * The statistics are across all interfaces. - * - * {@see android.os.Process#myUid()}. - * - * @param uid The UID of the process to examine. - * @return number of bytes. If the statistics are not supported by this device, - * {@link #UNSUPPORTED} will be returned. + * @deprecated Starting in {@link android.os.Build.VERSION_CODES#K}, + * transport layer statistics are no longer available, and will + * always return {@link #UNSUPPORTED}. + * @see #getUidTxBytes(int) */ - public static native long getUidTcpTxBytes(int uid); + @Deprecated + public static long getUidTcpTxBytes(int uid) { + return UNSUPPORTED; + } /** - * Get the number of TCP payload bytes received for this UID. - * This total does not include protocol and control overheads at - * the transport and the lower layers of the networking stack. - * The statistics are across all interfaces. - * - * {@see android.os.Process#myUid()}. - * - * @param uid The UID of the process to examine. - * @return number of bytes. If the statistics are not supported by this device, - * {@link #UNSUPPORTED} will be returned. + * @deprecated Starting in {@link android.os.Build.VERSION_CODES#K}, + * transport layer statistics are no longer available, and will + * always return {@link #UNSUPPORTED}. + * @see #getUidRxBytes(int) */ - public static native long getUidTcpRxBytes(int uid); + @Deprecated + public static long getUidTcpRxBytes(int uid) { + return UNSUPPORTED; + } /** - * Get the number of UDP payload bytes sent for this UID. - * This total does not include protocol and control overheads at - * the transport and the lower layers of the networking stack. - * The statistics are across all interfaces. - * - * {@see android.os.Process#myUid()}. - * - * @param uid The UID of the process to examine. - * @return number of bytes. If the statistics are not supported by this device, - * {@link #UNSUPPORTED} will be returned. + * @deprecated Starting in {@link android.os.Build.VERSION_CODES#K}, + * transport layer statistics are no longer available, and will + * always return {@link #UNSUPPORTED}. + * @see #getUidTxBytes(int) */ - public static native long getUidUdpTxBytes(int uid); + @Deprecated + public static long getUidUdpTxBytes(int uid) { + return UNSUPPORTED; + } /** - * Get the number of UDP payload bytes received for this UID. - * This total does not include protocol and control overheads at - * the transport and the lower layers of the networking stack. - * The statistics are across all interfaces. - * - * {@see android.os.Process#myUid()}. - * - * @param uid The UID of the process to examine. - * @return number of bytes. If the statistics are not supported by this device, - * {@link #UNSUPPORTED} will be returned. + * @deprecated Starting in {@link android.os.Build.VERSION_CODES#K}, + * transport layer statistics are no longer available, and will + * always return {@link #UNSUPPORTED}. + * @see #getUidRxBytes(int) */ - public static native long getUidUdpRxBytes(int uid); + @Deprecated + public static long getUidUdpRxBytes(int uid) { + return UNSUPPORTED; + } /** - * Get the number of TCP segments sent for this UID. - * Does not include TCP control packets (SYN/ACKs/FIN/..). - * The statistics are across all interfaces. - * - * {@see android.os.Process#myUid()}. - * - * @param uid The UID of the process to examine. - * @return number of TCP segments. If the statistics are not supported by this device, - * {@link #UNSUPPORTED} will be returned. + * @deprecated Starting in {@link android.os.Build.VERSION_CODES#K}, + * transport layer statistics are no longer available, and will + * always return {@link #UNSUPPORTED}. + * @see #getUidTxPackets(int) */ - public static native long getUidTcpTxSegments(int uid); + @Deprecated + public static long getUidTcpTxSegments(int uid) { + return UNSUPPORTED; + } /** - * Get the number of TCP segments received for this UID. - * Does not include TCP control packets (SYN/ACKs/FIN/..). - * The statistics are across all interfaces. - * - * {@see android.os.Process#myUid()}. - * - * @param uid The UID of the process to examine. - * @return number of TCP segments. If the statistics are not supported by this device, - * {@link #UNSUPPORTED} will be returned. + * @deprecated Starting in {@link android.os.Build.VERSION_CODES#K}, + * transport layer statistics are no longer available, and will + * always return {@link #UNSUPPORTED}. + * @see #getUidRxPackets(int) */ - public static native long getUidTcpRxSegments(int uid); + @Deprecated + public static long getUidTcpRxSegments(int uid) { + return UNSUPPORTED; + } /** - * Get the number of UDP packets sent for this UID. - * Includes DNS requests. - * The statistics are across all interfaces. - * - * {@see android.os.Process#myUid()}. - * - * @param uid The UID of the process to examine. - * @return number of packets. If the statistics are not supported by this device, - * {@link #UNSUPPORTED} will be returned. + * @deprecated Starting in {@link android.os.Build.VERSION_CODES#K}, + * transport layer statistics are no longer available, and will + * always return {@link #UNSUPPORTED}. + * @see #getUidTxPackets(int) */ - public static native long getUidUdpTxPackets(int uid); + @Deprecated + public static long getUidUdpTxPackets(int uid) { + return UNSUPPORTED; + } /** - * Get the number of UDP packets received for this UID. - * Includes DNS responses. - * The statistics are across all interfaces. - * - * {@see android.os.Process#myUid()}. - * - * @param uid The UID of the process to examine. - * @return number of packets. If the statistics are not supported by this device, - * {@link #UNSUPPORTED} will be returned. + * @deprecated Starting in {@link android.os.Build.VERSION_CODES#K}, + * transport layer statistics are no longer available, and will + * always return {@link #UNSUPPORTED}. + * @see #getUidRxPackets(int) */ - public static native long getUidUdpRxPackets(int uid); + @Deprecated + public static long getUidUdpRxPackets(int uid) { + return UNSUPPORTED; + } /** * Return detailed {@link NetworkStats} for the current UID. Requires no @@ -616,4 +611,5 @@ public class TrafficStats { private static native long nativeGetTotalStat(int type); private static native long nativeGetIfaceStat(String iface, int type); + private static native long nativeGetUidStat(int uid, int type); } diff --git a/core/jni/android_net_TrafficStats.cpp b/core/jni/android_net_TrafficStats.cpp index aa8a58b..bf963de 100644 --- a/core/jni/android_net_TrafficStats.cpp +++ b/core/jni/android_net_TrafficStats.cpp @@ -32,17 +32,7 @@ namespace android { static const char* QTAGUID_IFACE_STATS = "/proc/net/xt_qtaguid/iface_stat_fmt"; - -enum Tx_Rx { - TX, - RX -}; - -enum Tcp_Udp { - TCP, - UDP, - TCP_AND_UDP -}; +static const char* QTAGUID_UID_STATS = "/proc/net/xt_qtaguid/stats"; // NOTE: keep these in sync with TrafficStats.java static const uint64_t UNKNOWN = -1; @@ -84,27 +74,6 @@ static uint64_t getStatsType(struct Stats* stats, StatsType type) { } } -// Returns an ASCII decimal number read from the specified file, -1 on error. -static jlong readNumber(char const* filename) { - char buf[80]; - int fd = open(filename, O_RDONLY); - if (fd < 0) { - if (errno != ENOENT) ALOGE("Can't open %s: %s", filename, strerror(errno)); - return -1; - } - - int len = read(fd, buf, sizeof(buf) - 1); - if (len < 0) { - ALOGE("Can't read %s: %s", filename, strerror(errno)); - close(fd); - return -1; - } - - close(fd); - buf[len] = '\0'; - return atoll(buf); -} - static int parseIfaceStats(const char* iface, struct Stats* stats) { FILE *fp = fopen(QTAGUID_IFACE_STATS, "r"); if (fp == NULL) { @@ -149,6 +118,36 @@ static int parseIfaceStats(const char* iface, struct Stats* stats) { return 0; } +static int parseUidStats(const uint32_t uid, struct Stats* stats) { + FILE *fp = fopen(QTAGUID_UID_STATS, "r"); + if (fp == NULL) { + return -1; + } + + char buffer[256]; + char iface[32]; + uint32_t idx, cur_uid, set; + uint64_t tag, rxBytes, rxPackets, txBytes, txPackets; + + while (fgets(buffer, 256, fp) != NULL) { + if (sscanf(buffer, "%d %31s 0x%llx %u %u %llu %llu %llu %llu", &idx, + iface, &tag, &cur_uid, &set, &rxBytes, &rxPackets, &txBytes, + &txPackets) == 9) { + if (uid == cur_uid && tag == 0L) { + stats->rxBytes += rxBytes; + stats->rxPackets += rxPackets; + stats->txBytes += txBytes; + stats->txPackets += txPackets; + } + } + } + + if (fclose(fp) != 0) { + return -1; + } + return 0; +} + static jlong getTotalStat(JNIEnv* env, jclass clazz, jint type) { struct Stats stats; memset(&stats, 0, sizeof(Stats)); @@ -174,160 +173,20 @@ static jlong getIfaceStat(JNIEnv* env, jclass clazz, jstring iface, jint type) { } } - -// Per-UID stats require reading from a constructed filename. - -static jlong getUidBytes(JNIEnv* env, jobject clazz, jint uid, - enum Tx_Rx tx_or_rx, enum Tcp_Udp tcp_or_udp) { - char tcp_filename[80], udp_filename[80]; - jlong tcp_bytes = -1, udp_bytes = -1, total_bytes = -1; - - switch (tx_or_rx) { - case TX: - sprintf(tcp_filename, "/proc/uid_stat/%d/tcp_snd", uid); - sprintf(udp_filename, "/proc/uid_stat/%d/udp_snd", uid); - break; - case RX: - sprintf(tcp_filename, "/proc/uid_stat/%d/tcp_rcv", uid); - sprintf(udp_filename, "/proc/uid_stat/%d/udp_rcv", uid); - break; - default: - return -1; - } - - switch (tcp_or_udp) { - case TCP: - tcp_bytes = readNumber(tcp_filename); - total_bytes = (tcp_bytes >= 0) ? tcp_bytes : -1; - break; - case UDP: - udp_bytes = readNumber(udp_filename); - total_bytes = (udp_bytes >= 0) ? udp_bytes : -1; - break; - case TCP_AND_UDP: - tcp_bytes = readNumber(tcp_filename); - total_bytes += (tcp_bytes >= 0 ? tcp_bytes : 0); - - udp_bytes = readNumber(udp_filename); - total_bytes += (udp_bytes >= 0 ? udp_bytes : 0); - break; - default: - return -1; - } - - return total_bytes; -} - -static jlong getUidPkts(JNIEnv* env, jobject clazz, jint uid, - enum Tx_Rx tx_or_rx, enum Tcp_Udp tcp_or_udp) { - char tcp_filename[80], udp_filename[80]; - jlong tcp_pkts = -1, udp_pkts = -1, total_pkts = -1; - - switch (tx_or_rx) { - case TX: - sprintf(tcp_filename, "/proc/uid_stat/%d/tcp_snd_pkt", uid); - sprintf(udp_filename, "/proc/uid_stat/%d/udp_snd_pkt", uid); - break; - case RX: - sprintf(tcp_filename, "/proc/uid_stat/%d/tcp_rcv_pkt", uid); - sprintf(udp_filename, "/proc/uid_stat/%d/udp_rcv_pkt", uid); - break; - default: - return -1; - } - - switch (tcp_or_udp) { - case TCP: - tcp_pkts = readNumber(tcp_filename); - total_pkts = (tcp_pkts >= 0) ? tcp_pkts : -1; - break; - case UDP: - udp_pkts = readNumber(udp_filename); - total_pkts = (udp_pkts >= 0) ? udp_pkts : -1; - break; - case TCP_AND_UDP: - tcp_pkts = readNumber(tcp_filename); - total_pkts += (tcp_pkts >= 0 ? tcp_pkts : 0); - - udp_pkts = readNumber(udp_filename); - total_pkts += (udp_pkts >= 0 ? udp_pkts : 0); - break; - default: - return -1; +static jlong getUidStat(JNIEnv* env, jclass clazz, jint uid, jint type) { + struct Stats stats; + memset(&stats, 0, sizeof(Stats)); + if (parseUidStats(uid, &stats) == 0) { + return getStatsType(&stats, (StatsType) type); + } else { + return UNKNOWN; } - - return total_pkts; -} - -static jlong getUidRxBytes(JNIEnv* env, jobject clazz, jint uid) { - return getUidBytes(env, clazz, uid, RX, TCP_AND_UDP); -} - -static jlong getUidTxBytes(JNIEnv* env, jobject clazz, jint uid) { - return getUidBytes(env, clazz, uid, TX, TCP_AND_UDP); -} - -/* TCP Segments + UDP Packets */ -static jlong getUidTxPackets(JNIEnv* env, jobject clazz, jint uid) { - return getUidPkts(env, clazz, uid, TX, TCP_AND_UDP); -} - -/* TCP Segments + UDP Packets */ -static jlong getUidRxPackets(JNIEnv* env, jobject clazz, jint uid) { - return getUidPkts(env, clazz, uid, RX, TCP_AND_UDP); -} - -static jlong getUidTcpTxBytes(JNIEnv* env, jobject clazz, jint uid) { - return getUidBytes(env, clazz, uid, TX, TCP); -} - -static jlong getUidTcpRxBytes(JNIEnv* env, jobject clazz, jint uid) { - return getUidBytes(env, clazz, uid, RX, TCP); -} - -static jlong getUidUdpTxBytes(JNIEnv* env, jobject clazz, jint uid) { - return getUidBytes(env, clazz, uid, TX, UDP); -} - -static jlong getUidUdpRxBytes(JNIEnv* env, jobject clazz, jint uid) { - return getUidBytes(env, clazz, uid, RX, UDP); -} - -static jlong getUidTcpTxSegments(JNIEnv* env, jobject clazz, jint uid) { - return getUidPkts(env, clazz, uid, TX, TCP); -} - -static jlong getUidTcpRxSegments(JNIEnv* env, jobject clazz, jint uid) { - return getUidPkts(env, clazz, uid, RX, TCP); -} - -static jlong getUidUdpTxPackets(JNIEnv* env, jobject clazz, jint uid) { - return getUidPkts(env, clazz, uid, TX, UDP); -} - -static jlong getUidUdpRxPackets(JNIEnv* env, jobject clazz, jint uid) { - return getUidPkts(env, clazz, uid, RX, UDP); } static JNINativeMethod gMethods[] = { {"nativeGetTotalStat", "(I)J", (void*) getTotalStat}, {"nativeGetIfaceStat", "(Ljava/lang/String;I)J", (void*) getIfaceStat}, - - /* Per-UID Stats */ - {"getUidTxBytes", "(I)J", (void*) getUidTxBytes}, - {"getUidRxBytes", "(I)J", (void*) getUidRxBytes}, - {"getUidTxPackets", "(I)J", (void*) getUidTxPackets}, - {"getUidRxPackets", "(I)J", (void*) getUidRxPackets}, - - {"getUidTcpTxBytes", "(I)J", (void*) getUidTcpTxBytes}, - {"getUidTcpRxBytes", "(I)J", (void*) getUidTcpRxBytes}, - {"getUidUdpTxBytes", "(I)J", (void*) getUidUdpTxBytes}, - {"getUidUdpRxBytes", "(I)J", (void*) getUidUdpRxBytes}, - - {"getUidTcpTxSegments", "(I)J", (void*) getUidTcpTxSegments}, - {"getUidTcpRxSegments", "(I)J", (void*) getUidTcpRxSegments}, - {"getUidUdpTxPackets", "(I)J", (void*) getUidUdpTxPackets}, - {"getUidUdpRxPackets", "(I)J", (void*) getUidUdpRxPackets}, + {"nativeGetUidStat", "(II)J", (void*) getUidStat}, }; int register_android_net_TrafficStats(JNIEnv* env) { diff --git a/core/tests/benchmarks/src/android/net/TrafficStatsBenchmark.java b/core/tests/benchmarks/src/android/net/TrafficStatsBenchmark.java new file mode 100644 index 0000000..5a29adc --- /dev/null +++ b/core/tests/benchmarks/src/android/net/TrafficStatsBenchmark.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net; + +import com.google.caliper.SimpleBenchmark; + +public class TrafficStatsBenchmark extends SimpleBenchmark { + public void timeGetUidRxBytes(int reps) { + for (int i = 0; i < reps; i++) { + TrafficStats.getUidRxBytes(android.os.Process.myUid()); + } + } + + public void timeGetMobileRxBytes(int reps) { + for (int i = 0; i < reps; i++) { + TrafficStats.getMobileRxBytes(); + } + } + + public void timeGetTotalRxBytes(int reps) { + for (int i = 0; i < reps; i++) { + TrafficStats.getTotalRxBytes(); + } + } +} |