Make MockVpn more realistic and easier to use.

MockVpn is very difficult to use because it requires the test
caller keeping track of both the MockVpn object and an
accompanying TestNetworkAgentWrapper.

It's also not very realistic: for example, connect() doesn't
actually connect anything, it just makes it so that if
ConnectivityService tries to update the capabilities, the attempt
will not be ignored. Also, unlike the real code in Vpn, it
connects with empty NetworkCapabilities (in particular, with
empty UID ranges).

Make this easier to use and a bit more realistic by:
- Allowing TestNetworkAgentWrapper to take a "NetworkCapabilities
  template" that will form the initial capabilities sent when the
  agent registers with ConnectivityService. This allows the VPN
  to register its agent with its UID ranges already set, like the
  production code does.
- Providing separate methods to register the NetworkAgent and
  mark it connected for cases where the test needs to make
  changes to the NetworkAgent before connecting (e.g., poking
  NetworkMonitor).
- Putting the TestNetworkAgentWrapper inside MockVpn and driving
  it through MockVpn's methods. In order not to have too many
  wrapper functions (and because we can't delegate like in
  Kotlin), there's still an agent() method that returns the
  TestNetworkAgentWrapper.

Bug: 173331190
Test: test-only change
Change-Id: I749ff325bc13ac96f512270b86d1f67686eec378
This commit is contained in:
Lorenzo Colitti
2020-11-18 22:50:57 +09:00
parent e42d10a803
commit 4489abdb15
3 changed files with 227 additions and 298 deletions

View File

