Merge "Use delta reads for per uid traffic stats"
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index 126bf65..371276f 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -44,7 +44,7 @@
import android.net.Network;
import android.net.NetworkUtils;
import android.net.TrafficStats;
-import android.net.util.NetdService;
+import android.net.shared.NetdService;
import android.os.Binder;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index b0adf95..2e7cbc6 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -955,12 +955,64 @@
@Override
public long getIfaceStats(String iface, int type) {
- return nativeGetIfaceStat(iface, type, checkBpfStatsEnable());
+ long nativeIfaceStats = nativeGetIfaceStat(iface, type, checkBpfStatsEnable());
+ if (nativeIfaceStats == -1) {
+ return nativeIfaceStats;
+ } else {
+ // When tethering offload is in use, nativeIfaceStats does not contain usage from
+ // offload, add it back here.
+ // When tethering offload is not in use, nativeIfaceStats contains tethering usage.
+ // this does not cause double-counting of tethering traffic, because
+ // NetdTetheringStatsProvider returns zero NetworkStats
+ // when called with STATS_PER_IFACE.
+ return nativeIfaceStats + getTetherStats(iface, type);
+ }
}
@Override
public long getTotalStats(int type) {
- return nativeGetTotalStat(type, checkBpfStatsEnable());
+ long nativeTotalStats = nativeGetTotalStat(type, checkBpfStatsEnable());
+ if (nativeTotalStats == -1) {
+ return nativeTotalStats;
+ } else {
+ // Refer to comment in getIfaceStats
+ return nativeTotalStats + getTetherStats(IFACE_ALL, type);
+ }
+ }
+
+ private long getTetherStats(String iface, int type) {
+ final NetworkStats tetherSnapshot;
+ final long token = Binder.clearCallingIdentity();
+ try {
+ tetherSnapshot = getNetworkStatsTethering(STATS_PER_IFACE);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Error get TetherStats: " + e);
+ return 0;
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ HashSet<String> limitIfaces;
+ if (iface == IFACE_ALL) {
+ limitIfaces = null;
+ } else {
+ limitIfaces = new HashSet<String>();
+ limitIfaces.add(iface);
+ }
+ NetworkStats.Entry entry = tetherSnapshot.getTotal(null, limitIfaces);
+ if (LOGD) Slog.d(TAG, "TetherStats: iface=" + iface + " type=" + type +
+ " entry=" + entry);
+ switch (type) {
+ case 0: // TYPE_RX_BYTES
+ return entry.rxBytes;
+ case 1: // TYPE_RX_PACKETS
+ return entry.rxPackets;
+ case 2: // TYPE_TX_BYTES
+ return entry.txBytes;
+ case 3: // TYPE_TX_PACKETS
+ return entry.txPackets;
+ default:
+ return 0;
+ }
}
private boolean checkBpfStatsEnable() {