android_net_TrafficStats.cpp revision 234766a36af6214644fa8205202287084ca9cf93
12b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor/*
22b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor * Copyright (C) 2010 The Android Open Source Project
32b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor *
42b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor * Licensed under the Apache License, Version 2.0 (the "License");
52b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor * you may not use this file except in compliance with the License.
62b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor * You may obtain a copy of the License at
72b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor *
82b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor *      http://www.apache.org/licenses/LICENSE-2.0
92b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor *
102b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor * Unless required by applicable law or agreed to in writing, software
112b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor * distributed under the License is distributed on an "AS IS" BASIS,
122b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor * See the License for the specific language governing permissions and
142b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor * limitations under the License.
152b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor */
162b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor
172b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor#define LOG_TAG "TrafficStats"
182b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor
192b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor#include <dirent.h>
202b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor#include <errno.h>
212b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor#include <fcntl.h>
222b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor#include <sys/stat.h>
232b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor#include <sys/types.h>
242b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor
252b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor#include <android_runtime/AndroidRuntime.h>
262b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor#include <cutils/logger.h>
272b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor#include <jni.h>
28f17b971a75577a3a0e5ab574618e0756d167f5d4Elliott Hughes#include <ScopedUtfChars.h>
292b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor#include <utils/misc.h>
302b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor#include <utils/Log.h>
312b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor
322b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnornamespace android {
332b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor
34234766a36af6214644fa8205202287084ca9cf93Jeff Sharkeystatic const uint64_t VALUE_UNKNOWN = -1;
35234766a36af6214644fa8205202287084ca9cf93Jeff Sharkeystatic const char* IFACE_STAT_ALL = "/proc/net/xt_qtaguid/iface_stat_all";
36234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey
37c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmaenum Tx_Rx {
38c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    TX,
39c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    RX
40c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma};
41c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
42c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmaenum Tcp_Udp {
43c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    TCP,
44c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    UDP,
45c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    TCP_AND_UDP
46c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma};
47c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
48234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey// NOTE: keep these in sync with TrafficStats.java
49234766a36af6214644fa8205202287084ca9cf93Jeff Sharkeyenum IfaceStatType {
50234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    RX_BYTES = 0,
51234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    RX_PACKETS = 1,
52234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    TX_BYTES = 2,
53234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    TX_PACKETS = 3
54234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey};
55234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey
56234766a36af6214644fa8205202287084ca9cf93Jeff Sharkeystruct IfaceStat {
57234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    uint64_t rxBytes;
58234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    uint64_t rxPackets;
59234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    uint64_t txBytes;
60234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    uint64_t txPackets;
61234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey};
62234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey
632b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor// Returns an ASCII decimal number read from the specified file, -1 on error.
642b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnorstatic jlong readNumber(char const* filename) {
652b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor    char buf[80];
662b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor    int fd = open(filename, O_RDONLY);
672b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor    if (fd < 0) {
683762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        if (errno != ENOENT) ALOGE("Can't open %s: %s", filename, strerror(errno));
692b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor        return -1;
702b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor    }
712b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor
722b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor    int len = read(fd, buf, sizeof(buf) - 1);
732b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor    if (len < 0) {
743762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't read %s: %s", filename, strerror(errno));
752b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor        close(fd);
762b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor        return -1;
772b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor    }
782b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor
792b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor    close(fd);
802b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor    buf[len] = '\0';
812b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor    return atoll(buf);
822b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor}
832b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor
84234766a36af6214644fa8205202287084ca9cf93Jeff Sharkeystatic int parseIfaceStat(const char* iface, struct IfaceStat* stat) {
85234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    FILE *fp = fopen(IFACE_STAT_ALL, "r");
86234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    if (!fp) {
87234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        return errno;
8864ba5eaa40614877c679b3fbaaa3c2efd17d50d2Kazuhiro Ondo    }
8964ba5eaa40614877c679b3fbaaa3c2efd17d50d2Kazuhiro Ondo
90234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    char buffer[256];
91234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    char cur_iface[32];
92234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    int active;
93234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    uint64_t rxBytes, rxPackets, txBytes, txPackets, devRxBytes, devRxPackets, devTxBytes,
94234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            devTxPackets;
95234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey
96234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    while (fgets(buffer, 256, fp) != NULL) {
97234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        if (sscanf(buffer, "%31s %d %llu %llu %llu %llu %llu %llu %llu %llu", cur_iface, &active,
98234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                   &rxBytes, &rxPackets, &txBytes, &txPackets, &devRxBytes, &devRxPackets,
99234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                   &devTxBytes, &devTxPackets) != 10) {
100234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            continue;
101234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        }
1022b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor
103234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        if (!iface || !strcmp(iface, cur_iface)) {
104234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            stat->rxBytes += rxBytes;
105234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            stat->rxPackets += rxPackets;
106234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            stat->txBytes += txBytes;
107234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            stat->txPackets += txPackets;
108234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey
109234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            if (active) {
110234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                stat->rxBytes += devRxBytes;
111234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                stat->rxPackets += devRxPackets;
112234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                stat->txBytes += devTxBytes;
113234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                stat->txPackets += devTxPackets;
114234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            }
1152b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor        }
1162b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor    }
1172b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor
118234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    fclose(fp);
119234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    return 0;
1202b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor}
1212b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor
122234766a36af6214644fa8205202287084ca9cf93Jeff Sharkeystatic uint64_t getIfaceStatType(const char* iface, IfaceStatType type) {
123234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    struct IfaceStat stat;
124234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    memset(&stat, 0, sizeof(IfaceStat));
1252b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor
126234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    if (parseIfaceStat(iface, &stat)) {
127234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        return VALUE_UNKNOWN;
128f17b971a75577a3a0e5ab574618e0756d167f5d4Elliott Hughes    }
129227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff
130234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    switch (type) {
131234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        case RX_BYTES:
132234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            return stat.rxBytes;
133234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        case RX_PACKETS:
134234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            return stat.rxPackets;
135234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        case TX_BYTES:
136234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            return stat.txBytes;
137234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        case TX_PACKETS:
138234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            return stat.txPackets;
139234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        default:
140234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            return VALUE_UNKNOWN;
141234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    }
1422b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor}
1432b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor
144234766a36af6214644fa8205202287084ca9cf93Jeff Sharkeystatic jlong getTotalStat(JNIEnv* env, jclass clazz, jint type) {
145234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    return getIfaceStatType(NULL, (IfaceStatType) type);
1462b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor}
1472b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor
148234766a36af6214644fa8205202287084ca9cf93Jeff Sharkeystatic jlong getIfaceStat(JNIEnv* env, jclass clazz, jstring iface, jint type) {
149234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    struct IfaceStat stat;
150234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    const char* ifaceChars = env->GetStringUTFChars(iface, NULL);
151234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    if (ifaceChars) {
152234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        uint64_t stat = getIfaceStatType(ifaceChars, (IfaceStatType) type);
153234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        env->ReleaseStringUTFChars(iface, ifaceChars);
154234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        return stat;
155234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    } else {
156234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        return VALUE_UNKNOWN;
157234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    }
1582b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor}
1592b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor
1602b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor
1612b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor// Per-UID stats require reading from a constructed filename.
1622b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor
163c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidBytes(JNIEnv* env, jobject clazz, jint uid,
164c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma                         enum Tx_Rx tx_or_rx, enum Tcp_Udp tcp_or_udp) {
165c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    char tcp_filename[80], udp_filename[80];
166c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    jlong tcp_bytes = -1, udp_bytes = -1, total_bytes = -1;
167c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
168c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    switch (tx_or_rx) {
169c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma        case TX:
170c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            sprintf(tcp_filename, "/proc/uid_stat/%d/tcp_snd", uid);
171c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            sprintf(udp_filename, "/proc/uid_stat/%d/udp_snd", uid);
172c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            break;
173c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma        case RX:
174c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            sprintf(tcp_filename, "/proc/uid_stat/%d/tcp_rcv", uid);
175c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            sprintf(udp_filename, "/proc/uid_stat/%d/udp_rcv", uid);
176c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            break;
177c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma        default:
178c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            return -1;
179c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    }
180c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
181c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    switch (tcp_or_udp) {
182c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma        case TCP:
183c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            tcp_bytes = readNumber(tcp_filename);
184c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            total_bytes = (tcp_bytes >= 0) ? tcp_bytes : -1;
185c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            break;
186c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma        case UDP:
187c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            udp_bytes = readNumber(udp_filename);
188c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            total_bytes = (udp_bytes >= 0) ? udp_bytes : -1;
189c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            break;
190c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma        case TCP_AND_UDP:
191c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            tcp_bytes = readNumber(tcp_filename);
192c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            total_bytes += (tcp_bytes >= 0 ? tcp_bytes : 0);
193c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
194c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            udp_bytes = readNumber(udp_filename);
195c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            total_bytes += (udp_bytes >= 0 ? udp_bytes : 0);
196c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            break;
197c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma        default:
198c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            return -1;
199c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    }
200c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
201c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    return total_bytes;
202c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma}
203c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
204c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidPkts(JNIEnv* env, jobject clazz, jint uid,
205c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma                         enum Tx_Rx tx_or_rx, enum Tcp_Udp tcp_or_udp) {
206c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    char tcp_filename[80], udp_filename[80];
207c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    jlong tcp_pkts = -1, udp_pkts = -1, total_pkts = -1;
208c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
209c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    switch (tx_or_rx) {
210c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma        case TX:
211c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            sprintf(tcp_filename, "/proc/uid_stat/%d/tcp_snd_pkt", uid);
212c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            sprintf(udp_filename, "/proc/uid_stat/%d/udp_snd_pkt", uid);
213c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            break;
214c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma        case RX:
215c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            sprintf(tcp_filename, "/proc/uid_stat/%d/tcp_rcv_pkt", uid);
216c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            sprintf(udp_filename, "/proc/uid_stat/%d/udp_rcv_pkt", uid);
217c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            break;
218c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma        default:
219c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            return -1;
220c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    }
221c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
222c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    switch (tcp_or_udp) {
223c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma        case TCP:
224c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            tcp_pkts = readNumber(tcp_filename);
225c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            total_pkts = (tcp_pkts >= 0) ? tcp_pkts : -1;
226c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            break;
227c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma        case UDP:
228c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            udp_pkts = readNumber(udp_filename);
229c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            total_pkts = (udp_pkts >= 0) ? udp_pkts : -1;
230c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            break;
231c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma        case TCP_AND_UDP:
232c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            tcp_pkts = readNumber(tcp_filename);
233c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            total_pkts += (tcp_pkts >= 0 ? tcp_pkts : 0);
234c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
235c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            udp_pkts = readNumber(udp_filename);
236c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            total_pkts += (udp_pkts >= 0 ? udp_pkts : 0);
237c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            break;
238c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma        default:
239c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma            return -1;
240c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    }
241c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
242c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    return total_pkts;
243c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma}
244c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
2452b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnorstatic jlong getUidRxBytes(JNIEnv* env, jobject clazz, jint uid) {
246c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    return getUidBytes(env, clazz, uid, RX, TCP_AND_UDP);
2472b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor}
2482b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor
2492b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnorstatic jlong getUidTxBytes(JNIEnv* env, jobject clazz, jint uid) {
250c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    return getUidBytes(env, clazz, uid, TX, TCP_AND_UDP);
251c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma}
252c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
253c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma/* TCP Segments + UDP Packets */
254c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidTxPackets(JNIEnv* env, jobject clazz, jint uid) {
255c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    return getUidPkts(env, clazz, uid, TX, TCP_AND_UDP);
256c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma}
257c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
258c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma/* TCP Segments + UDP Packets */
259c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidRxPackets(JNIEnv* env, jobject clazz, jint uid) {
260c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    return getUidPkts(env, clazz, uid, RX, TCP_AND_UDP);
261c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma}
262c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
263c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidTcpTxBytes(JNIEnv* env, jobject clazz, jint uid) {
264c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    return getUidBytes(env, clazz, uid, TX, TCP);
265c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma}
266c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
267c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidTcpRxBytes(JNIEnv* env, jobject clazz, jint uid) {
268c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    return getUidBytes(env, clazz, uid, RX, TCP);
269c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma}
270c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
271c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidUdpTxBytes(JNIEnv* env, jobject clazz, jint uid) {
272c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    return getUidBytes(env, clazz, uid, TX, UDP);
273c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma}
274c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
275c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidUdpRxBytes(JNIEnv* env, jobject clazz, jint uid) {
276c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    return getUidBytes(env, clazz, uid, RX, UDP);
277c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma}
278c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
279c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidTcpTxSegments(JNIEnv* env, jobject clazz, jint uid) {
280c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    return getUidPkts(env, clazz, uid, TX, TCP);
281c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma}
282c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
283c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidTcpRxSegments(JNIEnv* env, jobject clazz, jint uid) {
284c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    return getUidPkts(env, clazz, uid, RX, TCP);
285c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma}
286c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
287c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidUdpTxPackets(JNIEnv* env, jobject clazz, jint uid) {
288c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    return getUidPkts(env, clazz, uid, TX, UDP);
289c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma}
290c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
291c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidUdpRxPackets(JNIEnv* env, jobject clazz, jint uid) {
292c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    return getUidPkts(env, clazz, uid, RX, UDP);
2932b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor}
2942b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor
2952b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnorstatic JNINativeMethod gMethods[] = {
296234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    {"nativeGetTotalStat", "(I)J", (void*) getTotalStat},
297234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    {"nativeGetIfaceStat", "(Ljava/lang/String;I)J", (void*) getIfaceStat},
298c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
299c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    /* Per-UID Stats */
3002b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor    {"getUidTxBytes", "(I)J", (void*) getUidTxBytes},
3012b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor    {"getUidRxBytes", "(I)J", (void*) getUidRxBytes},
302c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    {"getUidTxPackets", "(I)J", (void*) getUidTxPackets},
303c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    {"getUidRxPackets", "(I)J", (void*) getUidRxPackets},
304c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
305c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    {"getUidTcpTxBytes", "(I)J", (void*) getUidTcpTxBytes},
306c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    {"getUidTcpRxBytes", "(I)J", (void*) getUidTcpRxBytes},
307c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    {"getUidUdpTxBytes", "(I)J", (void*) getUidUdpTxBytes},
308c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    {"getUidUdpRxBytes", "(I)J", (void*) getUidUdpRxBytes},
309c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma
310c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    {"getUidTcpTxSegments", "(I)J", (void*) getUidTcpTxSegments},
311c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    {"getUidTcpRxSegments", "(I)J", (void*) getUidTcpRxSegments},
312c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    {"getUidUdpTxPackets", "(I)J", (void*) getUidUdpTxPackets},
313c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma    {"getUidUdpRxPackets", "(I)J", (void*) getUidUdpRxPackets},
3142b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor};
3152b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor
3162b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnorint register_android_net_TrafficStats(JNIEnv* env) {
3172b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor    return AndroidRuntime::registerNativeMethods(env, "android/net/TrafficStats",
3182b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor            gMethods, NELEM(gMethods));
3192b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor}
3202b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor
3212b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor}
322