[FUI04] Refactor VpnInfo

As a preparation of exposing system API. This patch does some
harmless refactoring, which includes:
  1. Change raw arrays into lists according to API guidelines.
  2. Write test.
  3. Rename class to UnderlyingNetworkInfo.
  4. Rename vpnIface to iface.
  5. Make underlyingIfaces @NonNull in order to adapt new
     unparceling code.
  6. implement equals and hashCode for testing.

Test: atest android.net.UnderlyingNetworkInfoTest
Bug: 174123988

Change-Id: I405c21e57c4af8a12a9dd0a1749b9e6690f87045
This commit is contained in:
junyulai
2021-01-23 09:46:34 +08:00
parent acb3297bd0
commit 2050bed66e
7 changed files with 162 additions and 80 deletions

View File

@@ -31,7 +31,6 @@ import android.net.NetworkRequest;
import android.net.NetworkState; import android.net.NetworkState;
import android.net.ProxyInfo; import android.net.ProxyInfo;
import android.net.UidRange; import android.net.UidRange;
import android.net.VpnInfo;
import android.net.QosSocketInfo; import android.net.QosSocketInfo;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;

View File

@@ -132,8 +132,8 @@ import android.net.SocketKeepalive;
import android.net.TetheringManager; import android.net.TetheringManager;
import android.net.UidRange; import android.net.UidRange;
import android.net.UidRangeParcel; import android.net.UidRangeParcel;
import android.net.UnderlyingNetworkInfo;
import android.net.Uri; import android.net.Uri;
import android.net.VpnInfo;
import android.net.VpnManager; import android.net.VpnManager;
import android.net.VpnService; import android.net.VpnService;
import android.net.metrics.INetdEventListener; import android.net.metrics.INetdEventListener;
@@ -4854,28 +4854,28 @@ public class ConnectivityService extends IConnectivityManager.Stub
* *
* <p>Must be called on the handler thread. * <p>Must be called on the handler thread.
*/ */
private VpnInfo[] getAllVpnInfo() { private UnderlyingNetworkInfo[] getAllVpnInfo() {
ensureRunningOnConnectivityServiceThread(); ensureRunningOnConnectivityServiceThread();
synchronized (mVpns) { synchronized (mVpns) {
if (mLockdownEnabled) { if (mLockdownEnabled) {
return new VpnInfo[0]; return new UnderlyingNetworkInfo[0];
} }
} }
List<VpnInfo> infoList = new ArrayList<>(); List<UnderlyingNetworkInfo> infoList = new ArrayList<>();
for (NetworkAgentInfo nai : mNetworkAgentInfos) { for (NetworkAgentInfo nai : mNetworkAgentInfos) {
VpnInfo info = createVpnInfo(nai); UnderlyingNetworkInfo info = createVpnInfo(nai);
if (info != null) { if (info != null) {
infoList.add(info); infoList.add(info);
} }
} }
return infoList.toArray(new VpnInfo[infoList.size()]); return infoList.toArray(new UnderlyingNetworkInfo[infoList.size()]);
} }
/** /**
* @return VPN information for accounting, or null if we can't retrieve all required * @return VPN information for accounting, or null if we can't retrieve all required
* information, e.g underlying ifaces. * information, e.g underlying ifaces.
*/ */
private VpnInfo createVpnInfo(NetworkAgentInfo nai) { private UnderlyingNetworkInfo createVpnInfo(NetworkAgentInfo nai) {
if (!nai.isVPN()) return null; if (!nai.isVPN()) return null;
Network[] underlyingNetworks = nai.declaredUnderlyingNetworks; Network[] underlyingNetworks = nai.declaredUnderlyingNetworks;
@@ -4907,11 +4907,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Must be non-null or NetworkStatsService will crash. // Must be non-null or NetworkStatsService will crash.
// Cannot happen in production code because Vpn only registers the NetworkAgent after the // Cannot happen in production code because Vpn only registers the NetworkAgent after the
// tun or ipsec interface is created. // tun or ipsec interface is created.
// TODO: Remove this check.
if (nai.linkProperties.getInterfaceName() == null) return null; if (nai.linkProperties.getInterfaceName() == null) return null;
return new VpnInfo(nai.networkCapabilities.getOwnerUid(), return new UnderlyingNetworkInfo(nai.networkCapabilities.getOwnerUid(),
nai.linkProperties.getInterfaceName(), nai.linkProperties.getInterfaceName(), interfaces);
interfaces.toArray(new String[0]));
} }
/** /**
@@ -7989,10 +7989,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
activeIface = activeLinkProperties.getInterfaceName(); activeIface = activeLinkProperties.getInterfaceName();
} }
final VpnInfo[] vpnInfos = getAllVpnInfo(); final UnderlyingNetworkInfo[] underlyingNetworkInfos = getAllVpnInfo();
try { try {
mStatsService.forceUpdateIfaces( mStatsService.forceUpdateIfaces(getDefaultNetworks(), getAllNetworkState(), activeIface,
getDefaultNetworks(), getAllNetworkState(), activeIface, vpnInfos); underlyingNetworkInfos);
} catch (Exception ignored) { } catch (Exception ignored) {
} }
} }
@@ -8252,6 +8252,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
return getVpnIfOwner(mDeps.getCallingUid()); return getVpnIfOwner(mDeps.getCallingUid());
} }
// TODO: stop calling into Vpn.java and get this information from data in this class.
@GuardedBy("mVpns") @GuardedBy("mVpns")
private Vpn getVpnIfOwner(int uid) { private Vpn getVpnIfOwner(int uid) {
final int user = UserHandle.getUserId(uid); final int user = UserHandle.getUserId(uid);
@@ -8260,7 +8261,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (vpn == null) { if (vpn == null) {
return null; return null;
} else { } else {
final VpnInfo info = vpn.getVpnInfo(); final UnderlyingNetworkInfo info = vpn.getUnderlyingNetworkInfo();
return (info == null || info.ownerUid != uid) ? null : vpn; return (info == null || info.ownerUid != uid) ? null : vpn;
} }
} }

View File

@@ -0,0 +1,50 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net
import android.os.Build
import androidx.test.filters.SmallTest
import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.DevSdkIgnoreRunner
import com.android.testutils.assertParcelSane
import org.junit.Test
import org.junit.runner.RunWith
import kotlin.test.assertEquals
private const val TEST_OWNER_UID = 123
private const val TEST_IFACE = "test_tun0"
private val TEST_IFACE_LIST = listOf("wlan0", "rmnet_data0", "eth0")
@SmallTest
@RunWith(DevSdkIgnoreRunner::class)
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
class UnderlyingNetworkInfoTest {
@Test
fun testParcelUnparcel() {
val testInfo = UnderlyingNetworkInfo(TEST_OWNER_UID, TEST_IFACE, TEST_IFACE_LIST)
assertEquals(TEST_OWNER_UID, testInfo.ownerUid)
assertEquals(TEST_IFACE, testInfo.iface)
assertEquals(TEST_IFACE_LIST, testInfo.underlyingIfaces)
assertParcelSane(testInfo, 3)
val emptyInfo = UnderlyingNetworkInfo(0, String(), listOf())
assertEquals(0, emptyInfo.ownerUid)
assertEquals(String(), emptyInfo.iface)
assertEquals(listOf(), emptyInfo.underlyingIfaces)
assertParcelSane(emptyInfo, 3)
}
}

View File

@@ -200,8 +200,8 @@ import android.net.RouteInfoParcel;
import android.net.SocketKeepalive; import android.net.SocketKeepalive;
import android.net.UidRange; import android.net.UidRange;
import android.net.UidRangeParcel; import android.net.UidRangeParcel;
import android.net.UnderlyingNetworkInfo;
import android.net.Uri; import android.net.Uri;
import android.net.VpnInfo;
import android.net.VpnManager; import android.net.VpnManager;
import android.net.metrics.IpConnectivityLog; import android.net.metrics.IpConnectivityLog;
import android.net.shared.NetworkMonitorUtils; import android.net.shared.NetworkMonitorUtils;
@@ -1075,7 +1075,7 @@ public class ConnectivityServiceTest {
private boolean mAgentRegistered = false; private boolean mAgentRegistered = false;
private int mVpnType = VpnManager.TYPE_VPN_SERVICE; private int mVpnType = VpnManager.TYPE_VPN_SERVICE;
private VpnInfo mVpnInfo; private UnderlyingNetworkInfo mUnderlyingNetworkInfo;
// These ConditionVariables allow tests to wait for LegacyVpnRunner to be stopped/started. // These ConditionVariables allow tests to wait for LegacyVpnRunner to be stopped/started.
// TODO: this scheme is ad-hoc and error-prone because it does not fail if, for example, the // TODO: this scheme is ad-hoc and error-prone because it does not fail if, for example, the
@@ -1249,14 +1249,15 @@ public class ConnectivityServiceTest {
} }
@Override @Override
public synchronized VpnInfo getVpnInfo() { public synchronized UnderlyingNetworkInfo getUnderlyingNetworkInfo() {
if (mVpnInfo != null) return mVpnInfo; if (mUnderlyingNetworkInfo != null) return mUnderlyingNetworkInfo;
return super.getVpnInfo(); return super.getUnderlyingNetworkInfo();
} }
private synchronized void setVpnInfo(VpnInfo vpnInfo) { private synchronized void setUnderlyingNetworkInfo(
mVpnInfo = vpnInfo; UnderlyingNetworkInfo underlyingNetworkInfo) {
mUnderlyingNetworkInfo = underlyingNetworkInfo;
} }
} }
@@ -5194,20 +5195,22 @@ public class ConnectivityServiceTest {
private void expectForceUpdateIfaces(Network[] networks, String defaultIface, private void expectForceUpdateIfaces(Network[] networks, String defaultIface,
Integer vpnUid, String vpnIfname, String[] underlyingIfaces) throws Exception { Integer vpnUid, String vpnIfname, String[] underlyingIfaces) throws Exception {
ArgumentCaptor<Network[]> networksCaptor = ArgumentCaptor.forClass(Network[].class); ArgumentCaptor<Network[]> networksCaptor = ArgumentCaptor.forClass(Network[].class);
ArgumentCaptor<VpnInfo[]> vpnInfosCaptor = ArgumentCaptor.forClass(VpnInfo[].class); ArgumentCaptor<UnderlyingNetworkInfo[]> vpnInfosCaptor = ArgumentCaptor.forClass(
UnderlyingNetworkInfo[].class);
verify(mStatsService, atLeastOnce()).forceUpdateIfaces(networksCaptor.capture(), verify(mStatsService, atLeastOnce()).forceUpdateIfaces(networksCaptor.capture(),
any(NetworkState[].class), eq(defaultIface), vpnInfosCaptor.capture()); any(NetworkState[].class), eq(defaultIface), vpnInfosCaptor.capture());
assertSameElementsNoDuplicates(networksCaptor.getValue(), networks); assertSameElementsNoDuplicates(networksCaptor.getValue(), networks);
VpnInfo[] infos = vpnInfosCaptor.getValue(); UnderlyingNetworkInfo[] infos = vpnInfosCaptor.getValue();
if (vpnUid != null) { if (vpnUid != null) {
assertEquals("Should have exactly one VPN:", 1, infos.length); assertEquals("Should have exactly one VPN:", 1, infos.length);
VpnInfo info = infos[0]; UnderlyingNetworkInfo info = infos[0];
assertEquals("Unexpected VPN owner:", (int) vpnUid, info.ownerUid); assertEquals("Unexpected VPN owner:", (int) vpnUid, info.ownerUid);
assertEquals("Unexpected VPN interface:", vpnIfname, info.vpnIface); assertEquals("Unexpected VPN interface:", vpnIfname, info.iface);
assertSameElementsNoDuplicates(underlyingIfaces, info.underlyingIfaces); assertSameElementsNoDuplicates(underlyingIfaces,
info.underlyingIfaces.toArray(new String[0]));
} else { } else {
assertEquals(0, infos.length); assertEquals(0, infos.length);
return; return;
@@ -5268,7 +5271,7 @@ public class ConnectivityServiceTest {
waitForIdle(); waitForIdle();
verify(mStatsService, never()) verify(mStatsService, never())
.forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME), .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME),
eq(new VpnInfo[0])); eq(new UnderlyingNetworkInfo[0]));
reset(mStatsService); reset(mStatsService);
// Roaming change should update ifaces // Roaming change should update ifaces
@@ -5351,8 +5354,8 @@ public class ConnectivityServiceTest {
// network for the VPN... // network for the VPN...
verify(mStatsService, never()).forceUpdateIfaces(any(Network[].class), verify(mStatsService, never()).forceUpdateIfaces(any(Network[].class),
any(NetworkState[].class), any() /* anyString() doesn't match null */, any(NetworkState[].class), any() /* anyString() doesn't match null */,
argThat(infos -> infos[0].underlyingIfaces.length == 1 argThat(infos -> infos[0].underlyingIfaces.size() == 1
&& WIFI_IFNAME.equals(infos[0].underlyingIfaces[0]))); && WIFI_IFNAME.equals(infos[0].underlyingIfaces.get(0))));
verifyNoMoreInteractions(mStatsService); verifyNoMoreInteractions(mStatsService);
reset(mStatsService); reset(mStatsService);
@@ -5365,8 +5368,8 @@ public class ConnectivityServiceTest {
waitForIdle(); waitForIdle();
verify(mStatsService).forceUpdateIfaces(any(Network[].class), verify(mStatsService).forceUpdateIfaces(any(Network[].class),
any(NetworkState[].class), any() /* anyString() doesn't match null */, any(NetworkState[].class), any() /* anyString() doesn't match null */,
argThat(vpnInfos -> vpnInfos[0].underlyingIfaces.length == 1 argThat(vpnInfos -> vpnInfos[0].underlyingIfaces.size() == 1
&& WIFI_IFNAME.equals(vpnInfos[0].underlyingIfaces[0]))); && WIFI_IFNAME.equals(vpnInfos[0].underlyingIfaces.get(0))));
mEthernetNetworkAgent.disconnect(); mEthernetNetworkAgent.disconnect();
waitForIdle(); waitForIdle();
reset(mStatsService); reset(mStatsService);
@@ -8323,8 +8326,9 @@ public class ConnectivityServiceTest {
assertVpnUidRangesUpdated(true, vpnRange, vpnOwnerUid); assertVpnUidRangesUpdated(true, vpnRange, vpnOwnerUid);
mMockVpn.setVpnType(vpnType); mMockVpn.setVpnType(vpnType);
final VpnInfo vpnInfo = new VpnInfo(vpnOwnerUid, null, null); final UnderlyingNetworkInfo underlyingNetworkInfo =
mMockVpn.setVpnInfo(vpnInfo); new UnderlyingNetworkInfo(vpnOwnerUid, VPN_IFNAME, new ArrayList<String>());
mMockVpn.setUnderlyingNetworkInfo(underlyingNetworkInfo);
} }
private void setupConnectionOwnerUidAsVpnApp(int vpnOwnerUid, @VpnManager.VpnType int vpnType) private void setupConnectionOwnerUidAsVpnApp(int vpnOwnerUid, @VpnManager.VpnType int vpnType)

