diff options
| author | Jeff Sharkey <jsharkey@android.com> | 2014-08-12 02:31:00 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-08-12 00:32:51 +0000 |
| commit | 93f871126c6dfb059c655d07f03a4cf4598bd6be (patch) | |
| tree | ec67559bf6115118103e804023075afddedbaafb /core/java | |
| parent | 652705f229845e5c716e0ca2d8c87ed6789e9586 (diff) | |
| parent | eb2c2c790c4b86c9c09245e0b87a38972713434a (diff) | |
Merge "Hack and ship: NetworkStats edition." into lmp-dev
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/net/LinkProperties.java | 9 | ||||
| -rw-r--r-- | core/java/com/android/internal/net/NetworkStatsFactory.java | 70 |
2 files changed, 72 insertions, 7 deletions
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java index 8be5cf8bd19e..47b74ab4d23f 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -16,6 +16,7 @@ package android.net; +import android.annotation.NonNull; import android.net.ProxyInfo; import android.os.Parcelable; import android.os.Parcel; @@ -24,7 +25,6 @@ import android.text.TextUtils; import java.net.InetAddress; import java.net.Inet4Address; import java.net.Inet6Address; - import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collection; @@ -480,10 +480,13 @@ public final class LinkProperties implements Parcelable { * Returns all the links stacked on top of this link. * @hide */ - public List<LinkProperties> getStackedLinks() { + public @NonNull List<LinkProperties> getStackedLinks() { + if (mStackedLinks.isEmpty()) { + return Collections.EMPTY_LIST; + } List<LinkProperties> stacked = new ArrayList<LinkProperties>(); for (LinkProperties link : mStackedLinks.values()) { - stacked.add(new LinkProperties(link)); + stacked.add(new LinkProperties(link)); } return Collections.unmodifiableList(stacked); } diff --git a/core/java/com/android/internal/net/NetworkStatsFactory.java b/core/java/com/android/internal/net/NetworkStatsFactory.java index e2a2b1eb2a5d..506114bd01f3 100644 --- a/core/java/com/android/internal/net/NetworkStatsFactory.java +++ b/core/java/com/android/internal/net/NetworkStatsFactory.java @@ -25,17 +25,20 @@ import static com.android.server.NetworkManagementSocketTagger.kernelToTag; import android.net.NetworkStats; import android.os.StrictMode; import android.os.SystemClock; +import android.util.ArrayMap; +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 libcore.io.IoUtils; + import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.ProtocolException; - -import libcore.io.IoUtils; +import java.util.Objects; /** * Creates {@link NetworkStats} instances by parsing various {@code /proc/} @@ -54,6 +57,19 @@ public class NetworkStatsFactory { /** Path to {@code /proc/net/xt_qtaguid/stats}. */ private final File mStatsXtUid; + @GuardedBy("sStackedIfaces") + private static final ArrayMap<String, String> sStackedIfaces = new ArrayMap<>(); + + public static void noteStackedIface(String stackedIface, String baseIface) { + synchronized (sStackedIfaces) { + if (baseIface != null) { + sStackedIfaces.put(stackedIface, baseIface); + } else { + sStackedIfaces.remove(stackedIface); + } + } + } + public NetworkStatsFactory() { this(new File("/proc/")); } @@ -171,8 +187,54 @@ public class NetworkStatsFactory { } public NetworkStats readNetworkStatsDetail(int limitUid, String[] limitIfaces, int limitTag, - NetworkStats lastStats) - throws IOException { + NetworkStats lastStats) throws IOException { + final NetworkStats stats = readNetworkStatsDetailInternal(limitUid, limitIfaces, limitTag, + lastStats); + + synchronized (sStackedIfaces) { + // Sigh, xt_qtaguid ends up double-counting tx traffic going through + // clatd interfaces, so we need to subtract it here. + final int size = sStackedIfaces.size(); + for (int i = 0; i < size; i++) { + final String stackedIface = sStackedIfaces.keyAt(i); + final String baseIface = sStackedIfaces.valueAt(i); + + // Count up the tx traffic and subtract from root UID on the + // base interface. + NetworkStats.Entry adjust = new NetworkStats.Entry(baseIface, 0, 0, 0, 0L, 0L, 0L, + 0L, 0L); + NetworkStats.Entry entry = null; + for (int j = 0; j < stats.size(); j++) { + entry = stats.getValues(j, entry); + if (Objects.equals(entry.iface, stackedIface)) { + adjust.txBytes -= entry.txBytes; + adjust.txPackets -= entry.txPackets; + } + } + stats.combineValues(adjust); + } + } + + // Double sigh, all rx traffic on clat needs to be tweaked to + // account for the dropped IPv6 header size post-unwrap. + NetworkStats.Entry entry = null; + for (int i = 0; i < stats.size(); i++) { + entry = stats.getValues(i, entry); + if (entry.iface != null && entry.iface.startsWith("clat")) { + // Delta between IPv4 header (20b) and IPv6 header (40b) + entry.rxBytes = entry.rxPackets * 20; + entry.rxPackets = 0; + entry.txBytes = 0; + entry.txPackets = 0; + stats.combineValues(entry); + } + } + + return stats; + } + + private NetworkStats readNetworkStatsDetailInternal(int limitUid, String[] limitIfaces, + int limitTag, NetworkStats lastStats) throws IOException { if (USE_NATIVE_PARSING) { final NetworkStats stats; if (lastStats != null) { |
