android_net_TrafficStats.cpp revision 227bec49157bc496f7c9e8e8f63c12728a448922
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> 282b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor#include <utils/misc.h> 292b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor#include <utils/Log.h> 302b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 312b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnornamespace android { 322b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 33c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmaenum Tx_Rx { 34c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma TX, 35c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma RX 36c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma}; 37c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 38c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmaenum Tcp_Udp { 39c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma TCP, 40c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma UDP, 41c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma TCP_AND_UDP 42c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma}; 43c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 442b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor// Returns an ASCII decimal number read from the specified file, -1 on error. 452b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnorstatic jlong readNumber(char const* filename) { 464e8d8238e10d168b434dcdd2e779a9aab37f1e2cDan Egnor#ifdef HAVE_ANDROID_OS 472b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor char buf[80]; 482b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor int fd = open(filename, O_RDONLY); 492b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor if (fd < 0) { 502b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor if (errno != ENOENT) LOGE("Can't open %s: %s", filename, strerror(errno)); 512b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor return -1; 522b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor } 532b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 542b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor int len = read(fd, buf, sizeof(buf) - 1); 552b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor if (len < 0) { 562b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor LOGE("Can't read %s: %s", filename, strerror(errno)); 572b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor close(fd); 582b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor return -1; 592b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor } 602b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 612b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor close(fd); 622b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor buf[len] = '\0'; 632b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor return atoll(buf); 644e8d8238e10d168b434dcdd2e779a9aab37f1e2cDan Egnor#else // Simulator 654e8d8238e10d168b434dcdd2e779a9aab37f1e2cDan Egnor return -1; 664e8d8238e10d168b434dcdd2e779a9aab37f1e2cDan Egnor#endif 672b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor} 682b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 692b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor// Return the number from the first file which exists and contains data 702b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnorstatic jlong tryBoth(char const* a, char const* b) { 712b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor jlong num = readNumber(a); 722b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor return num >= 0 ? num : readNumber(b); 732b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor} 742b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 752b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor// Returns the sum of numbers from the specified path under /sys/class/net/*, 762b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor// -1 if no such file exists. 772b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnorstatic jlong readTotal(char const* suffix) { 784e8d8238e10d168b434dcdd2e779a9aab37f1e2cDan Egnor#ifdef HAVE_ANDROID_OS 792b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor char filename[PATH_MAX] = "/sys/class/net/"; 802b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor DIR *dir = opendir(filename); 812b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor if (dir == NULL) { 822b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor LOGE("Can't list %s: %s", filename, strerror(errno)); 832b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor return -1; 842b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor } 852b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 862b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor int len = strlen(filename); 872b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor jlong total = -1; 882b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor while (struct dirent *entry = readdir(dir)) { 892b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor // Skip ., .., and localhost interfaces. 902b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor if (entry->d_name[0] != '.' && strncmp(entry->d_name, "lo", 2) != 0) { 912b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor strlcpy(filename + len, entry->d_name, sizeof(filename) - len); 922b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor strlcat(filename, suffix, sizeof(filename)); 932b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor jlong num = readNumber(filename); 942b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor if (num >= 0) total = total < 0 ? num : total + num; 952b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor } 962b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor } 972b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 982b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor closedir(dir); 992b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor return total; 1004e8d8238e10d168b434dcdd2e779a9aab37f1e2cDan Egnor#else // Simulator 1014e8d8238e10d168b434dcdd2e779a9aab37f1e2cDan Egnor return -1; 1024e8d8238e10d168b434dcdd2e779a9aab37f1e2cDan Egnor#endif 1032b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor} 1042b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 1052b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor// Mobile stats get accessed a lot more often than total stats. 1062b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor// Note the individual files can come and go at runtime, so we check 1072b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor// each file every time (rather than caching which ones exist). 1082b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 1092b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnorstatic jlong getMobileTxPackets(JNIEnv* env, jobject clazz) { 1102b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor return tryBoth( 1112b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor "/sys/class/net/rmnet0/statistics/tx_packets", 1122b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor "/sys/class/net/ppp0/statistics/tx_packets"); 1132b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor} 1142b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 1152b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnorstatic jlong getMobileRxPackets(JNIEnv* env, jobject clazz) { 1162b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor return tryBoth( 1172b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor "/sys/class/net/rmnet0/statistics/rx_packets", 1182b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor "/sys/class/net/ppp0/statistics/rx_packets"); 1192b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor} 1202b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 1212b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnorstatic jlong getMobileTxBytes(JNIEnv* env, jobject clazz) { 1222b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor return tryBoth( 1232b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor "/sys/class/net/rmnet0/statistics/tx_bytes", 1242b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor "/sys/class/net/ppp0/statistics/tx_bytes"); 1252b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor} 1262b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 1272b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnorstatic jlong getMobileRxBytes(JNIEnv* env, jobject clazz) { 1282b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor return tryBoth( 1292b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor "/sys/class/net/rmnet0/statistics/rx_bytes", 1302b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor "/sys/class/net/ppp0/statistics/rx_bytes"); 1312b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor} 1322b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 133227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriffstatic jlong getData(JNIEnv* env, char *what, jstring interface) { 134227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff char filename[80]; 135227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff jboolean isCopy; 136227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 137227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff const char *interfaceStr = env->GetStringUTFChars(interface, &isCopy); 138227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff snprintf(filename, sizeof(filename), "/sys/class/net/%s/statistics/%s", interfaceStr, what); 139227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 140227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff return readNumber(filename); 141227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff} 142227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 143227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriffstatic jlong getTxPackets(JNIEnv* env, jobject clazz, jstring interface) { 144227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff return getData(env, "tx_packets", interface); 145227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff} 146227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 147227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriffstatic jlong getRxPackets(JNIEnv* env, jobject clazz, jstring interface) { 148227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff return getData(env, "rx_packets", interface); 149227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff} 150227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 151227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriffstatic jlong getTxBytes(JNIEnv* env, jobject clazz, jstring interface) { 152227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff return getData(env, "tx_bytes", interface); 153227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff} 154227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 155227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriffstatic jlong getRxBytes(JNIEnv* env, jobject clazz, jstring interface) { 156227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff return getData(env, "rx_bytes", interface); 157227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff} 158227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 159227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 1602b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor// Total stats are read less often, so we're willing to put up 1612b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor// with listing the directory and concatenating filenames. 1622b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 1632b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnorstatic jlong getTotalTxPackets(JNIEnv* env, jobject clazz) { 1642b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor return readTotal("/statistics/tx_packets"); 1652b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor} 1662b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 1672b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnorstatic jlong getTotalRxPackets(JNIEnv* env, jobject clazz) { 1682b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor return readTotal("/statistics/rx_packets"); 1692b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor} 1702b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 1712b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnorstatic jlong getTotalTxBytes(JNIEnv* env, jobject clazz) { 1722b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor return readTotal("/statistics/tx_bytes"); 1732b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor} 1742b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 1752b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnorstatic jlong getTotalRxBytes(JNIEnv* env, jobject clazz) { 1762b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor return readTotal("/statistics/rx_bytes"); 1772b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor} 1782b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 1792b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor// Per-UID stats require reading from a constructed filename. 1802b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 181c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidBytes(JNIEnv* env, jobject clazz, jint uid, 182c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma enum Tx_Rx tx_or_rx, enum Tcp_Udp tcp_or_udp) { 183c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma char tcp_filename[80], udp_filename[80]; 184c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma jlong tcp_bytes = -1, udp_bytes = -1, total_bytes = -1; 185c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 186c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma switch (tx_or_rx) { 187c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma case TX: 188c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma sprintf(tcp_filename, "/proc/uid_stat/%d/tcp_snd", uid); 189c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma sprintf(udp_filename, "/proc/uid_stat/%d/udp_snd", uid); 190c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma break; 191c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma case RX: 192c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma sprintf(tcp_filename, "/proc/uid_stat/%d/tcp_rcv", uid); 193c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma sprintf(udp_filename, "/proc/uid_stat/%d/udp_rcv", uid); 194c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma break; 195c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma default: 196c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma return -1; 197c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma } 198c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 199c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma switch (tcp_or_udp) { 200c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma case TCP: 201c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma tcp_bytes = readNumber(tcp_filename); 202c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma total_bytes = (tcp_bytes >= 0) ? tcp_bytes : -1; 203c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma break; 204c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma case UDP: 205c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma udp_bytes = readNumber(udp_filename); 206c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma total_bytes = (udp_bytes >= 0) ? udp_bytes : -1; 207c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma break; 208c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma case TCP_AND_UDP: 209c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma tcp_bytes = readNumber(tcp_filename); 210c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma total_bytes += (tcp_bytes >= 0 ? tcp_bytes : 0); 211c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 212c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma udp_bytes = readNumber(udp_filename); 213c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma total_bytes += (udp_bytes >= 0 ? udp_bytes : 0); 214c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma break; 215c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma default: 216c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma return -1; 217c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma } 218c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 219c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma return total_bytes; 220c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma} 221c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 222c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidPkts(JNIEnv* env, jobject clazz, jint uid, 223c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma enum Tx_Rx tx_or_rx, enum Tcp_Udp tcp_or_udp) { 224c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma char tcp_filename[80], udp_filename[80]; 225c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma jlong tcp_pkts = -1, udp_pkts = -1, total_pkts = -1; 226c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 227c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma switch (tx_or_rx) { 228c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma case TX: 229c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma sprintf(tcp_filename, "/proc/uid_stat/%d/tcp_snd_pkt", uid); 230c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma sprintf(udp_filename, "/proc/uid_stat/%d/udp_snd_pkt", uid); 231c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma break; 232c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma case RX: 233c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma sprintf(tcp_filename, "/proc/uid_stat/%d/tcp_rcv_pkt", uid); 234c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma sprintf(udp_filename, "/proc/uid_stat/%d/udp_rcv_pkt", uid); 235c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma break; 236c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma default: 237c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma return -1; 238c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma } 239c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 240c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma switch (tcp_or_udp) { 241c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma case TCP: 242c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma tcp_pkts = readNumber(tcp_filename); 243c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma total_pkts = (tcp_pkts >= 0) ? tcp_pkts : -1; 244c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma break; 245c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma case UDP: 246c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma udp_pkts = readNumber(udp_filename); 247c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma total_pkts = (udp_pkts >= 0) ? udp_pkts : -1; 248c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma break; 249c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma case TCP_AND_UDP: 250c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma tcp_pkts = readNumber(tcp_filename); 251c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma total_pkts += (tcp_pkts >= 0 ? tcp_pkts : 0); 252c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 253c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma udp_pkts = readNumber(udp_filename); 254c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma total_pkts += (udp_pkts >= 0 ? udp_pkts : 0); 255c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma break; 256c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma default: 257c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma return -1; 258c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma } 259c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 260c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma return total_pkts; 261c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma} 262c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 2632b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnorstatic jlong getUidRxBytes(JNIEnv* env, jobject clazz, jint uid) { 264c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma return getUidBytes(env, clazz, uid, RX, TCP_AND_UDP); 2652b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor} 2662b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 2672b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnorstatic jlong getUidTxBytes(JNIEnv* env, jobject clazz, jint uid) { 268c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma return getUidBytes(env, clazz, uid, TX, TCP_AND_UDP); 269c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma} 270c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 271c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma/* TCP Segments + UDP Packets */ 272c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidTxPackets(JNIEnv* env, jobject clazz, jint uid) { 273c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma return getUidPkts(env, clazz, uid, TX, TCP_AND_UDP); 274c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma} 275c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 276c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma/* TCP Segments + UDP Packets */ 277c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidRxPackets(JNIEnv* env, jobject clazz, jint uid) { 278c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma return getUidPkts(env, clazz, uid, RX, TCP_AND_UDP); 279c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma} 280c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 281c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidTcpTxBytes(JNIEnv* env, jobject clazz, jint uid) { 282c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma return getUidBytes(env, clazz, uid, TX, TCP); 283c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma} 284c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 285c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidTcpRxBytes(JNIEnv* env, jobject clazz, jint uid) { 286c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma return getUidBytes(env, clazz, uid, RX, TCP); 287c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma} 288c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 289c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidUdpTxBytes(JNIEnv* env, jobject clazz, jint uid) { 290c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma return getUidBytes(env, clazz, uid, TX, UDP); 291c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma} 292c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 293c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidUdpRxBytes(JNIEnv* env, jobject clazz, jint uid) { 294c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma return getUidBytes(env, clazz, uid, RX, UDP); 295c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma} 296c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 297c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidTcpTxSegments(JNIEnv* env, jobject clazz, jint uid) { 298c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma return getUidPkts(env, clazz, uid, TX, TCP); 299c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma} 300c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 301c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidTcpRxSegments(JNIEnv* env, jobject clazz, jint uid) { 302c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma return getUidPkts(env, clazz, uid, RX, TCP); 303c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma} 304c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 305c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidUdpTxPackets(JNIEnv* env, jobject clazz, jint uid) { 306c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma return getUidPkts(env, clazz, uid, TX, UDP); 307c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma} 308c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 309c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharmastatic jlong getUidUdpRxPackets(JNIEnv* env, jobject clazz, jint uid) { 310c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma return getUidPkts(env, clazz, uid, RX, UDP); 3112b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor} 3122b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 3132b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnorstatic JNINativeMethod gMethods[] = { 3142b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor {"getMobileTxPackets", "()J", (void*) getMobileTxPackets}, 3152b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor {"getMobileRxPackets", "()J", (void*) getMobileRxPackets}, 3162b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor {"getMobileTxBytes", "()J", (void*) getMobileTxBytes}, 3172b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor {"getMobileRxBytes", "()J", (void*) getMobileRxBytes}, 318227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff {"getTxPackets", "(Ljava/lang/String;)J", (void*) getTxPackets}, 319227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff {"getRxPackets", "(Ljava/lang/String;)J", (void*) getRxPackets}, 320227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff {"getTxBytes", "(Ljava/lang/String;)J", (void*) getTxBytes}, 321227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff {"getRxBytes", "(Ljava/lang/String;)J", (void*) getRxBytes}, 3222b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor {"getTotalTxPackets", "()J", (void*) getTotalTxPackets}, 3232b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor {"getTotalRxPackets", "()J", (void*) getTotalRxPackets}, 3242b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor {"getTotalTxBytes", "()J", (void*) getTotalTxBytes}, 3252b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor {"getTotalRxBytes", "()J", (void*) getTotalRxBytes}, 326c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 327c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma /* Per-UID Stats */ 3282b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor {"getUidTxBytes", "(I)J", (void*) getUidTxBytes}, 3292b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor {"getUidRxBytes", "(I)J", (void*) getUidRxBytes}, 330c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma {"getUidTxPackets", "(I)J", (void*) getUidTxPackets}, 331c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma {"getUidRxPackets", "(I)J", (void*) getUidRxPackets}, 332c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 333c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma {"getUidTcpTxBytes", "(I)J", (void*) getUidTcpTxBytes}, 334c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma {"getUidTcpRxBytes", "(I)J", (void*) getUidTcpRxBytes}, 335c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma {"getUidUdpTxBytes", "(I)J", (void*) getUidUdpTxBytes}, 336c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma {"getUidUdpRxBytes", "(I)J", (void*) getUidUdpRxBytes}, 337c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma 338c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma {"getUidTcpTxSegments", "(I)J", (void*) getUidTcpTxSegments}, 339c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma {"getUidTcpRxSegments", "(I)J", (void*) getUidTcpRxSegments}, 340c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma {"getUidUdpTxPackets", "(I)J", (void*) getUidUdpTxPackets}, 341c39c1d4dee917560d174f6ba5402e4c6644edd47Ashish Sharma {"getUidUdpRxPackets", "(I)J", (void*) getUidUdpRxPackets}, 3422b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor}; 3432b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 3442b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnorint register_android_net_TrafficStats(JNIEnv* env) { 3452b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor return AndroidRuntime::registerNativeMethods(env, "android/net/TrafficStats", 3462b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor gMethods, NELEM(gMethods)); 3472b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor} 3482b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor 3492b4abcd0c7c4361af8ab6d5d7b073fb75ac6d219Dan Egnor} 350