View File

@@ -33,7 +33,9 @@ import static android.net.NetworkStats.TAG_NONE;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import android.net.NetworkStats; import android.net.NetworkStats;
import android.net.VpnInfo; import android.net.UnderlyingNetworkInfo;
import java.util.Arrays;
/** Superclass with utilities for NetworkStats(Service|Factory)Test */ /** Superclass with utilities for NetworkStats(Service|Factory)Test */
abstract class NetworkStatsBaseTest { abstract class NetworkStatsBaseTest {
@@ -107,11 +109,11 @@ abstract class NetworkStatsBaseTest {
assertEquals("unexpected operations", operations, entry.operations); assertEquals("unexpected operations", operations, entry.operations);
} }
static VpnInfo createVpnInfo(String[] underlyingIfaces) { static UnderlyingNetworkInfo createVpnInfo(String[] underlyingIfaces) {
return createVpnInfo(TUN_IFACE, underlyingIfaces); return createVpnInfo(TUN_IFACE, underlyingIfaces);
} }
static VpnInfo createVpnInfo(String vpnIface, String[] underlyingIfaces) { static UnderlyingNetworkInfo createVpnInfo(String vpnIface, String[] underlyingIfaces) {
return new VpnInfo(UID_VPN, vpnIface, underlyingIfaces); return new UnderlyingNetworkInfo(UID_VPN, vpnIface, Arrays.asList(underlyingIfaces));
} }
} }

