diff --git a/service-t/native/libs/libnetworkstats/NetworkTracePoller.cpp b/service-t/native/libs/libnetworkstats/NetworkTracePoller.cpp index 80c315a837..450f380644 100644 --- a/service-t/native/libs/libnetworkstats/NetworkTracePoller.cpp +++ b/service-t/native/libs/libnetworkstats/NetworkTracePoller.cpp @@ -25,9 +25,15 @@ #include #include +#include +#include + +#include "netdbpf/BpfNetworkStats.h" + namespace android { namespace bpf { namespace internal { +using ::android::base::StringPrintf; void NetworkTracePoller::PollAndSchedule(perfetto::base::TaskRunner* runner, uint32_t poll_ms) { @@ -116,6 +122,28 @@ bool NetworkTracePoller::Stop() { return res.ok(); } +void NetworkTracePoller::TraceIfaces(const std::vector& packets) { + if (packets.empty()) return; + + std::unordered_set uniqueIfindex; + for (const PacketTrace& pkt : packets) { + uniqueIfindex.insert(pkt.ifindex); + } + + for (uint32_t ifindex : uniqueIfindex) { + char ifname[IF_NAMESIZE] = {}; + if (if_indextoname(ifindex, ifname) != ifname) continue; + + StatsValue stats = {}; + if (bpfGetIfIndexStats(ifindex, &stats) != 0) continue; + + std::string rxTrack = StringPrintf("%s [%d] Rx Bytes", ifname, ifindex); + std::string txTrack = StringPrintf("%s [%d] Tx Bytes", ifname, ifindex); + ATRACE_INT64(rxTrack.c_str(), stats.rxBytes); + ATRACE_INT64(txTrack.c_str(), stats.txBytes); + } +} + bool NetworkTracePoller::ConsumeAll() { std::scoped_lock lock(mMutex); return ConsumeAllLocked(); @@ -137,6 +165,7 @@ bool NetworkTracePoller::ConsumeAllLocked() { ATRACE_INT("NetworkTracePackets", packets.size()); + TraceIfaces(packets); mCallback(packets); return true; diff --git a/service-t/native/libs/libnetworkstats/include/netdbpf/NetworkTracePoller.h b/service-t/native/libs/libnetworkstats/include/netdbpf/NetworkTracePoller.h index 8433934db7..092ab64575 100644 --- a/service-t/native/libs/libnetworkstats/include/netdbpf/NetworkTracePoller.h +++ b/service-t/native/libs/libnetworkstats/include/netdbpf/NetworkTracePoller.h @@ -61,6 +61,11 @@ class NetworkTracePoller { void PollAndSchedule(perfetto::base::TaskRunner* runner, uint32_t poll_ms); bool ConsumeAllLocked() REQUIRES(mMutex); + // Record sparse iface stats via atrace. This queries the per-iface stats maps + // for any iface present in the vector of packets. This is inexact, but should + // have sufficient coverage given these are cumulative counters. + void TraceIfaces(const std::vector& packets) REQUIRES(mMutex); + std::mutex mMutex; // Records the number of successfully started active sessions so that only the