diff --git a/core/java/com/android/internal/net/NetworkStatsFactory.java b/core/java/com/android/internal/net/NetworkStatsFactory.java index 98afebc51b..c4d08c7dc5 100644 --- a/core/java/com/android/internal/net/NetworkStatsFactory.java +++ b/core/java/com/android/internal/net/NetworkStatsFactory.java @@ -56,8 +56,6 @@ public class NetworkStatsFactory { private static final boolean USE_NATIVE_PARSING = true; private static final boolean SANITY_CHECK_NATIVE = false; - /** Path to {@code /proc/net/dev}. */ - private final File mStatsIfaceDev; /** Path to {@code /proc/net/xt_qtaguid/iface_stat_all}. */ private final File mStatsXtIfaceAll; /** Path to {@code /proc/net/xt_qtaguid/iface_stat_fmt}. */ @@ -133,47 +131,16 @@ public class NetworkStatsFactory { @VisibleForTesting public NetworkStatsFactory(File procRoot, boolean useBpfStats) { - mStatsIfaceDev = new File(procRoot, "net/dev"); mStatsXtIfaceAll = new File(procRoot, "net/xt_qtaguid/iface_stat_all"); mStatsXtIfaceFmt = new File(procRoot, "net/xt_qtaguid/iface_stat_fmt"); mStatsXtUid = new File(procRoot, "net/xt_qtaguid/stats"); mUseBpfStats = useBpfStats; } - @VisibleForTesting - public NetworkStats readNetworkStatsIfaceDev() throws IOException { - final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads(); - + public NetworkStats readBpfNetworkStatsDev() throws IOException { final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 6); - final NetworkStats.Entry entry = new NetworkStats.Entry(); - - BufferedReader reader = null; - try { - reader = new BufferedReader(new FileReader(mStatsIfaceDev)); - - // skip first two header lines - reader.readLine(); - reader.readLine(); - - // parse remaining lines - String line; - while ((line = reader.readLine()) != null) { - String[] values = line.trim().split("\\:?\\s+"); - entry.iface = values[0]; - entry.uid = UID_ALL; - entry.set = SET_ALL; - entry.tag = TAG_NONE; - entry.rxBytes = Long.parseLong(values[1]); - entry.rxPackets = Long.parseLong(values[2]); - entry.txBytes = Long.parseLong(values[9]); - entry.txPackets = Long.parseLong(values[10]); - stats.addValues(entry); - } - } catch (NullPointerException|NumberFormatException e) { - throw new ProtocolException("problem parsing stats", e); - } finally { - IoUtils.closeQuietly(reader); - StrictMode.setThreadPolicy(savedPolicy); + if (nativeReadNetworkStatsDev(stats) != 0) { + throw new IOException("Failed to parse bpf iface stats"); } return stats; } @@ -188,9 +155,9 @@ public class NetworkStatsFactory { */ public NetworkStats readNetworkStatsSummaryDev() throws IOException { - // Return the stats get from /proc/net/dev if switched to bpf module. + // Return xt_bpf stats if switched to bpf module. if (mUseBpfStats) - return readNetworkStatsIfaceDev(); + return readBpfNetworkStatsDev(); final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads(); @@ -244,9 +211,9 @@ public class NetworkStatsFactory { */ public NetworkStats readNetworkStatsSummaryXt() throws IOException { - // Return the stats get from /proc/net/dev if qtaguid module is replaced. + // Return xt_bpf stats if qtaguid module is replaced. if (mUseBpfStats) - return readNetworkStatsIfaceDev(); + return readBpfNetworkStatsDev(); final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads(); @@ -408,4 +375,7 @@ public class NetworkStatsFactory { @VisibleForTesting public static native int nativeReadNetworkStatsDetail(NetworkStats stats, String path, int limitUid, String[] limitIfaces, int limitTag, boolean useBpfStats); + + @VisibleForTesting + public static native int nativeReadNetworkStatsDev(NetworkStats stats); } diff --git a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp index 99d9839570..c15b7ee4fe 100644 --- a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp +++ b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp @@ -205,37 +205,8 @@ static int legacyReadNetworkStatsDetail(std::vector* lines, return 0; } -static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats, jstring path, - jint limitUid, jobjectArray limitIfacesObj, jint limitTag, - jboolean useBpfStats) { - ScopedUtfChars path8(env, path); - if (path8.c_str() == NULL) { - return -1; - } - - std::vector limitIfaces; - if (limitIfacesObj != NULL && env->GetArrayLength(limitIfacesObj) > 0) { - int num = env->GetArrayLength(limitIfacesObj); - for (int i = 0; i < num; i++) { - jstring string = (jstring)env->GetObjectArrayElement(limitIfacesObj, i); - ScopedUtfChars string8(env, string); - if (string8.c_str() != NULL) { - limitIfaces.push_back(std::string(string8.c_str())); - } - } - } - std::vector lines; - - - if (useBpfStats) { - if (parseBpfNetworkStatsDetail(&lines, limitIfaces, limitTag, limitUid) < 0) - return -1; - } else { - if (legacyReadNetworkStatsDetail(&lines, limitIfaces, limitTag, - limitUid, path8.c_str()) < 0) - return -1; - } - +static int statsLinesToNetworkStats(JNIEnv* env, jclass clazz, jobject stats, + std::vector& lines) { int size = lines.size(); bool grow = size > env->GetIntField(stats, gNetworkStatsClassInfo.capacity); @@ -308,14 +279,58 @@ static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats, jstr env->SetObjectField(stats, gNetworkStatsClassInfo.txPackets, txPackets.getJavaArray()); env->SetObjectField(stats, gNetworkStatsClassInfo.operations, operations.getJavaArray()); } - return 0; } +static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats, jstring path, + jint limitUid, jobjectArray limitIfacesObj, jint limitTag, + jboolean useBpfStats) { + ScopedUtfChars path8(env, path); + if (path8.c_str() == NULL) { + return -1; + } + + std::vector limitIfaces; + if (limitIfacesObj != NULL && env->GetArrayLength(limitIfacesObj) > 0) { + int num = env->GetArrayLength(limitIfacesObj); + for (int i = 0; i < num; i++) { + jstring string = (jstring)env->GetObjectArrayElement(limitIfacesObj, i); + ScopedUtfChars string8(env, string); + if (string8.c_str() != NULL) { + limitIfaces.push_back(std::string(string8.c_str())); + } + } + } + std::vector lines; + + + if (useBpfStats) { + if (parseBpfNetworkStatsDetail(&lines, limitIfaces, limitTag, limitUid) < 0) + return -1; + } else { + if (legacyReadNetworkStatsDetail(&lines, limitIfaces, limitTag, + limitUid, path8.c_str()) < 0) + return -1; + } + + return statsLinesToNetworkStats(env, clazz, stats, lines); +} + +static int readNetworkStatsDev(JNIEnv* env, jclass clazz, jobject stats) { + std::vector lines; + + if (parseBpfNetworkStatsDev(&lines) < 0) + return -1; + + return statsLinesToNetworkStats(env, clazz, stats, lines); +} + static const JNINativeMethod gMethods[] = { { "nativeReadNetworkStatsDetail", "(Landroid/net/NetworkStats;Ljava/lang/String;I[Ljava/lang/String;IZ)I", - (void*) readNetworkStatsDetail } + (void*) readNetworkStatsDetail }, + { "nativeReadNetworkStatsDev", "(Landroid/net/NetworkStats;)I", + (void*) readNetworkStatsDev }, }; int register_com_android_internal_net_NetworkStatsFactory(JNIEnv* env) {