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