Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 93afbf25 authored by Chenbo Feng's avatar Chenbo Feng
Browse files

Use /proc/net/dev to get stats summary

If the qtaguid proc file is no longer exist, the device is running new
eBPF module to do traffic accounting. So the NetworkStatsFactory need to
use the proc/net/dev interface to get the per interface traffic stats
summary. Also, adding a test to verify the helper function work properly

Bug: 30950746
Test: run NetworkStatsFactoryTest
Change-Id: Ia36808bf02f1637dd41a3e7c50917b91b1a77524
parent 828f1b45
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
@@ -31,13 +31,17 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.ProcFileReader;
import com.google.android.collect.Lists;

import libcore.io.IoUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.net.ProtocolException;
import java.util.ArrayList;
import java.util.Objects;

/**
@@ -55,6 +59,8 @@ public class NetworkStatsFactory {
    // Used for correct stats accounting on clatd interfaces.
    private static final int IPV4V6_HEADER_DELTA = 20;

    /** 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}. */
@@ -84,12 +90,51 @@ 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();

        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);
        }
        return stats;
    }

    /**
     * Parse and return interface-level summary {@link NetworkStats} measured
     * using {@code /proc/net/dev} style hooks, which may include non IP layer
@@ -99,6 +144,11 @@ public class NetworkStatsFactory {
     * @throws IllegalStateException when problem parsing stats.
     */
    public NetworkStats readNetworkStatsSummaryDev() throws IOException {

        // Return the stats get from /proc/net/dev if switched to bpf module.
        if (mUseBpfStats)
            return readNetworkStatsIfaceDev();

        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();

        final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 6);
@@ -150,6 +200,11 @@ public class NetworkStatsFactory {
     * @throws IllegalStateException when problem parsing stats.
     */
    public NetworkStats readNetworkStatsSummaryXt() throws IOException {

        // Return the stats get from /proc/net/dev if qtaguid  module is replaced.
        if (mUseBpfStats)
            return readNetworkStatsIfaceDev();

        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();

        // return null when kernel doesn't support
+14 −0
Original line number Diff line number Diff line
@@ -115,6 +115,20 @@ public class NetworkStatsFactoryTest {
        assertStatsEntry(stats, "rmnet1", 10021, SET_FOREGROUND, 0x30100000, 742L, 3L, 1265L, 3L);
    }

    @Test
    public void testNetworkStatsSummary() throws Exception {
        stageFile(R.raw.net_dev_typical, file("net/dev"));

        final NetworkStats stats = mFactory.readNetworkStatsIfaceDev();
        assertEquals(6, stats.size());
        assertStatsEntry(stats, "lo", UID_ALL, SET_ALL, TAG_NONE, 8308L, 8308L);
        assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 1507570L, 489339L);
        assertStatsEntry(stats, "ifb0", UID_ALL, SET_ALL, TAG_NONE, 52454L, 0L);
        assertStatsEntry(stats, "ifb1", UID_ALL, SET_ALL, TAG_NONE, 52454L, 0L);
        assertStatsEntry(stats, "sit0", UID_ALL, SET_ALL, TAG_NONE, 0L, 0L);
        assertStatsEntry(stats, "ip6tnl0", UID_ALL, SET_ALL, TAG_NONE, 0L, 0L);
    }

    @Test
    public void testNetworkStatsSingle() throws Exception {
        stageFile(R.raw.xt_qtaguid_iface_typical, file("net/xt_qtaguid/iface_stat_all"));
+8 −0
Original line number Diff line number Diff line
Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
    lo:    8308     116    0    0    0     0          0         0     8308     116    0    0    0     0       0          0
rmnet0: 1507570    2205    0    0    0     0          0         0   489339    2237    0    0    0     0       0          0
  ifb0:   52454     151    0  151    0     0          0         0        0       0    0    0    0     0       0          0
  ifb1:   52454     151    0  151    0     0          0         0        0       0    0    0    0     0       0          0
  sit0:       0       0    0    0    0     0          0         0        0       0  148    0    0     0       0          0
ip6tnl0:       0       0    0    0    0     0          0         0        0       0  151  151    0     0       0          0