View File

@@ -36,7 +36,7 @@ import static org.junit.Assert.fail;
import android.content.res.Resources; import android.content.res.Resources;
import android.net.NetworkStats; import android.net.NetworkStats;
import android.net.TrafficStats; import android.net.TrafficStats;
import android.net.VpnInfo; import android.net.UnderlyingNetworkInfo;
import androidx.test.InstrumentationRegistry; import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
@@ -79,7 +79,7 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
// related to networkStatsFactory is compiled to a minimal native library and loaded here. // related to networkStatsFactory is compiled to a minimal native library and loaded here.
System.loadLibrary("networkstatsfactorytestjni"); System.loadLibrary("networkstatsfactorytestjni");
mFactory = new NetworkStatsFactory(mTestProc, false); mFactory = new NetworkStatsFactory(mTestProc, false);
mFactory.updateVpnInfos(new VpnInfo[0]); mFactory.updateUnderlyingNetworkInfos(new UnderlyingNetworkInfo[0]);
} }
@After @After
@@ -105,8 +105,9 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
@Test @Test
public void testVpnRewriteTrafficThroughItself() throws Exception { public void testVpnRewriteTrafficThroughItself() throws Exception {
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})}; UnderlyingNetworkInfo[] underlyingNetworkInfos =
mFactory.updateVpnInfos(vpnInfos); new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet): // overhead per packet):
@@ -134,8 +135,9 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
@Test @Test
public void testVpnWithClat() throws Exception { public void testVpnWithClat() throws Exception {
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {CLAT_PREFIX + TEST_IFACE})}; final UnderlyingNetworkInfo[] underlyingNetworkInfos = new UnderlyingNetworkInfo[] {
mFactory.updateVpnInfos(vpnInfos); createVpnInfo(new String[] {CLAT_PREFIX + TEST_IFACE})};
mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
mFactory.noteStackedIface(CLAT_PREFIX + TEST_IFACE, TEST_IFACE); mFactory.noteStackedIface(CLAT_PREFIX + TEST_IFACE, TEST_IFACE);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
@@ -167,8 +169,9 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
@Test @Test
public void testVpnWithOneUnderlyingIface() throws Exception { public void testVpnWithOneUnderlyingIface() throws Exception {
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})}; final UnderlyingNetworkInfo[] underlyingNetworkInfos =
mFactory.updateVpnInfos(vpnInfos); new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet): // overhead per packet):
@@ -191,8 +194,9 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
@Test @Test
public void testVpnWithOneUnderlyingIfaceAndOwnTraffic() throws Exception { public void testVpnWithOneUnderlyingIfaceAndOwnTraffic() throws Exception {
// WiFi network is connected and VPN is using WiFi (which has TEST_IFACE). // WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})}; final UnderlyingNetworkInfo[] underlyingNetworkInfos =
mFactory.updateVpnInfos(vpnInfos); new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet): // overhead per packet):
@@ -219,8 +223,9 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
@Test @Test
public void testVpnWithOneUnderlyingIface_withCompression() throws Exception { public void testVpnWithOneUnderlyingIface_withCompression() throws Exception {
// WiFi network is connected and VPN is using WiFi (which has TEST_IFACE). // WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})}; final UnderlyingNetworkInfo[] underlyingNetworkInfos =
mFactory.updateVpnInfos(vpnInfos); new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet): // overhead per packet):
@@ -242,8 +247,9 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
// WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and // 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. // Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
// Additionally, VPN is duplicating traffic across both WiFi and Cell. // Additionally, VPN is duplicating traffic across both WiFi and Cell.
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})}; final UnderlyingNetworkInfo[] underlyingNetworkInfos =
mFactory.updateVpnInfos(vpnInfos); new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet): // overhead per packet):
@@ -267,10 +273,10 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
public void testConcurrentVpns() throws Exception { public void testConcurrentVpns() throws Exception {
// Assume two VPNs are connected on two different network interfaces. VPN1 is using // Assume two VPNs are connected on two different network interfaces. VPN1 is using
// TEST_IFACE and VPN2 is using TEST_IFACE2. // TEST_IFACE and VPN2 is using TEST_IFACE2.
final VpnInfo[] vpnInfos = new VpnInfo[] { final UnderlyingNetworkInfo[] underlyingNetworkInfos = new UnderlyingNetworkInfo[] {
createVpnInfo(TUN_IFACE, new String[] {TEST_IFACE}), createVpnInfo(TUN_IFACE, new String[] {TEST_IFACE}),
createVpnInfo(TUN_IFACE2, new String[] {TEST_IFACE2})}; createVpnInfo(TUN_IFACE2, new String[] {TEST_IFACE2})};
mFactory.updateVpnInfos(vpnInfos); mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet): // overhead per packet):
@@ -308,8 +314,9 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
// WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and // 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. // Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
// Additionally, VPN is arbitrarily splitting traffic across WiFi and Cell. // Additionally, VPN is arbitrarily splitting traffic across WiFi and Cell.
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})}; final UnderlyingNetworkInfo[] underlyingNetworkInfos =
mFactory.updateVpnInfos(vpnInfos); new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet): // overhead per packet):
@@ -335,8 +342,9 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
// WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and // 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. // Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
// Additionally, VPN is arbitrarily splitting compressed traffic across WiFi and Cell. // Additionally, VPN is arbitrarily splitting compressed traffic across WiFi and Cell.
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})}; final UnderlyingNetworkInfo[] underlyingNetworkInfos =
mFactory.updateVpnInfos(vpnInfos); new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface: // create some traffic (assume 10 bytes of MTU for VPN interface:
// 1000 bytes (100 packets) were sent/received by UID_RED over VPN. // 1000 bytes (100 packets) were sent/received by UID_RED over VPN.
@@ -357,8 +365,9 @@ public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
public void testVpnWithIncorrectUnderlyingIface() throws Exception { public void testVpnWithIncorrectUnderlyingIface() throws Exception {
// WiFi and Cell networks are connected and VPN is using Cell (which has TEST_IFACE2), // WiFi and Cell networks are connected and VPN is using Cell (which has TEST_IFACE2),
// but has declared only WiFi (TEST_IFACE) in its underlying network set. // but has declared only WiFi (TEST_IFACE) in its underlying network set.
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})}; final UnderlyingNetworkInfo[] underlyingNetworkInfos =
mFactory.updateVpnInfos(vpnInfos); new UnderlyingNetworkInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
mFactory.updateUnderlyingNetworkInfos(underlyingNetworkInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet): // overhead per packet):

