Filter debug entries for each vpn

NetworkStats calculation needs to filter out debug entries to
prevent over counting. While NetworkStatsFactory migrates data
usage over a VPN to the TUN network, NetworkStatsFactory does
not filter out debug entries per vpn which will cause debug
entries left and cause exception.

Bug: 152678151
Test: atest com.android.server.net.NetworkStatsFactoryTest
      and verify no exception
Change-Id: I3525edc385b07858b48c7add2d331c4b5a2e84ad
diff --git a/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java b/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java
index 28785f7..3aafe0b 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java
@@ -41,6 +41,7 @@
     static final String TEST_IFACE = "test0";
     static final String TEST_IFACE2 = "test1";
     static final String TUN_IFACE = "test_nss_tun0";
+    static final String TUN_IFACE2 = "test_nss_tun1";
 
     static final int UID_RED = 1001;
     static final int UID_BLUE = 1002;
@@ -107,10 +108,14 @@
         assertEquals("unexpected operations", operations, entry.operations);
     }
 
-    VpnInfo createVpnInfo(String[] underlyingIfaces) {
+    static VpnInfo createVpnInfo(String[] underlyingIfaces) {
+        return createVpnInfo(TUN_IFACE, underlyingIfaces);
+    }
+
+    static VpnInfo createVpnInfo(String vpnIface, String[] underlyingIfaces) {
         VpnInfo info = new VpnInfo();
         info.ownerUid = UID_VPN;
-        info.vpnIface = TUN_IFACE;
+        info.vpnIface = vpnIface;
         info.underlyingIfaces = underlyingIfaces;
         return info;
     }
diff --git a/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java b/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java
index 5ab2e32..4473492 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java
@@ -264,6 +264,46 @@
     }
 
     @Test
+    public void testConcurrentVpns() throws Exception {
+        // Assume two VPNs are connected on two different network interfaces. VPN1 is using
+        // TEST_IFACE and VPN2 is using TEST_IFACE2.
+        final VpnInfo[] vpnInfos = new VpnInfo[] {
+                createVpnInfo(TUN_IFACE, new String[] {TEST_IFACE}),
+                createVpnInfo(TUN_IFACE2, new String[] {TEST_IFACE2})};
+        mFactory.updateVpnInfos(vpnInfos);
+
+        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
+        // overhead per packet):
+        // 1000 bytes (100 packets) were sent, and 2000 bytes (200 packets) were received by UID_RED
+        // over VPN1.
+        // 700 bytes (70 packets) were sent, and 3000 bytes (300 packets) were received by UID_RED
+        // over VPN2.
+        // 500 bytes (50 packets) were sent, and 1000 bytes (100 packets) were received by UID_BLUE
+        // over VPN1.
+        // 250 bytes (25 packets) were sent, and 500 bytes (50 packets) were received by UID_BLUE
+        // over VPN2.
+        // VPN1 sent 1650 bytes (150 packets), and received 3300 (300 packets) over TEST_IFACE.
+        // Of 1650 bytes sent over WiFi, expect 1000 bytes attributed to UID_RED, 500 bytes
+        // attributed to UID_BLUE, and 150 bytes attributed to UID_VPN.
+        // Of 3300 bytes received over WiFi, expect 2000 bytes attributed to UID_RED, 1000 bytes
+        // attributed to UID_BLUE, and 300 bytes attributed to UID_VPN.
+        // VPN2 sent 1045 bytes (95 packets), and received 3850 (350 packets) over TEST_IFACE2.
+        // Of 1045 bytes sent over Cell, expect 700 bytes attributed to UID_RED, 250 bytes
+        // attributed to UID_BLUE, and 95 bytes attributed to UID_VPN.
+        // Of 3850 bytes received over Cell, expect 3000 bytes attributed to UID_RED, 500 bytes
+        // attributed to UID_BLUE, and 350 bytes attributed to UID_VPN.
+        final NetworkStats tunStats =
+                parseDetailedStats(R.raw.xt_qtaguid_vpn_one_underlying_two_vpn);
+
+        assertValues(tunStats, TEST_IFACE, UID_RED, 2000L, 200L, 1000L, 100L);
+        assertValues(tunStats, TEST_IFACE, UID_BLUE, 1000L, 100L, 500L, 50L);
+        assertValues(tunStats, TEST_IFACE2, UID_RED, 3000L, 300L, 700L, 70L);
+        assertValues(tunStats, TEST_IFACE2, UID_BLUE, 500L, 50L, 250L, 25L);
+        assertValues(tunStats, TEST_IFACE, UID_VPN, 300L, 0L, 150L, 0L);
+        assertValues(tunStats, TEST_IFACE2, UID_VPN, 350L, 0L, 95L, 0L);
+    }
+
+    @Test
     public void testVpnWithTwoUnderlyingIfaces_splitTraffic() throws Exception {
         // WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and
         // Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
diff --git a/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_two_vpn b/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_two_vpn
new file mode 100644
index 0000000..eb0513b
--- /dev/null
+++ b/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_two_vpn
@@ -0,0 +1,9 @@
+idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
+2 test_nss_tun0 0x0 1001 0 2000 200 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
+3 test_nss_tun0 0x0 1002 0 1000 100 500 50 0 0 0 0 0 0 0 0 0 0 0 0
+4 test_nss_tun1 0x0 1001 0 3000 300 700 70 0 0 0 0 0 0 0 0 0 0 0 0
+5 test_nss_tun1 0x0 1002 0 500 50 250 25 0 0 0 0 0 0 0 0 0 0 0 0
+6 test0 0x0 1004 0 3300 300 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+7 test0 0x0 1004 1 0 0 1650 150 0 0 0 0 0 0 0 0 0 0 0 0
+8 test1 0x0 1004 0 3850 350 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+9 test1 0x0 1004 1 0 0 1045 95 0 0 0 0 0 0 0 0 0 0 0 0
\ No newline at end of file