summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2014-08-12 02:31:00 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-08-12 00:32:51 +0000
commit93f871126c6dfb059c655d07f03a4cf4598bd6be (patch)
treeec67559bf6115118103e804023075afddedbaafb /core/java
parent652705f229845e5c716e0ca2d8c87ed6789e9586 (diff)
parenteb2c2c790c4b86c9c09245e0b87a38972713434a (diff)
Merge "Hack and ship: NetworkStats edition." into lmp-dev
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/net/LinkProperties.java9
-rw-r--r--core/java/com/android/internal/net/NetworkStatsFactory.java70
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) {