View File

@@ -86,7 +86,7 @@ import android.net.NetworkState;
import android.net.NetworkStats; import android.net.NetworkStats;
import android.net.NetworkStatsHistory; import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate; import android.net.NetworkTemplate;
import android.net.VpnInfo; import android.net.UnderlyingNetworkInfo;
import android.net.netstats.provider.INetworkStatsProviderCallback; import android.net.netstats.provider.INetworkStatsProviderCallback;
import android.os.ConditionVariable; import android.os.ConditionVariable;
import android.os.Handler; import android.os.Handler;
@@ -286,7 +286,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// verify service has empty history for wifi // verify service has empty history for wifi
assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0); assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
@@ -328,7 +329,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// verify service has empty history for wifi // verify service has empty history for wifi
assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0); assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
@@ -401,7 +403,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// modify some number on wifi, and trigger poll event // modify some number on wifi, and trigger poll event
incrementCurrentTime(2 * HOUR_IN_MILLIS); incrementCurrentTime(2 * HOUR_IN_MILLIS);
@@ -441,7 +444,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]); mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// create some traffic on first network // create some traffic on first network
incrementCurrentTime(HOUR_IN_MILLIS); incrementCurrentTime(HOUR_IN_MILLIS);
@@ -475,7 +479,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L) .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
.insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L)); .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]); mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
forcePollAndWaitForIdle(); forcePollAndWaitForIdle();
@@ -514,7 +519,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// create some traffic // create some traffic
incrementCurrentTime(HOUR_IN_MILLIS); incrementCurrentTime(HOUR_IN_MILLIS);
@@ -581,7 +587,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_UMTS); setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_UMTS);
mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
new VpnInfo[0]); new UnderlyingNetworkInfo[0]);
// Create some traffic. // Create some traffic.
incrementCurrentTime(MINUTE_IN_MILLIS); incrementCurrentTime(MINUTE_IN_MILLIS);
@@ -655,7 +661,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// create some traffic for two apps // create some traffic for two apps
incrementCurrentTime(HOUR_IN_MILLIS); incrementCurrentTime(HOUR_IN_MILLIS);
@@ -713,7 +720,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
NetworkStats.Entry entry1 = new NetworkStats.Entry( NetworkStats.Entry entry1 = new NetworkStats.Entry(
TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L); TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L);
@@ -756,7 +764,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
NetworkStats.Entry uidStats = new NetworkStats.Entry( NetworkStats.Entry uidStats = new NetworkStats.Entry(
TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xF00D, 1024L, 8L, 512L, 4L, 0L); TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xF00D, 1024L, 8L, 512L, 4L, 0L);
@@ -810,7 +819,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// create some initial traffic // create some initial traffic
incrementCurrentTime(HOUR_IN_MILLIS); incrementCurrentTime(HOUR_IN_MILLIS);
@@ -867,7 +877,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// create some initial traffic // create some initial traffic
incrementCurrentTime(HOUR_IN_MILLIS); incrementCurrentTime(HOUR_IN_MILLIS);
@@ -906,7 +917,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]); mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// Create some traffic // Create some traffic
incrementCurrentTime(HOUR_IN_MILLIS); incrementCurrentTime(HOUR_IN_MILLIS);
@@ -943,7 +955,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]); mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// create some tethering traffic // create some tethering traffic
incrementCurrentTime(HOUR_IN_MILLIS); incrementCurrentTime(HOUR_IN_MILLIS);
@@ -999,7 +1012,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// verify service has empty history for wifi // verify service has empty history for wifi
assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0); assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
@@ -1104,7 +1118,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
mService.registerNetworkStatsProvider("TEST", provider); mService.registerNetworkStatsProvider("TEST", provider);
assertNotNull(cb); assertNotNull(cb);
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// Verifies that one requestStatsUpdate will be called during iface update. // Verifies that one requestStatsUpdate will be called during iface update.
provider.expectOnRequestStatsUpdate(0 /* unused */); provider.expectOnRequestStatsUpdate(0 /* unused */);
@@ -1155,7 +1170,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
expectDefaultSettings(); expectDefaultSettings();
NetworkState[] states = NetworkState[] states =
new NetworkState[]{buildWifiState(true /* isMetered */, TEST_IFACE)}; new NetworkState[]{buildWifiState(true /* isMetered */, TEST_IFACE)};
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// Register custom provider and retrieve callback. // Register custom provider and retrieve callback.
final TestableNetworkStatsProviderBinder provider = final TestableNetworkStatsProviderBinder provider =
@@ -1204,7 +1220,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
// 3G network comes online. // 3G network comes online.
setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_UMTS); setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_UMTS);
mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
new VpnInfo[0]); new UnderlyingNetworkInfo[0]);
// Create some traffic. // Create some traffic.
incrementCurrentTime(MINUTE_IN_MILLIS); incrementCurrentTime(MINUTE_IN_MILLIS);
@@ -1274,7 +1290,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
NetworkState[] states = new NetworkState[]{ NetworkState[] states = new NetworkState[]{
buildWifiState(true /*isMetered*/, TEST_IFACE2), buildMobile3gState(IMSI_1)}; buildWifiState(true /*isMetered*/, TEST_IFACE2), buildMobile3gState(IMSI_1)};
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// Create some traffic on mobile network. // Create some traffic on mobile network.
incrementCurrentTime(HOUR_IN_MILLIS); incrementCurrentTime(HOUR_IN_MILLIS);