@@ -200,7 +200,8 @@ class ConnectivityServiceIntegrationTest {
nsInstrumentation.addHttpResponse(HttpResponse(httpProbeUrl, responseCode = 204)) nsInstrumentation.addHttpResponse(HttpResponse(httpProbeUrl, responseCode = 204))
nsInstrumentation.addHttpResponse(HttpResponse(httpsProbeUrl, responseCode = 204)) nsInstrumentation.addHttpResponse(HttpResponse(httpsProbeUrl, responseCode = 204))
val na = NetworkAgentWrapper(TRANSPORT_CELLULAR, LinkProperties(), context) val na = NetworkAgentWrapper(TRANSPORT_CELLULAR, LinkProperties(), null /* ncTemplate */,
context)
networkStackClient.verifyNetworkMonitorCreated(na.network, TEST_TIMEOUT_MS) networkStackClient.verifyNetworkMonitorCreated(na.network, TEST_TIMEOUT_MS)
na.addCapability(NET_CAPABILITY_INTERNET) na.addCapability(NET_CAPABILITY_INTERNET)
@@ -238,7 +239,7 @@ class ConnectivityServiceIntegrationTest {
val lp = LinkProperties() val lp = LinkProperties()
lp.captivePortalApiUrl = Uri.parse(apiUrl) lp.captivePortalApiUrl = Uri.parse(apiUrl)
val na = NetworkAgentWrapper(TRANSPORT_CELLULAR, lp, context) val na = NetworkAgentWrapper(TRANSPORT_CELLULAR, lp, null /* ncTemplate */, context)
networkStackClient.verifyNetworkMonitorCreated(na.network, TEST_TIMEOUT_MS) networkStackClient.verifyNetworkMonitorCreated(na.network, TEST_TIMEOUT_MS)
na.addCapability(NET_CAPABILITY_INTERNET) na.addCapability(NET_CAPABILITY_INTERNET)

View File

@@ -72,12 +72,12 @@ public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork {
private long mKeepaliveResponseDelay = 0L; private long mKeepaliveResponseDelay = 0L;
private Integer mExpectedKeepaliveSlot = null; private Integer mExpectedKeepaliveSlot = null;
public NetworkAgentWrapper(int transport, LinkProperties linkProperties, Context context) public NetworkAgentWrapper(int transport, LinkProperties linkProperties,
throws Exception { NetworkCapabilities ncTemplate, Context context) throws Exception {
final int type = transportToLegacyType(transport); final int type = transportToLegacyType(transport);
final String typeName = ConnectivityManager.getNetworkTypeName(type); final String typeName = ConnectivityManager.getNetworkTypeName(type);
mNetworkInfo = new NetworkInfo(type, 0, typeName, "Mock"); mNetworkInfo = new NetworkInfo(type, 0, typeName, "Mock");
mNetworkCapabilities = new NetworkCapabilities(); mNetworkCapabilities = (ncTemplate != null) ? ncTemplate : new NetworkCapabilities();
mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_SUSPENDED); mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
mNetworkCapabilities.addTransportType(transport); mNetworkCapabilities.addTransportType(transport);
switch (transport) { switch (transport) {

View File

@@ -619,12 +619,17 @@ public class ConnectivityServiceTest {
private String mRedirectUrl; private String mRedirectUrl;
TestNetworkAgentWrapper(int transport) throws Exception { TestNetworkAgentWrapper(int transport) throws Exception {
this(transport, new LinkProperties()); this(transport, new LinkProperties(), null);
} }
TestNetworkAgentWrapper(int transport, LinkProperties linkProperties) TestNetworkAgentWrapper(int transport, LinkProperties linkProperties)
throws Exception { throws Exception {
super(transport, linkProperties, mServiceContext); this(transport, linkProperties, null);
}
private TestNetworkAgentWrapper(int transport, LinkProperties linkProperties,
NetworkCapabilities ncTemplate) throws Exception {
super(transport, linkProperties, ncTemplate, mServiceContext);
// Waits for the NetworkAgent to be registered, which includes the creation of the // Waits for the NetworkAgent to be registered, which includes the creation of the
// NetworkMonitor. // NetworkMonitor.
@@ -1019,30 +1024,26 @@ public class ConnectivityServiceTest {
} }
} }
private Set<UidRange> uidRangesForUid(int uid) {
final ArraySet<UidRange> ranges = new ArraySet<>();
ranges.add(new UidRange(uid, uid));
return ranges;
}
private static Looper startHandlerThreadAndReturnLooper() { private static Looper startHandlerThreadAndReturnLooper() {
final HandlerThread handlerThread = new HandlerThread("MockVpnThread"); final HandlerThread handlerThread = new HandlerThread("MockVpnThread");
handlerThread.start(); handlerThread.start();
return handlerThread.getLooper(); return handlerThread.getLooper();
} }
private class MockVpn extends Vpn { private class MockVpn extends Vpn implements TestableNetworkCallback.HasNetwork {
// TODO : the interactions between this mock and the mock network agent are too
// hard to get right at this moment, because it's unclear in which case which
// target needs to get a method call or both, and in what order. It's because
// MockNetworkAgent wants to manage its own NetworkCapabilities, but the Vpn
// parent class of MockVpn agent wants that responsibility.
// That being said inside the test it should be possible to make the interactions
// harder to get wrong with precise speccing, judicious comments, helper methods
// and a few sprinkled assertions.
private boolean mConnected = false;
// Careful ! This is different from mNetworkAgent, because MockNetworkAgent does // Careful ! This is different from mNetworkAgent, because MockNetworkAgent does
// not inherit from NetworkAgent. // not inherit from NetworkAgent.
private TestNetworkAgentWrapper mMockNetworkAgent; private TestNetworkAgentWrapper mMockNetworkAgent;
private int mVpnType = VpnManager.TYPE_VPN_SERVICE; private boolean mAgentRegistered = false;
private int mVpnType = VpnManager.TYPE_VPN_SERVICE;
private VpnInfo mVpnInfo; private VpnInfo mVpnInfo;
private Network[] mUnderlyingNetworks;
public MockVpn(int userId) { public MockVpn(int userId) {
super(startHandlerThreadAndReturnLooper(), mServiceContext, mNetworkManagementService, super(startHandlerThreadAndReturnLooper(), mServiceContext, mNetworkManagementService,
@@ -1050,29 +1051,23 @@ public class ConnectivityServiceTest {
mConfig = new VpnConfig(); mConfig = new VpnConfig();
} }
public void setNetworkAgent(TestNetworkAgentWrapper agent) {
agent.waitForIdle(TIMEOUT_MS);
mMockNetworkAgent = agent;
mNetworkAgent = agent.getNetworkAgent();
mInterface = VPN_IFNAME;
mNetworkCapabilities.set(agent.getNetworkCapabilities());
}
public void setUids(Set<UidRange> uids) { public void setUids(Set<UidRange> uids) {
mNetworkCapabilities.setUids(uids); mNetworkCapabilities.setUids(uids);
updateCapabilities(null /* defaultNetwork */); updateCapabilitiesInternal(null /* defaultNetwork */, true);
} }
public void setVpnType(int vpnType) { public void setVpnType(int vpnType) {
mVpnType = vpnType; mVpnType = vpnType;
} }
@Override
public Network getNetwork() {
return (mMockNetworkAgent == null) ? null : mMockNetworkAgent.getNetwork();
}
@Override @Override
public int getNetId() { public int getNetId() {
if (mMockNetworkAgent == null) { return (mMockNetworkAgent == null) ? NETID_UNSET : mMockNetworkAgent.getNetwork().netId;
return NETID_UNSET;
}
return mMockNetworkAgent.getNetwork().netId;
} }
@Override @Override
@@ -1080,39 +1075,94 @@ public class ConnectivityServiceTest {
return mVpnType; return mVpnType;
} }
private void connect(boolean isAlwaysMetered) { private void registerAgent(boolean isAlwaysMetered, Set<UidRange> uids, LinkProperties lp)
mNetworkCapabilities.set(mMockNetworkAgent.getNetworkCapabilities()); throws Exception {
mConnected = true; if (mAgentRegistered) throw new IllegalStateException("already registered");
setUids(uids);
mConfig.isMetered = isAlwaysMetered; mConfig.isMetered = isAlwaysMetered;
mInterface = VPN_IFNAME;
mMockNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN, lp,
mNetworkCapabilities);
mMockNetworkAgent.waitForIdle(TIMEOUT_MS);
mAgentRegistered = true;
mNetworkCapabilities.set(mMockNetworkAgent.getNetworkCapabilities());
mNetworkAgent = mMockNetworkAgent.getNetworkAgent();
} }
public void connectAsAlwaysMetered() { private void registerAgent(Set<UidRange> uids) throws Exception {
connect(true /* isAlwaysMetered */); registerAgent(false /* isAlwaysMetered */, uids, new LinkProperties());
} }
public void connect() { private void connect(boolean validated, boolean hasInternet, boolean isStrictMode) {
connect(false /* isAlwaysMetered */); mMockNetworkAgent.connect(validated, hasInternet, isStrictMode);
}
private void connect(boolean validated) {
mMockNetworkAgent.connect(validated);
}
private TestNetworkAgentWrapper getAgent() {
return mMockNetworkAgent;
}
public void establish(LinkProperties lp, int uid, Set<UidRange> ranges, boolean validated,
boolean hasInternet, boolean isStrictMode) throws Exception {
mNetworkCapabilities.setOwnerUid(uid);
mNetworkCapabilities.setAdministratorUids(new int[]{uid});
registerAgent(false, ranges, lp);
connect(validated, hasInternet, isStrictMode);
waitForIdle();
}
public void establish(LinkProperties lp, int uid, Set<UidRange> ranges) throws Exception {
establish(lp, uid, ranges, true, true, false);
}
public void establishForMyUid(LinkProperties lp) throws Exception {
final int uid = Process.myUid();
establish(lp, uid, uidRangesForUid(uid), true, true, false);
}
public void establishForMyUid(boolean validated, boolean hasInternet, boolean isStrictMode)
throws Exception {
final int uid = Process.myUid();
establish(new LinkProperties(), uid, uidRangesForUid(uid), validated, hasInternet,
isStrictMode);
}
public void establishForMyUid() throws Exception {
establishForMyUid(new LinkProperties());
}
public void sendLinkProperties(LinkProperties lp) {
mMockNetworkAgent.sendLinkProperties(lp);
}
private NetworkCapabilities updateCapabilitiesInternal(Network defaultNetwork,
boolean sendToConnectivityService) {
if (!mAgentRegistered) return null;
super.updateCapabilities(defaultNetwork);
// Because super.updateCapabilities will update the capabilities of the agent but
// not the mock agent, the mock agent needs to know about them.
copyCapabilitiesToNetworkAgent(sendToConnectivityService);
return new NetworkCapabilities(mNetworkCapabilities);
}
private void copyCapabilitiesToNetworkAgent(boolean sendToConnectivityService) {
if (null != mMockNetworkAgent) {
mMockNetworkAgent.setNetworkCapabilities(mNetworkCapabilities,
sendToConnectivityService);
}
} }
@Override @Override
public NetworkCapabilities updateCapabilities(Network defaultNetwork) { public NetworkCapabilities updateCapabilities(Network defaultNetwork) {
if (!mConnected) return null; return updateCapabilitiesInternal(defaultNetwork, false);
super.updateCapabilities(defaultNetwork);
// Because super.updateCapabilities will update the capabilities of the agent but
// not the mock agent, the mock agent needs to know about them.
copyCapabilitiesToNetworkAgent();
return new NetworkCapabilities(mNetworkCapabilities);
}
private void copyCapabilitiesToNetworkAgent() {
if (null != mMockNetworkAgent) {
mMockNetworkAgent.setNetworkCapabilities(mNetworkCapabilities,
false /* sendToConnectivityService */);
}
} }
public void disconnect() { public void disconnect() {
mConnected = false; if (mMockNetworkAgent != null) mMockNetworkAgent.disconnect();
mAgentRegistered = false;
} }
@Override @Override
@@ -1317,6 +1367,9 @@ public class ConnectivityServiceTest {
mEthernetNetworkAgent.disconnect(); mEthernetNetworkAgent.disconnect();
mEthernetNetworkAgent = null; mEthernetNetworkAgent = null;
} }
mMockVpn.disconnect();
waitForIdle();
FakeSettingsProvider.clearSettingsProvider(); FakeSettingsProvider.clearSettingsProvider();
mCsHandlerThread.quitSafely(); mCsHandlerThread.quitSafely();
@@ -3200,20 +3253,12 @@ public class ConnectivityServiceTest {
waitForIdle(); waitForIdle();
assertEquals(null, mCm.getActiveNetwork()); assertEquals(null, mCm.getActiveNetwork());
final int uid = Process.myUid(); mMockVpn.establishForMyUid();
final TestNetworkAgentWrapper defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN);
final ArraySet<UidRange> ranges = new ArraySet<>();
ranges.add(new UidRange(uid, uid));
mMockVpn.setNetworkAgent(vpnNetworkAgent);
mMockVpn.setUids(ranges);
vpnNetworkAgent.connect(true);
mMockVpn.connect();
defaultNetworkCallback.expectAvailableThenValidatedCallbacks(vpnNetworkAgent);
assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
vpnNetworkAgent.disconnect(); mMockVpn.disconnect();
defaultNetworkCallback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent); defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
waitForIdle(); waitForIdle();
assertEquals(null, mCm.getActiveNetwork()); assertEquals(null, mCm.getActiveNetwork());
} }
@@ -4892,9 +4937,10 @@ public class ConnectivityServiceTest {
final LinkProperties lp = new LinkProperties(); final LinkProperties lp = new LinkProperties();
lp.setInterfaceName(VPN_IFNAME); lp.setInterfaceName(VPN_IFNAME);
final NetworkAgentWrapper vpnNetworkAgent = establishVpnForMyUid(lp); mMockVpn.establishForMyUid(lp);
final Network[] cellAndVpn = new Network[] { final Network[] cellAndVpn = new Network[] {
mCellNetworkAgent.getNetwork(), vpnNetworkAgent.getNetwork()}; mCellNetworkAgent.getNetwork(), mMockVpn.getNetwork()};
Network[] cellAndWifi = new Network[] { Network[] cellAndWifi = new Network[] {
mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork()}; mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork()};
@@ -4907,7 +4953,7 @@ public class ConnectivityServiceTest {
mWiFiNetworkAgent.connect(false); mWiFiNetworkAgent.connect(false);
mWiFiNetworkAgent.sendLinkProperties(wifiLp); mWiFiNetworkAgent.sendLinkProperties(wifiLp);
final Network[] wifiAndVpn = new Network[] { final Network[] wifiAndVpn = new Network[] {
mWiFiNetworkAgent.getNetwork(), vpnNetworkAgent.getNetwork()}; mWiFiNetworkAgent.getNetwork(), mMockVpn.getNetwork()};
cellAndWifi = new Network[] { cellAndWifi = new Network[] {
mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork()}; mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork()};
@@ -5346,22 +5392,13 @@ public class ConnectivityServiceTest {
// Note: it's sort of meaningless for a VPN app to declare a network that doesn't exist yet, // Note: it's sort of meaningless for a VPN app to declare a network that doesn't exist yet,
// (and doing so is difficult without using reflection) but it's good to test that the code // (and doing so is difficult without using reflection) but it's good to test that the code
// behaves approximately correctly. // behaves approximately correctly.
final int uid = Process.myUid(); mMockVpn.establishForMyUid(false, true, false);
final TestNetworkAgentWrapper
vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN);
final ArraySet<UidRange> ranges = new ArraySet<>();
ranges.add(new UidRange(uid, uid));
final Network wifiNetwork = new Network(mNetIdManager.peekNextNetId()); final Network wifiNetwork = new Network(mNetIdManager.peekNextNetId());
mMockVpn.setNetworkAgent(vpnNetworkAgent);
mMockVpn.setUids(ranges);
mService.setUnderlyingNetworksForVpn(new Network[]{wifiNetwork}); mService.setUnderlyingNetworksForVpn(new Network[]{wifiNetwork});
vpnNetworkAgent.connect(false); callback.expectAvailableCallbacksUnvalidated(mMockVpn);
mMockVpn.connect(); assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork())
callback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent);
assertTrue(mCm.getNetworkCapabilities(vpnNetworkAgent.getNetwork())
.hasTransport(TRANSPORT_VPN)); .hasTransport(TRANSPORT_VPN));
assertFalse(mCm.getNetworkCapabilities(vpnNetworkAgent.getNetwork()) assertFalse(mCm.getNetworkCapabilities(mMockVpn.getNetwork())
.hasTransport(TRANSPORT_WIFI)); .hasTransport(TRANSPORT_WIFI));
// Make that underlying network connect, and expect to see its capabilities immediately // Make that underlying network connect, and expect to see its capabilities immediately
@@ -5378,20 +5415,20 @@ public class ConnectivityServiceTest {
// 2. When a network connects, updateNetworkInfo propagates underlying network capabilities // 2. When a network connects, updateNetworkInfo propagates underlying network capabilities
// before rematching networks. // before rematching networks.
// Given that this scenario can't really happen, this is probably fine for now. // Given that this scenario can't really happen, this is probably fine for now.
callback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, vpnNetworkAgent); callback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn);
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
assertTrue(mCm.getNetworkCapabilities(vpnNetworkAgent.getNetwork()) assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork())
.hasTransport(TRANSPORT_VPN)); .hasTransport(TRANSPORT_VPN));
assertTrue(mCm.getNetworkCapabilities(vpnNetworkAgent.getNetwork()) assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork())
.hasTransport(TRANSPORT_WIFI)); .hasTransport(TRANSPORT_WIFI));
// Disconnect the network, and expect to see the VPN capabilities change accordingly. // Disconnect the network, and expect to see the VPN capabilities change accordingly.
mWiFiNetworkAgent.disconnect(); mWiFiNetworkAgent.disconnect();
callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
callback.expectCapabilitiesThat(vpnNetworkAgent, (nc) -> callback.expectCapabilitiesThat(mMockVpn, (nc) ->
nc.getTransportTypes().length == 1 && nc.hasTransport(TRANSPORT_VPN)); nc.getTransportTypes().length == 1 && nc.hasTransport(TRANSPORT_VPN));
vpnNetworkAgent.disconnect(); mMockVpn.disconnect();
mCm.unregisterNetworkCallback(callback); mCm.unregisterNetworkCallback(callback);
} }
@@ -5429,42 +5466,38 @@ public class ConnectivityServiceTest {
vpnNetworkCallback.assertNoCallback(); vpnNetworkCallback.assertNoCallback();
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
final TestNetworkAgentWrapper final Set<UidRange> ranges = uidRangesForUid(uid);
vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN); mMockVpn.registerAgent(ranges);
final ArraySet<UidRange> ranges = new ArraySet<>();
ranges.add(new UidRange(uid, uid));
mMockVpn.setNetworkAgent(vpnNetworkAgent);
mMockVpn.setUids(ranges);
// VPN networks do not satisfy the default request and are automatically validated // VPN networks do not satisfy the default request and are automatically validated
// by NetworkMonitor // by NetworkMonitor
assertFalse(NetworkMonitorUtils.isValidationRequired( assertFalse(NetworkMonitorUtils.isValidationRequired(
vpnNetworkAgent.getNetworkCapabilities())); mMockVpn.getAgent().getNetworkCapabilities()));
vpnNetworkAgent.setNetworkValid(false /* isStrictMode */); mMockVpn.getAgent().setNetworkValid(false /* isStrictMode */);
vpnNetworkAgent.connect(false); mMockVpn.connect(false);
mMockVpn.connect();
mService.setUnderlyingNetworksForVpn(new Network[0]); mService.setUnderlyingNetworksForVpn(new Network[0]);
genericNetworkCallback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent); genericNetworkCallback.expectAvailableCallbacksUnvalidated(mMockVpn);
genericNotVpnNetworkCallback.assertNoCallback(); genericNotVpnNetworkCallback.assertNoCallback();
wifiNetworkCallback.assertNoCallback(); wifiNetworkCallback.assertNoCallback();
vpnNetworkCallback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent); vpnNetworkCallback.expectAvailableCallbacksUnvalidated(mMockVpn);
defaultCallback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent); defaultCallback.expectAvailableCallbacksUnvalidated(mMockVpn);
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
genericNetworkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, vpnNetworkAgent); genericNetworkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn);
genericNotVpnNetworkCallback.assertNoCallback(); genericNotVpnNetworkCallback.assertNoCallback();
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, nc -> null == nc.getUids()); vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, nc -> null == nc.getUids());
defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, vpnNetworkAgent); defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn);
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
ranges.clear(); ranges.clear();
vpnNetworkAgent.setUids(ranges); mMockVpn.setUids(ranges);
genericNetworkCallback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent); genericNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
genericNotVpnNetworkCallback.assertNoCallback(); genericNotVpnNetworkCallback.assertNoCallback();
wifiNetworkCallback.assertNoCallback(); wifiNetworkCallback.assertNoCallback();
vpnNetworkCallback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent); vpnNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
// TODO : The default network callback should actually get a LOST call here (also see the // TODO : The default network callback should actually get a LOST call here (also see the
// comment below for AVAILABLE). This is because ConnectivityService does not look at UID // comment below for AVAILABLE). This is because ConnectivityService does not look at UID
@@ -5472,19 +5505,18 @@ public class ConnectivityServiceTest {
// can't currently update their UIDs without disconnecting, so this does not matter too // can't currently update their UIDs without disconnecting, so this does not matter too
// much, but that is the reason the test here has to check for an update to the // much, but that is the reason the test here has to check for an update to the
// capabilities instead of the expected LOST then AVAILABLE. // capabilities instead of the expected LOST then AVAILABLE.
defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, vpnNetworkAgent); defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn);
ranges.add(new UidRange(uid, uid)); ranges.add(new UidRange(uid, uid));
mMockVpn.setUids(ranges); mMockVpn.setUids(ranges);
vpnNetworkAgent.setUids(ranges);
genericNetworkCallback.expectAvailableCallbacksValidated(vpnNetworkAgent); genericNetworkCallback.expectAvailableCallbacksValidated(mMockVpn);
genericNotVpnNetworkCallback.assertNoCallback(); genericNotVpnNetworkCallback.assertNoCallback();
wifiNetworkCallback.assertNoCallback(); wifiNetworkCallback.assertNoCallback();
vpnNetworkCallback.expectAvailableCallbacksValidated(vpnNetworkAgent); vpnNetworkCallback.expectAvailableCallbacksValidated(mMockVpn);
// TODO : Here like above, AVAILABLE would be correct, but because this can't actually // TODO : Here like above, AVAILABLE would be correct, but because this can't actually
// happen outside of the test, ConnectivityService does not rematch callbacks. // happen outside of the test, ConnectivityService does not rematch callbacks.
defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, vpnNetworkAgent); defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn);
mWiFiNetworkAgent.disconnect(); mWiFiNetworkAgent.disconnect();
@@ -5494,13 +5526,13 @@ public class ConnectivityServiceTest {
vpnNetworkCallback.assertNoCallback(); vpnNetworkCallback.assertNoCallback();
defaultCallback.assertNoCallback(); defaultCallback.assertNoCallback();
vpnNetworkAgent.disconnect(); mMockVpn.disconnect();
genericNetworkCallback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent); genericNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
genericNotVpnNetworkCallback.assertNoCallback(); genericNotVpnNetworkCallback.assertNoCallback();
wifiNetworkCallback.assertNoCallback(); wifiNetworkCallback.assertNoCallback();
vpnNetworkCallback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent); vpnNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
defaultCallback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent); defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
assertEquals(null, mCm.getActiveNetwork()); assertEquals(null, mCm.getActiveNetwork());
mCm.unregisterNetworkCallback(genericNetworkCallback); mCm.unregisterNetworkCallback(genericNetworkCallback);
@@ -5522,20 +5554,13 @@ public class ConnectivityServiceTest {
defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent);
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
TestNetworkAgentWrapper mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */,
vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN);
final ArraySet<UidRange> ranges = new ArraySet<>();
ranges.add(new UidRange(uid, uid));
mMockVpn.setNetworkAgent(vpnNetworkAgent);
mMockVpn.setUids(ranges);
vpnNetworkAgent.connect(true /* validated */, false /* hasInternet */,
false /* isStrictMode */); false /* isStrictMode */);
mMockVpn.connect();
defaultCallback.assertNoCallback(); defaultCallback.assertNoCallback();
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
vpnNetworkAgent.disconnect(); mMockVpn.disconnect();
defaultCallback.assertNoCallback(); defaultCallback.assertNoCallback();
mCm.unregisterNetworkCallback(defaultCallback); mCm.unregisterNetworkCallback(defaultCallback);
@@ -5554,21 +5579,14 @@ public class ConnectivityServiceTest {
defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent);
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
TestNetworkAgentWrapper mMockVpn.establishForMyUid(true /* validated */, true /* hasInternet */,
vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN);
final ArraySet<UidRange> ranges = new ArraySet<>();
ranges.add(new UidRange(uid, uid));
mMockVpn.setNetworkAgent(vpnNetworkAgent);
mMockVpn.setUids(ranges);
vpnNetworkAgent.connect(true /* validated */, true /* hasInternet */,
false /* isStrictMode */); false /* isStrictMode */);
mMockVpn.connect();
defaultCallback.expectAvailableThenValidatedCallbacks(vpnNetworkAgent); defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
vpnNetworkAgent.disconnect(); mMockVpn.disconnect();
defaultCallback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent); defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
defaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); defaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
mCm.unregisterNetworkCallback(defaultCallback); mCm.unregisterNetworkCallback(defaultCallback);
@@ -5586,44 +5604,36 @@ public class ConnectivityServiceTest {
callback.assertNoCallback(); callback.assertNoCallback();
// Bring up a VPN that has the INTERNET capability, initially unvalidated. // Bring up a VPN that has the INTERNET capability, initially unvalidated.
final int uid = Process.myUid(); mMockVpn.establishForMyUid(false /* validated */, true /* hasInternet */,
final TestNetworkAgentWrapper
vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN);
final ArraySet<UidRange> ranges = new ArraySet<>();
ranges.add(new UidRange(uid, uid));
mMockVpn.setNetworkAgent(vpnNetworkAgent);
mMockVpn.setUids(ranges);
vpnNetworkAgent.connect(false /* validated */, true /* hasInternet */,
false /* isStrictMode */); false /* isStrictMode */);
mMockVpn.connect();
// Even though the VPN is unvalidated, it becomes the default network for our app. // Even though the VPN is unvalidated, it becomes the default network for our app.
callback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent); callback.expectAvailableCallbacksUnvalidated(mMockVpn);
callback.assertNoCallback(); callback.assertNoCallback();
assertTrue(vpnNetworkAgent.getScore() > mEthernetNetworkAgent.getScore()); assertTrue(mMockVpn.getAgent().getScore() > mEthernetNetworkAgent.getScore());
assertEquals(ConnectivityConstants.VPN_DEFAULT_SCORE, vpnNetworkAgent.getScore()); assertEquals(ConnectivityConstants.VPN_DEFAULT_SCORE, mMockVpn.getAgent().getScore());
assertEquals(vpnNetworkAgent.getNetwork(), mCm.getActiveNetwork()); assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork());
NetworkCapabilities nc = mCm.getNetworkCapabilities(vpnNetworkAgent.getNetwork()); NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork());
assertFalse(nc.hasCapability(NET_CAPABILITY_VALIDATED)); assertFalse(nc.hasCapability(NET_CAPABILITY_VALIDATED));
assertTrue(nc.hasCapability(NET_CAPABILITY_INTERNET)); assertTrue(nc.hasCapability(NET_CAPABILITY_INTERNET));
assertFalse(NetworkMonitorUtils.isValidationRequired( assertFalse(NetworkMonitorUtils.isValidationRequired(
vpnNetworkAgent.getNetworkCapabilities())); mMockVpn.getAgent().getNetworkCapabilities()));
assertTrue(NetworkMonitorUtils.isPrivateDnsValidationRequired( assertTrue(NetworkMonitorUtils.isPrivateDnsValidationRequired(
vpnNetworkAgent.getNetworkCapabilities())); mMockVpn.getAgent().getNetworkCapabilities()));
// Pretend that the VPN network validates. // Pretend that the VPN network validates.
vpnNetworkAgent.setNetworkValid(false /* isStrictMode */); mMockVpn.getAgent().setNetworkValid(false /* isStrictMode */);
vpnNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); mMockVpn.getAgent().mNetworkMonitor.forceReevaluation(Process.myUid());
// Expect to see the validated capability, but no other changes, because the VPN is already // Expect to see the validated capability, but no other changes, because the VPN is already
// the default network for the app. // the default network for the app.
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, vpnNetworkAgent); callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mMockVpn);
callback.assertNoCallback(); callback.assertNoCallback();
vpnNetworkAgent.disconnect(); mMockVpn.disconnect();
callback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent); callback.expectCallback(CallbackEntry.LOST, mMockVpn);
callback.expectAvailableCallbacksValidated(mEthernetNetworkAgent); callback.expectAvailableCallbacksValidated(mEthernetNetworkAgent);
} }
@@ -5645,21 +5655,15 @@ public class ConnectivityServiceTest {
mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
mCellNetworkAgent.connect(true); mCellNetworkAgent.connect(true);
final TestNetworkAgentWrapper vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN); mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */,
final ArraySet<UidRange> ranges = new ArraySet<>();
ranges.add(new UidRange(uid, uid));
mMockVpn.setNetworkAgent(vpnNetworkAgent);
mMockVpn.connect();
mMockVpn.setUids(ranges);
vpnNetworkAgent.connect(true /* validated */, false /* hasInternet */,
false /* isStrictMode */); false /* isStrictMode */);
vpnNetworkCallback.expectAvailableCallbacks(vpnNetworkAgent.getNetwork(), vpnNetworkCallback.expectAvailableCallbacks(mMockVpn.getNetwork(),
false /* suspended */, false /* validated */, false /* blocked */, TIMEOUT_MS); false /* suspended */, false /* validated */, false /* blocked */, TIMEOUT_MS);
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent.getNetwork(), TIMEOUT_MS, vpnNetworkCallback.expectCapabilitiesThat(mMockVpn.getNetwork(), TIMEOUT_MS,
nc -> nc.hasCapability(NET_CAPABILITY_VALIDATED)); nc -> nc.hasCapability(NET_CAPABILITY_VALIDATED));
final NetworkCapabilities nc = mCm.getNetworkCapabilities(vpnNetworkAgent.getNetwork()); final NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork());
assertTrue(nc.hasTransport(TRANSPORT_VPN)); assertTrue(nc.hasTransport(TRANSPORT_VPN));
assertTrue(nc.hasTransport(TRANSPORT_CELLULAR)); assertTrue(nc.hasTransport(TRANSPORT_CELLULAR));
assertFalse(nc.hasTransport(TRANSPORT_WIFI)); assertFalse(nc.hasTransport(TRANSPORT_WIFI));
@@ -5681,18 +5685,11 @@ public class ConnectivityServiceTest {
mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback);
vpnNetworkCallback.assertNoCallback(); vpnNetworkCallback.assertNoCallback();
final TestNetworkAgentWrapper mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */,
vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN);
final ArraySet<UidRange> ranges = new ArraySet<>();
ranges.add(new UidRange(uid, uid));
mMockVpn.setNetworkAgent(vpnNetworkAgent);
mMockVpn.connect();
mMockVpn.setUids(ranges);
vpnNetworkAgent.connect(true /* validated */, false /* hasInternet */,
false /* isStrictMode */); false /* isStrictMode */);
vpnNetworkCallback.expectAvailableThenValidatedCallbacks(vpnNetworkAgent); vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
nc = mCm.getNetworkCapabilities(vpnNetworkAgent.getNetwork()); nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork());
assertTrue(nc.hasTransport(TRANSPORT_VPN)); assertTrue(nc.hasTransport(TRANSPORT_VPN));
assertFalse(nc.hasTransport(TRANSPORT_CELLULAR)); assertFalse(nc.hasTransport(TRANSPORT_CELLULAR));
assertFalse(nc.hasTransport(TRANSPORT_WIFI)); assertFalse(nc.hasTransport(TRANSPORT_WIFI));
@@ -5709,7 +5706,7 @@ public class ConnectivityServiceTest {
mService.setUnderlyingNetworksForVpn( mService.setUnderlyingNetworksForVpn(
new Network[] { mCellNetworkAgent.getNetwork() }); new Network[] { mCellNetworkAgent.getNetwork() });
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, vpnNetworkCallback.expectCapabilitiesThat(mMockVpn,
(caps) -> caps.hasTransport(TRANSPORT_VPN) (caps) -> caps.hasTransport(TRANSPORT_VPN)
&& caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI)
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED) && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
@@ -5723,7 +5720,7 @@ public class ConnectivityServiceTest {
mService.setUnderlyingNetworksForVpn( mService.setUnderlyingNetworksForVpn(
new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() }); new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() });
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, vpnNetworkCallback.expectCapabilitiesThat(mMockVpn,
(caps) -> caps.hasTransport(TRANSPORT_VPN) (caps) -> caps.hasTransport(TRANSPORT_VPN)
&& caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) && caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI)
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED) && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
@@ -5733,7 +5730,7 @@ public class ConnectivityServiceTest {
mService.setUnderlyingNetworksForVpn( mService.setUnderlyingNetworksForVpn(
new Network[] { mCellNetworkAgent.getNetwork() }); new Network[] { mCellNetworkAgent.getNetwork() });
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, vpnNetworkCallback.expectCapabilitiesThat(mMockVpn,
(caps) -> caps.hasTransport(TRANSPORT_VPN) (caps) -> caps.hasTransport(TRANSPORT_VPN)
&& caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI)
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED) && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
@@ -5741,27 +5738,27 @@ public class ConnectivityServiceTest {
// Remove NOT_SUSPENDED from the only network and observe VPN is now suspended. // Remove NOT_SUSPENDED from the only network and observe VPN is now suspended.
mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_SUSPENDED);
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, vpnNetworkCallback.expectCapabilitiesThat(mMockVpn,
(caps) -> caps.hasTransport(TRANSPORT_VPN) (caps) -> caps.hasTransport(TRANSPORT_VPN)
&& caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI)
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED) && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
&& !caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); && !caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
vpnNetworkCallback.expectCallback(CallbackEntry.SUSPENDED, vpnNetworkAgent); vpnNetworkCallback.expectCallback(CallbackEntry.SUSPENDED, mMockVpn);
// Add NOT_SUSPENDED again and observe VPN is no longer suspended. // Add NOT_SUSPENDED again and observe VPN is no longer suspended.
mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, vpnNetworkCallback.expectCapabilitiesThat(mMockVpn,
(caps) -> caps.hasTransport(TRANSPORT_VPN) (caps) -> caps.hasTransport(TRANSPORT_VPN)
&& caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI)
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED) && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
&& caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
vpnNetworkCallback.expectCallback(CallbackEntry.RESUMED, vpnNetworkAgent); vpnNetworkCallback.expectCallback(CallbackEntry.RESUMED, mMockVpn);
// Use Wifi but not cell. Note the VPN is now unmetered and not suspended. // Use Wifi but not cell. Note the VPN is now unmetered and not suspended.
mService.setUnderlyingNetworksForVpn( mService.setUnderlyingNetworksForVpn(
new Network[] { mWiFiNetworkAgent.getNetwork() }); new Network[] { mWiFiNetworkAgent.getNetwork() });
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, vpnNetworkCallback.expectCapabilitiesThat(mMockVpn,
(caps) -> caps.hasTransport(TRANSPORT_VPN) (caps) -> caps.hasTransport(TRANSPORT_VPN)
&& !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) && !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI)
&& caps.hasCapability(NET_CAPABILITY_NOT_METERED) && caps.hasCapability(NET_CAPABILITY_NOT_METERED)
@@ -5771,7 +5768,7 @@ public class ConnectivityServiceTest {
mService.setUnderlyingNetworksForVpn( mService.setUnderlyingNetworksForVpn(
new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() }); new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() });
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, vpnNetworkCallback.expectCapabilitiesThat(mMockVpn,
(caps) -> caps.hasTransport(TRANSPORT_VPN) (caps) -> caps.hasTransport(TRANSPORT_VPN)
&& caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) && caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI)
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED) && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
@@ -5784,7 +5781,7 @@ public class ConnectivityServiceTest {
// Stop using WiFi. The VPN is suspended again. // Stop using WiFi. The VPN is suspended again.
mService.setUnderlyingNetworksForVpn( mService.setUnderlyingNetworksForVpn(
new Network[] { mCellNetworkAgent.getNetwork() }); new Network[] { mCellNetworkAgent.getNetwork() });
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, vpnNetworkCallback.expectCapabilitiesThat(mMockVpn,
(caps) -> caps.hasTransport(TRANSPORT_VPN) (caps) -> caps.hasTransport(TRANSPORT_VPN)
&& caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_CELLULAR)
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED) && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
@@ -5798,7 +5795,7 @@ public class ConnectivityServiceTest {
mService.setUnderlyingNetworksForVpn( mService.setUnderlyingNetworksForVpn(
new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() }); new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() });
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, vpnNetworkCallback.expectCapabilitiesThat(mMockVpn,
(caps) -> caps.hasTransport(TRANSPORT_VPN) (caps) -> caps.hasTransport(TRANSPORT_VPN)
&& caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) && caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI)
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED) && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
@@ -5809,14 +5806,14 @@ public class ConnectivityServiceTest {
// Disconnect cell. Receive update without even removing the dead network from the // Disconnect cell. Receive update without even removing the dead network from the
// underlying networks it's dead anyway. Not metered any more. // underlying networks it's dead anyway. Not metered any more.
mCellNetworkAgent.disconnect(); mCellNetworkAgent.disconnect();
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, vpnNetworkCallback.expectCapabilitiesThat(mMockVpn,
(caps) -> caps.hasTransport(TRANSPORT_VPN) (caps) -> caps.hasTransport(TRANSPORT_VPN)
&& !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) && !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI)
&& caps.hasCapability(NET_CAPABILITY_NOT_METERED)); && caps.hasCapability(NET_CAPABILITY_NOT_METERED));
// Disconnect wifi too. No underlying networks means this is now metered. // Disconnect wifi too. No underlying networks means this is now metered.
mWiFiNetworkAgent.disconnect(); mWiFiNetworkAgent.disconnect();
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, vpnNetworkCallback.expectCapabilitiesThat(mMockVpn,
(caps) -> caps.hasTransport(TRANSPORT_VPN) (caps) -> caps.hasTransport(TRANSPORT_VPN)
&& !caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) && !caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI)
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED)); && !caps.hasCapability(NET_CAPABILITY_NOT_METERED));
@@ -5837,18 +5834,11 @@ public class ConnectivityServiceTest {
mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback);
vpnNetworkCallback.assertNoCallback(); vpnNetworkCallback.assertNoCallback();
final TestNetworkAgentWrapper mMockVpn.establishForMyUid(true /* validated */, false /* hasInternet */,
vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN);
final ArraySet<UidRange> ranges = new ArraySet<>();
ranges.add(new UidRange(uid, uid));
mMockVpn.setNetworkAgent(vpnNetworkAgent);
mMockVpn.connect();
mMockVpn.setUids(ranges);
vpnNetworkAgent.connect(true /* validated */, false /* hasInternet */,
false /* isStrictMode */); false /* isStrictMode */);
vpnNetworkCallback.expectAvailableThenValidatedCallbacks(vpnNetworkAgent); vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
nc = mCm.getNetworkCapabilities(vpnNetworkAgent.getNetwork()); nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork());
assertTrue(nc.hasTransport(TRANSPORT_VPN)); assertTrue(nc.hasTransport(TRANSPORT_VPN));
assertFalse(nc.hasTransport(TRANSPORT_CELLULAR)); assertFalse(nc.hasTransport(TRANSPORT_CELLULAR));
assertFalse(nc.hasTransport(TRANSPORT_WIFI)); assertFalse(nc.hasTransport(TRANSPORT_WIFI));
@@ -5860,7 +5850,7 @@ public class ConnectivityServiceTest {
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
mCellNetworkAgent.connect(true); mCellNetworkAgent.connect(true);
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, vpnNetworkCallback.expectCapabilitiesThat(mMockVpn,
(caps) -> caps.hasTransport(TRANSPORT_VPN) (caps) -> caps.hasTransport(TRANSPORT_VPN)
&& caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI)
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED)); && !caps.hasCapability(NET_CAPABILITY_NOT_METERED));
@@ -5870,7 +5860,7 @@ public class ConnectivityServiceTest {
mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
mWiFiNetworkAgent.connect(true); mWiFiNetworkAgent.connect(true);
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, vpnNetworkCallback.expectCapabilitiesThat(mMockVpn,
(caps) -> caps.hasTransport(TRANSPORT_VPN) (caps) -> caps.hasTransport(TRANSPORT_VPN)
&& !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) && !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI)
&& caps.hasCapability(NET_CAPABILITY_NOT_METERED)); && caps.hasCapability(NET_CAPABILITY_NOT_METERED));
@@ -5882,7 +5872,7 @@ public class ConnectivityServiceTest {
// Disconnect wifi too. Now we have no default network. // Disconnect wifi too. Now we have no default network.
mWiFiNetworkAgent.disconnect(); mWiFiNetworkAgent.disconnect();
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, vpnNetworkCallback.expectCapabilitiesThat(mMockVpn,
(caps) -> caps.hasTransport(TRANSPORT_VPN) (caps) -> caps.hasTransport(TRANSPORT_VPN)
&& !caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) && !caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI)
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED)); && !caps.hasCapability(NET_CAPABILITY_NOT_METERED));
@@ -5925,18 +5915,10 @@ public class ConnectivityServiceTest {
assertTrue(mCm.isActiveNetworkMetered()); assertTrue(mCm.isActiveNetworkMetered());
// Connect VPN network. By default it is using current default network (Cell). // Connect VPN network. By default it is using current default network (Cell).
TestNetworkAgentWrapper mMockVpn.establishForMyUid();
vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN);
final ArraySet<UidRange> ranges = new ArraySet<>();
final int uid = Process.myUid();
ranges.add(new UidRange(uid, uid));
mMockVpn.setNetworkAgent(vpnNetworkAgent);
mMockVpn.setUids(ranges);
vpnNetworkAgent.connect(true);
mMockVpn.connect();
waitForIdle();
// Ensure VPN is now the active network. // Ensure VPN is now the active network.
assertEquals(vpnNetworkAgent.getNetwork(), mCm.getActiveNetwork()); assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork());
// Expect VPN to be metered. // Expect VPN to be metered.
assertTrue(mCm.isActiveNetworkMetered()); assertTrue(mCm.isActiveNetworkMetered());
@@ -5947,7 +5929,7 @@ public class ConnectivityServiceTest {
mWiFiNetworkAgent.connect(true); mWiFiNetworkAgent.connect(true);
waitForIdle(); waitForIdle();
// VPN should still be the active network. // VPN should still be the active network.
assertEquals(vpnNetworkAgent.getNetwork(), mCm.getActiveNetwork()); assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork());
// Expect VPN to be unmetered as it should now be using WiFi (new default). // Expect VPN to be unmetered as it should now be using WiFi (new default).
assertFalse(mCm.isActiveNetworkMetered()); assertFalse(mCm.isActiveNetworkMetered());
@@ -5965,7 +5947,6 @@ public class ConnectivityServiceTest {
// VPN without any underlying networks is treated as metered. // VPN without any underlying networks is treated as metered.
assertTrue(mCm.isActiveNetworkMetered()); assertTrue(mCm.isActiveNetworkMetered());
vpnNetworkAgent.disconnect();
mMockVpn.disconnect(); mMockVpn.disconnect();
} }
@@ -5986,18 +5967,10 @@ public class ConnectivityServiceTest {
assertFalse(mCm.isActiveNetworkMetered()); assertFalse(mCm.isActiveNetworkMetered());
// Connect VPN network. // Connect VPN network.
TestNetworkAgentWrapper mMockVpn.establishForMyUid();
vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN);
final ArraySet<UidRange> ranges = new ArraySet<>();
final int uid = Process.myUid();
ranges.add(new UidRange(uid, uid));
mMockVpn.setNetworkAgent(vpnNetworkAgent);
mMockVpn.setUids(ranges);
vpnNetworkAgent.connect(true);
mMockVpn.connect();
waitForIdle();
// Ensure VPN is now the active network. // Ensure VPN is now the active network.
assertEquals(vpnNetworkAgent.getNetwork(), mCm.getActiveNetwork()); assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork());
// VPN is using Cell // VPN is using Cell
mService.setUnderlyingNetworksForVpn( mService.setUnderlyingNetworksForVpn(
new Network[] { mCellNetworkAgent.getNetwork() }); new Network[] { mCellNetworkAgent.getNetwork() });
@@ -6037,7 +6010,6 @@ public class ConnectivityServiceTest {
// VPN without underlying networks is treated as metered. // VPN without underlying networks is treated as metered.
assertTrue(mCm.isActiveNetworkMetered()); assertTrue(mCm.isActiveNetworkMetered());
vpnNetworkAgent.disconnect();
mMockVpn.disconnect(); mMockVpn.disconnect();
} }
@@ -6052,17 +6024,11 @@ public class ConnectivityServiceTest {
assertFalse(mCm.isActiveNetworkMetered()); assertFalse(mCm.isActiveNetworkMetered());
// Connect VPN network. // Connect VPN network.
TestNetworkAgentWrapper mMockVpn.registerAgent(true /* isAlwaysMetered */, uidRangesForUid(Process.myUid()),
vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN); new LinkProperties());
final ArraySet<UidRange> ranges = new ArraySet<>(); mMockVpn.connect(true);
final int uid = Process.myUid();
ranges.add(new UidRange(uid, uid));
mMockVpn.setNetworkAgent(vpnNetworkAgent);
mMockVpn.setUids(ranges);
vpnNetworkAgent.connect(true);
mMockVpn.connectAsAlwaysMetered();
waitForIdle(); waitForIdle();
assertEquals(vpnNetworkAgent.getNetwork(), mCm.getActiveNetwork()); assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork());
// VPN is tracking current platform default (WiFi). // VPN is tracking current platform default (WiFi).
mService.setUnderlyingNetworksForVpn(null); mService.setUnderlyingNetworksForVpn(null);
@@ -6086,7 +6052,7 @@ public class ConnectivityServiceTest {
assertTrue(mCm.isActiveNetworkMetered()); assertTrue(mCm.isActiveNetworkMetered());
vpnNetworkAgent.disconnect(); mMockVpn.disconnect();
} }
@Test @Test
@@ -6815,34 +6781,21 @@ public class ConnectivityServiceTest {
waitForIdle(); waitForIdle();
assertNull(mService.getProxyForNetwork(null)); assertNull(mService.getProxyForNetwork(null));
// Set up a VPN network with a proxy // Connect a VPN network with a proxy.
final int uid = Process.myUid();
final TestNetworkAgentWrapper
vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN);
final ArraySet<UidRange> ranges = new ArraySet<>();
ranges.add(new UidRange(uid, uid));
mMockVpn.setUids(ranges);
LinkProperties testLinkProperties = new LinkProperties(); LinkProperties testLinkProperties = new LinkProperties();
testLinkProperties.setHttpProxy(testProxyInfo); testLinkProperties.setHttpProxy(testProxyInfo);
vpnNetworkAgent.sendLinkProperties(testLinkProperties); mMockVpn.establishForMyUid(testLinkProperties);
waitForIdle();
// Connect to VPN with proxy
mMockVpn.setNetworkAgent(vpnNetworkAgent);
vpnNetworkAgent.connect(true);
mMockVpn.connect();
waitForIdle();
// Test that the VPN network returns a proxy, and the WiFi does not. // Test that the VPN network returns a proxy, and the WiFi does not.
assertEquals(testProxyInfo, mService.getProxyForNetwork(vpnNetworkAgent.getNetwork())); assertEquals(testProxyInfo, mService.getProxyForNetwork(mMockVpn.getNetwork()));
assertEquals(testProxyInfo, mService.getProxyForNetwork(null)); assertEquals(testProxyInfo, mService.getProxyForNetwork(null));
assertNull(mService.getProxyForNetwork(mWiFiNetworkAgent.getNetwork())); assertNull(mService.getProxyForNetwork(mWiFiNetworkAgent.getNetwork()));
// Test that the VPN network returns no proxy when it is set to null. // Test that the VPN network returns no proxy when it is set to null.
testLinkProperties.setHttpProxy(null); testLinkProperties.setHttpProxy(null);
vpnNetworkAgent.sendLinkProperties(testLinkProperties); mMockVpn.sendLinkProperties(testLinkProperties);
waitForIdle(); waitForIdle();
assertNull(mService.getProxyForNetwork(vpnNetworkAgent.getNetwork())); assertNull(mService.getProxyForNetwork(mMockVpn.getNetwork()));
assertNull(mService.getProxyForNetwork(null)); assertNull(mService.getProxyForNetwork(null));
// Set WiFi proxy and check that the vpn proxy is still null. // Set WiFi proxy and check that the vpn proxy is still null.
@@ -6853,7 +6806,7 @@ public class ConnectivityServiceTest {
// Disconnect from VPN and check that the active network, which is now the WiFi, has the // Disconnect from VPN and check that the active network, which is now the WiFi, has the
// correct proxy setting. // correct proxy setting.
vpnNetworkAgent.disconnect(); mMockVpn.disconnect();
waitForIdle(); waitForIdle();
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertEquals(testProxyInfo, mService.getProxyForNetwork(mWiFiNetworkAgent.getNetwork())); assertEquals(testProxyInfo, mService.getProxyForNetwork(mWiFiNetworkAgent.getNetwork()));
@@ -6868,7 +6821,7 @@ public class ConnectivityServiceTest {
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE)); lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE));
// The uid range needs to cover the test app so the network is visible to it. // The uid range needs to cover the test app so the network is visible to it.
final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER)); final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER));
final TestNetworkAgentWrapper vpnNetworkAgent = establishVpn(lp, VPN_UID, vpnRange); mMockVpn.establish(lp, VPN_UID, vpnRange);
// Connected VPN should have interface rules set up. There are two expected invocations, // Connected VPN should have interface rules set up. There are two expected invocations,
// one during VPN uid update, one during VPN LinkProperties update // one during VPN uid update, one during VPN LinkProperties update
@@ -6878,7 +6831,7 @@ public class ConnectivityServiceTest {
assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID); assertContainsExactly(uidCaptor.getAllValues().get(1), APP1_UID, APP2_UID);
assertTrue(mService.mPermissionMonitor.getVpnUidRanges("tun0").equals(vpnRange)); assertTrue(mService.mPermissionMonitor.getVpnUidRanges("tun0").equals(vpnRange));
vpnNetworkAgent.disconnect(); mMockVpn.disconnect();
waitForIdle(); waitForIdle();
// Disconnected VPN should have interface rules removed // Disconnected VPN should have interface rules removed
@@ -6895,8 +6848,7 @@ public class ConnectivityServiceTest {
lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
// The uid range needs to cover the test app so the network is visible to it. // The uid range needs to cover the test app so the network is visible to it.
final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER)); final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER));
final TestNetworkAgentWrapper vpnNetworkAgent = establishVpn( mMockVpn.establish(lp, Process.SYSTEM_UID, vpnRange);
lp, Process.SYSTEM_UID, vpnRange);
// Legacy VPN should not have interface rules set up // Legacy VPN should not have interface rules set up
verify(mMockNetd, never()).firewallAddUidInterfaceRules(any(), any()); verify(mMockNetd, never()).firewallAddUidInterfaceRules(any(), any());
@@ -6911,8 +6863,7 @@ public class ConnectivityServiceTest {
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE)); lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE));
// The uid range needs to cover the test app so the network is visible to it. // The uid range needs to cover the test app so the network is visible to it.
final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER)); final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER));
final TestNetworkAgentWrapper vpnNetworkAgent = establishVpn( mMockVpn.establish(lp, Process.SYSTEM_UID, vpnRange);
lp, Process.SYSTEM_UID, vpnRange);
// IPv6 unreachable route should not be misinterpreted as a default route // IPv6 unreachable route should not be misinterpreted as a default route
verify(mMockNetd, never()).firewallAddUidInterfaceRules(any(), any()); verify(mMockNetd, never()).firewallAddUidInterfaceRules(any(), any());
@@ -6926,7 +6877,7 @@ public class ConnectivityServiceTest {
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
// The uid range needs to cover the test app so the network is visible to it. // The uid range needs to cover the test app so the network is visible to it.
final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER)); final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER));
final TestNetworkAgentWrapper vpnNetworkAgent = establishVpn(lp, VPN_UID, vpnRange); mMockVpn.establish(lp, VPN_UID, vpnRange);
// Connected VPN should have interface rules set up. There are two expected invocations, // Connected VPN should have interface rules set up. There are two expected invocations,
// one during VPN uid update, one during VPN LinkProperties update // one during VPN uid update, one during VPN LinkProperties update
@@ -6938,7 +6889,7 @@ public class ConnectivityServiceTest {
reset(mMockNetd); reset(mMockNetd);
InOrder inOrder = inOrder(mMockNetd); InOrder inOrder = inOrder(mMockNetd);
lp.setInterfaceName("tun1"); lp.setInterfaceName("tun1");
vpnNetworkAgent.sendLinkProperties(lp); mMockVpn.sendLinkProperties(lp);
waitForIdle(); waitForIdle();
// VPN handover (switch to a new interface) should result in rules being updated (old rules // VPN handover (switch to a new interface) should result in rules being updated (old rules
// removed first, then new rules added) // removed first, then new rules added)
@@ -6951,7 +6902,7 @@ public class ConnectivityServiceTest {
lp = new LinkProperties(); lp = new LinkProperties();
lp.setInterfaceName("tun1"); lp.setInterfaceName("tun1");
lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, "tun1")); lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, "tun1"));
vpnNetworkAgent.sendLinkProperties(lp); mMockVpn.sendLinkProperties(lp);
waitForIdle(); waitForIdle();
// VPN not routing everything should no longer have interface filtering rules // VPN not routing everything should no longer have interface filtering rules
verify(mMockNetd).firewallRemoveUidInterfaceRules(uidCaptor.capture()); verify(mMockNetd).firewallRemoveUidInterfaceRules(uidCaptor.capture());
@@ -6962,7 +6913,7 @@ public class ConnectivityServiceTest {
lp.setInterfaceName("tun1"); lp.setInterfaceName("tun1");
lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE)); lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE));
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
vpnNetworkAgent.sendLinkProperties(lp); mMockVpn.sendLinkProperties(lp);
waitForIdle(); waitForIdle();
// Back to routing all IPv6 traffic should have filtering rules // Back to routing all IPv6 traffic should have filtering rules
verify(mMockNetd).firewallAddUidInterfaceRules(eq("tun1"), uidCaptor.capture()); verify(mMockNetd).firewallAddUidInterfaceRules(eq("tun1"), uidCaptor.capture());
@@ -6977,8 +6928,7 @@ public class ConnectivityServiceTest {
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null)); lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
// The uid range needs to cover the test app so the network is visible to it. // The uid range needs to cover the test app so the network is visible to it.
final UidRange vpnRange = UidRange.createForUser(VPN_USER); final UidRange vpnRange = UidRange.createForUser(VPN_USER);
final TestNetworkAgentWrapper vpnNetworkAgent = establishVpn(lp, VPN_UID, mMockVpn.establish(lp, VPN_UID, Collections.singleton(vpnRange));
Collections.singleton(vpnRange));
reset(mMockNetd); reset(mMockNetd);
InOrder inOrder = inOrder(mMockNetd); InOrder inOrder = inOrder(mMockNetd);
@@ -6987,7 +6937,7 @@ public class ConnectivityServiceTest {
final Set<UidRange> newRanges = new HashSet<>(Arrays.asList( final Set<UidRange> newRanges = new HashSet<>(Arrays.asList(
new UidRange(vpnRange.start, APP1_UID - 1), new UidRange(vpnRange.start, APP1_UID - 1),
new UidRange(APP1_UID + 1, vpnRange.stop))); new UidRange(APP1_UID + 1, vpnRange.stop)));
vpnNetworkAgent.setUids(newRanges); mMockVpn.setUids(newRanges);
waitForIdle(); waitForIdle();
ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class); ArgumentCaptor<int[]> uidCaptor = ArgumentCaptor.forClass(int[].class);
@@ -7128,7 +7078,7 @@ public class ConnectivityServiceTest {
private void setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType) private void setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType)
throws Exception { throws Exception {
final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER)); final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER));
establishVpn(new LinkProperties(), vpnOwnerUid, vpnRange); mMockVpn.establish(new LinkProperties(), vpnOwnerUid, vpnRange);
mMockVpn.setVpnType(vpnType); mMockVpn.setVpnType(vpnType);
final VpnInfo vpnInfo = new VpnInfo(); final VpnInfo vpnInfo = new VpnInfo();
@@ -7209,27 +7159,6 @@ public class ConnectivityServiceTest {
mService.getConnectionOwnerUid(getTestConnectionInfo()); mService.getConnectionOwnerUid(getTestConnectionInfo());
} }
private TestNetworkAgentWrapper establishVpn(
LinkProperties lp, int ownerUid, Set<UidRange> vpnRange) throws Exception {
final TestNetworkAgentWrapper
vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN, lp);
vpnNetworkAgent.getNetworkCapabilities().setOwnerUid(ownerUid);
mMockVpn.setNetworkAgent(vpnNetworkAgent);
mMockVpn.connect();
mMockVpn.setUids(vpnRange);
vpnNetworkAgent.connect(true);
waitForIdle();
return vpnNetworkAgent;
}
private TestNetworkAgentWrapper establishVpnForMyUid(LinkProperties lp)
throws Exception {
final int uid = Process.myUid();
final ArraySet<UidRange> ranges = new ArraySet<>();
ranges.add(new UidRange(uid, uid));
return establishVpn(lp, uid, ranges);
}
private static PackageInfo buildPackageInfo(boolean hasSystemPermission, int uid) { private static PackageInfo buildPackageInfo(boolean hasSystemPermission, int uid) {
final PackageInfo packageInfo = new PackageInfo(); final PackageInfo packageInfo = new PackageInfo();
if (hasSystemPermission) { if (hasSystemPermission) {
@@ -7409,7 +7338,6 @@ public class ConnectivityServiceTest {
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION); Manifest.permission.ACCESS_FINE_LOCATION);
mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED);
// setUp() calls mockVpn() which adds a VPN with the Test Runner's uid. Configure it to be // setUp() calls mockVpn() which adds a VPN with the Test Runner's uid. Configure it to be
// active // active
@@ -7418,9 +7346,11 @@ public class ConnectivityServiceTest {
info.vpnIface = VPN_IFNAME; info.vpnIface = VPN_IFNAME;
mMockVpn.setVpnInfo(info); mMockVpn.setVpnInfo(info);
final TestNetworkAgentWrapper vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN); mMockVpn.establishForMyUid();
mMockVpn.setNetworkAgent(vpnNetworkAgent); waitForIdle();
mMockVpn.connect();
mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED);
assertTrue(mService.setUnderlyingNetworksForVpn(new Network[] {network})); assertTrue(mService.setUnderlyingNetworksForVpn(new Network[] {network}));
assertTrue( assertTrue(
@@ -7450,8 +7380,6 @@ public class ConnectivityServiceTest {
Manifest.permission.ACCESS_FINE_LOCATION); Manifest.permission.ACCESS_FINE_LOCATION);
mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED); mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED);
// Disconnect mock vpn so the uid check on NetworkAgentInfo is tested
mMockVpn.disconnect();
assertTrue( assertTrue(
"NetworkCapabilities administrator uid permission not applied", "NetworkCapabilities administrator uid permission not applied",
mService.checkConnectivityDiagnosticsPermissions( mService.checkConnectivityDiagnosticsPermissions(