19a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey/* 29a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey * Copyright (C) 2013 The Android Open Source Project 39a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey * 49a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 59a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey * you may not use this file except in compliance with the License. 69a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey * You may obtain a copy of the License at 79a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey * 89a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 99a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey * 109a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey * Unless required by applicable law or agreed to in writing, software 119a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 129a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey * See the License for the specific language governing permissions and 149a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey * limitations under the License. 159a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey */ 169a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 179a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey#define LOG_TAG "NetworkStats" 189a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 199a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey#include <errno.h> 209a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey#include <sys/stat.h> 219a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey#include <sys/types.h> 229a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 239a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey#include <android_runtime/AndroidRuntime.h> 249a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey#include <cutils/logger.h> 259a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey#include <jni.h> 269a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 279a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey#include <ScopedUtfChars.h> 289a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey#include <ScopedLocalRef.h> 299a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey#include <ScopedPrimitiveArray.h> 309a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 319a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey#include <utils/Log.h> 329a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey#include <utils/misc.h> 339a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey#include <utils/Vector.h> 349a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 359a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkeynamespace android { 369a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 379a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkeystatic jclass gStringClass; 389a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 399a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkeystatic struct { 409a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey jfieldID size; 419a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey jfieldID iface; 429a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey jfieldID uid; 439a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey jfieldID set; 449a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey jfieldID tag; 459a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey jfieldID rxBytes; 469a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey jfieldID rxPackets; 479a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey jfieldID txBytes; 489a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey jfieldID txPackets; 499a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey jfieldID operations; 509a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey} gNetworkStatsClassInfo; 519a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 529a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkeystruct stats_line { 539a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey int32_t idx; 549a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey char iface[32]; 559a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey int32_t uid; 569a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey int32_t set; 579a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey int32_t tag; 589a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey int64_t rxBytes; 599a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey int64_t rxPackets; 609a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey int64_t txBytes; 619a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey int64_t txPackets; 629a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey}; 639a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 649a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkeystatic int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats, 659a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey jstring path, jint limitUid) { 669a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey ScopedUtfChars path8(env, path); 679a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey if (path8.c_str() == NULL) { 689a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey return -1; 699a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey } 709a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 719a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey FILE *fp = fopen(path8.c_str(), "r"); 729a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey if (fp == NULL) { 739a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey return -1; 749a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey } 759a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 769a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey Vector<stats_line> lines; 779a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 789a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey int lastIdx = 1; 799a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey char buffer[384]; 809a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey while (fgets(buffer, sizeof(buffer), fp) != NULL) { 819a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey stats_line s; 829a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey int64_t rawTag; 839a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey if (sscanf(buffer, "%d %31s 0x%llx %u %u %llu %llu %llu %llu", &s.idx, 849a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey &s.iface, &rawTag, &s.uid, &s.set, &s.rxBytes, &s.rxPackets, 859a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey &s.txBytes, &s.txPackets) == 9) { 869a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey if (s.idx != lastIdx + 1) { 879a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey ALOGE("inconsistent idx=%d after lastIdx=%d", s.idx, lastIdx); 889a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey return -1; 899a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey } 909a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey lastIdx = s.idx; 919a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 929a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey s.tag = rawTag >> 32; 939a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey lines.push_back(s); 949a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey } 959a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey } 969a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 979a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey if (fclose(fp) != 0) { 989a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey return -1; 999a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey } 1009a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 1019a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey int size = lines.size(); 1029a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 1039a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey ScopedLocalRef<jobjectArray> iface(env, env->NewObjectArray(size, gStringClass, NULL)); 1049a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey if (iface.get() == NULL) return -1; 1059a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey ScopedIntArrayRW uid(env, env->NewIntArray(size)); 1069a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey if (uid.get() == NULL) return -1; 1079a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey ScopedIntArrayRW set(env, env->NewIntArray(size)); 1089a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey if (set.get() == NULL) return -1; 1099a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey ScopedIntArrayRW tag(env, env->NewIntArray(size)); 1109a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey if (tag.get() == NULL) return -1; 1119a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey ScopedLongArrayRW rxBytes(env, env->NewLongArray(size)); 1129a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey if (rxBytes.get() == NULL) return -1; 1139a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey ScopedLongArrayRW rxPackets(env, env->NewLongArray(size)); 1149a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey if (rxPackets.get() == NULL) return -1; 1159a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey ScopedLongArrayRW txBytes(env, env->NewLongArray(size)); 1169a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey if (txBytes.get() == NULL) return -1; 1179a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey ScopedLongArrayRW txPackets(env, env->NewLongArray(size)); 1189a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey if (txPackets.get() == NULL) return -1; 1199a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey ScopedLongArrayRW operations(env, env->NewLongArray(size)); 1209a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey if (operations.get() == NULL) return -1; 1219a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 1229a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey for (int i = 0; i < size; i++) { 1239a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey ScopedLocalRef<jstring> ifaceString(env, env->NewStringUTF(lines[i].iface)); 1249a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey env->SetObjectArrayElement(iface.get(), i, ifaceString.get()); 1259a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 1269a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey uid[i] = lines[i].uid; 1279a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey set[i] = lines[i].set; 1289a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey tag[i] = lines[i].tag; 1299a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey rxBytes[i] = lines[i].rxBytes; 1309a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey rxPackets[i] = lines[i].rxPackets; 1319a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey txBytes[i] = lines[i].txBytes; 1329a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey txPackets[i] = lines[i].txPackets; 1339a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey } 1349a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 1359a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey env->SetIntField(stats, gNetworkStatsClassInfo.size, size); 1369a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey env->SetObjectField(stats, gNetworkStatsClassInfo.iface, iface.get()); 1379a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey env->SetObjectField(stats, gNetworkStatsClassInfo.uid, uid.getJavaArray()); 1389a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey env->SetObjectField(stats, gNetworkStatsClassInfo.set, set.getJavaArray()); 1399a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey env->SetObjectField(stats, gNetworkStatsClassInfo.tag, tag.getJavaArray()); 1409a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey env->SetObjectField(stats, gNetworkStatsClassInfo.rxBytes, rxBytes.getJavaArray()); 1419a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey env->SetObjectField(stats, gNetworkStatsClassInfo.rxPackets, rxPackets.getJavaArray()); 1429a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey env->SetObjectField(stats, gNetworkStatsClassInfo.txBytes, txBytes.getJavaArray()); 1439a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey env->SetObjectField(stats, gNetworkStatsClassInfo.txPackets, txPackets.getJavaArray()); 1449a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey env->SetObjectField(stats, gNetworkStatsClassInfo.operations, operations.getJavaArray()); 1459a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 1469a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey return 0; 1479a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey} 1489a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 1499a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkeystatic jclass findClass(JNIEnv* env, const char* name) { 1509a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey ScopedLocalRef<jclass> localClass(env, env->FindClass(name)); 1519a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey jclass result = reinterpret_cast<jclass>(env->NewGlobalRef(localClass.get())); 1529a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey if (result == NULL) { 1539a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey ALOGE("failed to find class '%s'", name); 1549a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey abort(); 1559a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey } 1569a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey return result; 1579a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey} 1589a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 1599a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkeystatic JNINativeMethod gMethods[] = { 1609a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey { "nativeReadNetworkStatsDetail", 1619a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey "(Landroid/net/NetworkStats;Ljava/lang/String;I)I", 1629a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey (void*) readNetworkStatsDetail } 1639a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey}; 1649a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 1659a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkeyint register_com_android_internal_net_NetworkStatsFactory(JNIEnv* env) { 1669a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey int err = AndroidRuntime::registerNativeMethods(env, 1679a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey "com/android/internal/net/NetworkStatsFactory", gMethods, 1689a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey NELEM(gMethods)); 1699a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 1709a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey gStringClass = findClass(env, "java/lang/String"); 1719a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 1729a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey jclass clazz = env->FindClass("android/net/NetworkStats"); 1739a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey gNetworkStatsClassInfo.size = env->GetFieldID(clazz, "size", "I"); 1749a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey gNetworkStatsClassInfo.iface = env->GetFieldID(clazz, "iface", "[Ljava/lang/String;"); 1759a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey gNetworkStatsClassInfo.uid = env->GetFieldID(clazz, "uid", "[I"); 1769a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey gNetworkStatsClassInfo.set = env->GetFieldID(clazz, "set", "[I"); 1779a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey gNetworkStatsClassInfo.tag = env->GetFieldID(clazz, "tag", "[I"); 1789a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey gNetworkStatsClassInfo.rxBytes = env->GetFieldID(clazz, "rxBytes", "[J"); 1799a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey gNetworkStatsClassInfo.rxPackets = env->GetFieldID(clazz, "rxPackets", "[J"); 1809a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey gNetworkStatsClassInfo.txBytes = env->GetFieldID(clazz, "txBytes", "[J"); 1819a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey gNetworkStatsClassInfo.txPackets = env->GetFieldID(clazz, "txPackets", "[J"); 1829a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey gNetworkStatsClassInfo.operations = env->GetFieldID(clazz, "operations", "[J"); 1839a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 1849a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey return err; 1859a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey} 1869a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 1879a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey} 188