Add test coverage for LockdownVpnTracker.
Also add a comment to an existing test. Bug: 173331190 Test: test-only change Change-Id: I4211475f053f0cdf2b804132c52ce5205a772193
This commit is contained in:
@@ -21,6 +21,7 @@ import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
|
||||
import static android.app.PendingIntent.FLAG_IMMUTABLE;
|
||||
import static android.content.Intent.ACTION_USER_ADDED;
|
||||
import static android.content.Intent.ACTION_USER_REMOVED;
|
||||
import static android.content.Intent.ACTION_USER_UNLOCKED;
|
||||
import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
|
||||
import static android.content.pm.PackageManager.GET_PERMISSIONS;
|
||||
import static android.content.pm.PackageManager.MATCH_ANY_USER;
|
||||
@@ -220,6 +221,7 @@ import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.security.Credentials;
|
||||
import android.security.KeyStore;
|
||||
import android.system.Os;
|
||||
import android.telephony.TelephonyManager;
|
||||
@@ -236,6 +238,7 @@ import androidx.test.runner.AndroidJUnit4;
|
||||
import com.android.internal.app.IBatteryStats;
|
||||
import com.android.internal.net.VpnConfig;
|
||||
import com.android.internal.net.VpnInfo;
|
||||
import com.android.internal.net.VpnProfile;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.internal.util.WakeupMessage;
|
||||
import com.android.internal.util.test.BroadcastInterceptingContext;
|
||||
@@ -280,6 +283,7 @@ import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -387,6 +391,7 @@ public class ConnectivityServiceTest {
|
||||
@Mock MockableSystemProperties mSystemProperties;
|
||||
@Mock EthernetManager mEthernetManager;
|
||||
@Mock NetworkPolicyManager mNetworkPolicyManager;
|
||||
@Mock KeyStore mKeyStore;
|
||||
|
||||
private ArgumentCaptor<ResolverParamsParcel> mResolverParamsParcelCaptor =
|
||||
ArgumentCaptor.forClass(ResolverParamsParcel.class);
|
||||
@@ -1065,6 +1070,15 @@ public class ConnectivityServiceTest {
|
||||
private int mVpnType = VpnManager.TYPE_VPN_SERVICE;
|
||||
private VpnInfo mVpnInfo;
|
||||
|
||||
// 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
|
||||
// test expects two starts in a row, or even if the production code calls start twice in a
|
||||
// row. find a better solution. Simply putting a method to create a LegacyVpnRunner into
|
||||
// Vpn.Dependencies doesn't work because LegacyVpnRunner is not a static class and has
|
||||
// extensive access into the internals of Vpn.
|
||||
private ConditionVariable mStartLegacyVpnCv = new ConditionVariable();
|
||||
private ConditionVariable mStopVpnRunnerCv = new ConditionVariable();
|
||||
|
||||
public MockVpn(int userId) {
|
||||
super(startHandlerThreadAndReturnLooper(), mServiceContext,
|
||||
new Dependencies() {
|
||||
@@ -1078,7 +1092,7 @@ public class ConnectivityServiceTest {
|
||||
return mDeviceIdleInternal;
|
||||
}
|
||||
},
|
||||
mNetworkManagementService, mMockNetd, userId, mock(KeyStore.class));
|
||||
mNetworkManagementService, mMockNetd, userId, mKeyStore);
|
||||
}
|
||||
|
||||
public void setUids(Set<UidRange> uids) {
|
||||
@@ -1190,9 +1204,43 @@ public class ConnectivityServiceTest {
|
||||
}
|
||||
mAgentRegistered = false;
|
||||
setUids(null);
|
||||
// Remove NET_CAPABILITY_INTERNET or MockNetworkAgent will refuse to connect later on.
|
||||
mNetworkCapabilities.removeCapability(NET_CAPABILITY_INTERNET);
|
||||
mInterface = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startLegacyVpnRunner() {
|
||||
mStartLegacyVpnCv.open();
|
||||
}
|
||||
|
||||
public void expectStartLegacyVpnRunner() {
|
||||
assertTrue("startLegacyVpnRunner not called after " + TIMEOUT_MS + " ms",
|
||||
mStartLegacyVpnCv.block(TIMEOUT_MS));
|
||||
|
||||
// startLegacyVpn calls stopVpnRunnerPrivileged, which will open mStopVpnRunnerCv, just
|
||||
// before calling startLegacyVpnRunner. Restore mStopVpnRunnerCv, so the test can expect
|
||||
// that the VpnRunner is stopped and immediately restarted by calling
|
||||
// expectStartLegacyVpnRunner() and expectStopVpnRunnerPrivileged() back-to-back.
|
||||
mStopVpnRunnerCv = new ConditionVariable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopVpnRunnerPrivileged() {
|
||||
if (mVpnRunner != null) {
|
||||
super.stopVpnRunnerPrivileged();
|
||||
disconnect();
|
||||
mStartLegacyVpnCv = new ConditionVariable();
|
||||
}
|
||||
mVpnRunner = null;
|
||||
mStopVpnRunnerCv.open();
|
||||
}
|
||||
|
||||
public void expectStopVpnRunnerPrivileged() {
|
||||
assertTrue("stopVpnRunnerPrivileged not called after " + TIMEOUT_MS + " ms",
|
||||
mStopVpnRunnerCv.block(TIMEOUT_MS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized VpnInfo getVpnInfo() {
|
||||
if (mVpnInfo != null) return mVpnInfo;
|
||||
@@ -1274,10 +1322,12 @@ public class ConnectivityServiceTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static final int VPN_USER = 0;
|
||||
private static final int APP1_UID = UserHandle.getUid(VPN_USER, 10100);
|
||||
private static final int APP2_UID = UserHandle.getUid(VPN_USER, 10101);
|
||||
private static final int VPN_UID = UserHandle.getUid(VPN_USER, 10043);
|
||||
private static final int PRIMARY_USER = 0;
|
||||
private static final int APP1_UID = UserHandle.getUid(PRIMARY_USER, 10100);
|
||||
private static final int APP2_UID = UserHandle.getUid(PRIMARY_USER, 10101);
|
||||
private static final int VPN_UID = UserHandle.getUid(PRIMARY_USER, 10043);
|
||||
private static final UserInfo PRIMARY_USER_INFO = new UserInfo(PRIMARY_USER, "",
|
||||
UserInfo.FLAG_PRIMARY);
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
@@ -1288,10 +1338,9 @@ public class ConnectivityServiceTest {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
when(mMetricsService.defaultNetworkMetrics()).thenReturn(mDefaultNetworkMetrics);
|
||||
|
||||
when(mUserManager.getAliveUsers()).thenReturn(
|
||||
Arrays.asList(new UserInfo[] {
|
||||
new UserInfo(VPN_USER, "", 0),
|
||||
}));
|
||||
when(mUserManager.getAliveUsers()).thenReturn(Arrays.asList(PRIMARY_USER_INFO));
|
||||
when(mUserManager.getUserInfo(PRIMARY_USER)).thenReturn(PRIMARY_USER_INFO);
|
||||
|
||||
final ApplicationInfo applicationInfo = new ApplicationInfo();
|
||||
applicationInfo.targetSdkVersion = Build.VERSION_CODES.Q;
|
||||
when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), any()))
|
||||
@@ -1333,6 +1382,9 @@ public class ConnectivityServiceTest {
|
||||
verify(mNetworkPolicyManager).registerListener(policyListenerCaptor.capture());
|
||||
mPolicyListener = policyListenerCaptor.getValue();
|
||||
|
||||
mServiceContext.setPermission(
|
||||
Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED);
|
||||
|
||||
// Create local CM before sending system ready so that we can answer
|
||||
// getSystemService() correctly.
|
||||
mCm = new WrappedConnectivityManager(InstrumentationRegistry.getContext(), mService);
|
||||
@@ -1364,6 +1416,7 @@ public class ConnectivityServiceTest {
|
||||
doReturn(mMetricsService).when(deps).getMetricsLogger();
|
||||
doReturn(true).when(deps).queryUserAccess(anyInt(), anyInt());
|
||||
doReturn(mBatteryStatsService).when(deps).getBatteryStatsService();
|
||||
doReturn(mKeyStore).when(deps).getKeyStore();
|
||||
doAnswer(inv -> {
|
||||
mPolicyTracker = new WrappedMultinetworkPolicyTracker(
|
||||
inv.getArgument(0), inv.getArgument(1), inv.getArgument(2));
|
||||
@@ -1529,10 +1582,9 @@ public class ConnectivityServiceTest {
|
||||
}
|
||||
|
||||
public void expectNoBroadcast(int timeoutMs) throws Exception {
|
||||
waitForIdle();
|
||||
try {
|
||||
final Intent intent = get(timeoutMs, TimeUnit.MILLISECONDS);
|
||||
fail("Unexpected broadcast: " + intent.getAction());
|
||||
fail("Unexpected broadcast: " + intent.getAction() + " " + intent.getExtras());
|
||||
} catch (TimeoutException expected) {
|
||||
} finally {
|
||||
mServiceContext.unregisterReceiver(mReceiver);
|
||||
@@ -6400,8 +6452,6 @@ public class ConnectivityServiceTest {
|
||||
// Test lockdown with restricted profiles.
|
||||
mServiceContext.setPermission(
|
||||
Manifest.permission.CONTROL_ALWAYS_ON_VPN, PERMISSION_GRANTED);
|
||||
mServiceContext.setPermission(
|
||||
Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED);
|
||||
mServiceContext.setPermission(
|
||||
Manifest.permission.NETWORK_SETTINGS, PERMISSION_GRANTED);
|
||||
|
||||
@@ -6418,14 +6468,13 @@ public class ConnectivityServiceTest {
|
||||
mService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */, allowList);
|
||||
waitForIdle();
|
||||
assertNull(mCm.getActiveNetworkForUid(uid));
|
||||
// This is arguably overspecified: a UID that is not running doesn't have an active network.
|
||||
// But it's useful to check that non-default users do not lose network access, and to prove
|
||||
// that the loss of connectivity below is indeed due to the restricted profile coming up.
|
||||
assertNotNull(mCm.getActiveNetworkForUid(restrictedUid));
|
||||
|
||||
// Start the restricted profile, and check that the UID within it loses network access.
|
||||
when(mUserManager.getAliveUsers()).thenReturn(
|
||||
Arrays.asList(new UserInfo[] {
|
||||
new UserInfo(userId, "", 0),
|
||||
info
|
||||
}));
|
||||
when(mUserManager.getAliveUsers()).thenReturn(Arrays.asList(PRIMARY_USER_INFO, info));
|
||||
// TODO: check that VPN app within restricted profile still has access, etc.
|
||||
handler.post(() -> mServiceContext.sendBroadcast(addedIntent));
|
||||
waitForIdle();
|
||||
@@ -6433,10 +6482,7 @@ public class ConnectivityServiceTest {
|
||||
assertNull(mCm.getActiveNetworkForUid(restrictedUid));
|
||||
|
||||
// Stop the restricted profile, and check that the UID within it has network access again.
|
||||
when(mUserManager.getAliveUsers()).thenReturn(
|
||||
Arrays.asList(new UserInfo[] {
|
||||
new UserInfo(userId, "", 0),
|
||||
}));
|
||||
when(mUserManager.getAliveUsers()).thenReturn(Arrays.asList(PRIMARY_USER_INFO));
|
||||
handler.post(() -> mServiceContext.sendBroadcast(removedIntent));
|
||||
waitForIdle();
|
||||
assertNull(mCm.getActiveNetworkForUid(uid));
|
||||
@@ -6930,6 +6976,194 @@ public class ConnectivityServiceTest {
|
||||
mCm.unregisterNetworkCallback(vpnUidCallback);
|
||||
}
|
||||
|
||||
private void setupLegacyLockdownVpn() {
|
||||
final String profileName = "testVpnProfile";
|
||||
final byte[] profileTag = profileName.getBytes(StandardCharsets.UTF_8);
|
||||
when(mKeyStore.contains(Credentials.LOCKDOWN_VPN)).thenReturn(true);
|
||||
when(mKeyStore.get(Credentials.LOCKDOWN_VPN)).thenReturn(profileTag);
|
||||
|
||||
final VpnProfile profile = new VpnProfile(profileName);
|
||||
profile.name = "My VPN";
|
||||
profile.server = "192.0.2.1";
|
||||
profile.dnsServers = "8.8.8.8";
|
||||
profile.type = VpnProfile.TYPE_IPSEC_XAUTH_PSK;
|
||||
final byte[] encodedProfile = profile.encode();
|
||||
when(mKeyStore.get(Credentials.VPN + profileName)).thenReturn(encodedProfile);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLegacyLockdownVpn() throws Exception {
|
||||
final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build();
|
||||
final TestNetworkCallback callback = new TestNetworkCallback();
|
||||
mCm.registerNetworkCallback(request, callback);
|
||||
|
||||
final TestNetworkCallback defaultCallback = new TestNetworkCallback();
|
||||
mCm.registerDefaultNetworkCallback(defaultCallback);
|
||||
|
||||
// Pretend lockdown VPN was configured.
|
||||
setupLegacyLockdownVpn();
|
||||
|
||||
// LockdownVpnTracker disables the Vpn teardown code and enables lockdown.
|
||||
// Check the VPN's state before it does so.
|
||||
assertTrue(mMockVpn.getEnableTeardown());
|
||||
assertFalse(mMockVpn.getLockdown());
|
||||
|
||||
// Send a USER_UNLOCKED broadcast so CS starts LockdownVpnTracker.
|
||||
final int userId = UserHandle.getUserId(Process.myUid());
|
||||
final Intent addedIntent = new Intent(ACTION_USER_UNLOCKED);
|
||||
addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
|
||||
final Handler handler = new Handler(mCsHandlerThread.getLooper());
|
||||
handler.post(() -> mServiceContext.sendBroadcast(addedIntent));
|
||||
waitForIdle();
|
||||
|
||||
// Lockdown VPN disables teardown and enables lockdown.
|
||||
assertFalse(mMockVpn.getEnableTeardown());
|
||||
assertTrue(mMockVpn.getLockdown());
|
||||
|
||||
// Bring up a network.
|
||||
// Expect nothing to happen because the network does not have an IPv4 default route: legacy
|
||||
// VPN only supports IPv4.
|
||||
final LinkProperties cellLp = new LinkProperties();
|
||||
cellLp.setInterfaceName("rmnet0");
|
||||
cellLp.addLinkAddress(new LinkAddress("2001:db8::1/64"));
|
||||
cellLp.addRoute(new RouteInfo(new IpPrefix("::/0"), null, "rmnet0"));
|
||||
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp);
|
||||
mCellNetworkAgent.connect(false /* validated */);
|
||||
callback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent);
|
||||
defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent);
|
||||
waitForIdle();
|
||||
assertNull(mMockVpn.getAgent());
|
||||
|
||||
// Add an IPv4 address. Ideally the VPN should start, but it doesn't because nothing calls
|
||||
// LockdownVpnTracker#handleStateChangedLocked. This is a bug.
|
||||
// TODO: consider fixing this.
|
||||
cellLp.addLinkAddress(new LinkAddress("192.0.2.2/25"));
|
||||
cellLp.addRoute(new RouteInfo(new IpPrefix("0.0.0.0/0"), null, "rmnet0"));
|
||||
mCellNetworkAgent.sendLinkProperties(cellLp);
|
||||
callback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
|
||||
defaultCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
|
||||
waitForIdle();
|
||||
assertNull(mMockVpn.getAgent());
|
||||
|
||||
// Disconnect, then try again with a network that supports IPv4 at connection time.
|
||||
// Expect lockdown VPN to come up.
|
||||
ExpectedBroadcast b1 = expectConnectivityAction(TYPE_MOBILE, DetailedState.DISCONNECTED);
|
||||
mCellNetworkAgent.disconnect();
|
||||
callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
|
||||
defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
|
||||
b1.expectBroadcast();
|
||||
|
||||
// When lockdown VPN is active, the NetworkInfo state in CONNECTIVITY_ACTION is overwritten
|
||||
// with the state of the VPN network. So expect a CONNECTING broadcast.
|
||||
b1 = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTING);
|
||||
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp);
|
||||
mCellNetworkAgent.connect(false /* validated */);
|
||||
callback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent);
|
||||
defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent);
|
||||
b1.expectBroadcast();
|
||||
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
|
||||
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
|
||||
assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED);
|
||||
assertNetworkInfo(TYPE_VPN, DetailedState.BLOCKED);
|
||||
|
||||
// TODO: it would be nice if we could simply rely on the production code here, and have
|
||||
// LockdownVpnTracker start the VPN, have the VPN code register its NetworkAgent with
|
||||
// ConnectivityService, etc. That would require duplicating a fair bit of code from the
|
||||
// Vpn tests around how to mock out LegacyVpnRunner. But even if we did that, this does not
|
||||
// work for at least two reasons:
|
||||
// 1. In this test, calling registerNetworkAgent does not actually result in an agent being
|
||||
// registered. This is because nothing calls onNetworkMonitorCreated, which is what
|
||||
// actually ends up causing handleRegisterNetworkAgent to be called. Code in this test
|
||||
// that wants to register an agent must use TestNetworkAgentWrapper.
|
||||
// 2. Even if we exposed Vpn#agentConnect to the test, and made MockVpn#agentConnect call
|
||||
// the TestNetworkAgentWrapper code, this would deadlock because the
|
||||
// TestNetworkAgentWrapper code cannot be called on the handler thread since it calls
|
||||
// waitForIdle().
|
||||
mMockVpn.expectStartLegacyVpnRunner();
|
||||
b1 = expectConnectivityAction(TYPE_VPN, DetailedState.CONNECTED);
|
||||
ExpectedBroadcast b2 = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED);
|
||||
mMockVpn.establishForMyUid();
|
||||
callback.expectAvailableThenValidatedCallbacks(mMockVpn);
|
||||
defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
|
||||
b1.expectBroadcast();
|
||||
b2.expectBroadcast();
|
||||
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
||||
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
||||
assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED);
|
||||
assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED);
|
||||
|
||||
// Switch default network from cell to wifi. Expect VPN to disconnect and reconnect.
|
||||
final LinkProperties wifiLp = new LinkProperties();
|
||||
wifiLp.setInterfaceName("wlan0");
|
||||
wifiLp.addLinkAddress(new LinkAddress("192.0.2.163/25"));
|
||||
wifiLp.addRoute(new RouteInfo(new IpPrefix("0.0.0.0/0"), null, "wlan0"));
|
||||
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp);
|
||||
|
||||
b1 = expectConnectivityAction(TYPE_MOBILE, DetailedState.DISCONNECTED);
|
||||
// Wifi is CONNECTING because the VPN isn't up yet.
|
||||
b2 = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTING);
|
||||
ExpectedBroadcast b3 = expectConnectivityAction(TYPE_VPN, DetailedState.DISCONNECTED);
|
||||
mWiFiNetworkAgent.connect(false /* validated */);
|
||||
b1.expectBroadcast();
|
||||
b2.expectBroadcast();
|
||||
b3.expectBroadcast();
|
||||
mMockVpn.expectStopVpnRunnerPrivileged();
|
||||
mMockVpn.expectStartLegacyVpnRunner();
|
||||
|
||||
// TODO: why is wifi not blocked? Is this because something calls prepare()?
|
||||
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
|
||||
callback.expectCapabilitiesThat(mMockVpn, (nc) -> nc.hasTransport(TRANSPORT_WIFI));
|
||||
defaultCallback.expectCapabilitiesThat(mMockVpn, (nc) -> nc.hasTransport(TRANSPORT_WIFI));
|
||||
callback.expectCallback(CallbackEntry.LOST, mMockVpn);
|
||||
defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
|
||||
defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiNetworkAgent);
|
||||
|
||||
// While the VPN is reconnecting on the new network, everything is blocked.
|
||||
assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED);
|
||||
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
|
||||
assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED);
|
||||
assertNetworkInfo(TYPE_VPN, DetailedState.BLOCKED);
|
||||
|
||||
// The VPN comes up again on wifi.
|
||||
b1 = expectConnectivityAction(TYPE_VPN, DetailedState.CONNECTED);
|
||||
b2 = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED);
|
||||
mMockVpn.establishForMyUid();
|
||||
callback.expectAvailableThenValidatedCallbacks(mMockVpn);
|
||||
defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
|
||||
b1.expectBroadcast();
|
||||
b2.expectBroadcast();
|
||||
|
||||
assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
|
||||
assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED);
|
||||
assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
|
||||
assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED);
|
||||
|
||||
// Disconnect cell. Nothing much happens since it's not the default network.
|
||||
// Whenever LockdownVpnTracker is connected, it will send a connected broadcast any time any
|
||||
// NetworkInfo is updated. This is probably a bug.
|
||||
// TODO: consider fixing this.
|
||||
b1 = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED);
|
||||
mCellNetworkAgent.disconnect();
|
||||
b1.expectBroadcast();
|
||||
callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
|
||||
defaultCallback.assertNoCallback();
|
||||
|
||||
assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
|
||||
assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED);
|
||||
assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
|
||||
assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED);
|
||||
|
||||
b1 = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED);
|
||||
mWiFiNetworkAgent.disconnect();
|
||||
callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
|
||||
b1.expectBroadcast();
|
||||
callback.expectCapabilitiesThat(mMockVpn, (nc) -> !nc.hasTransport(TRANSPORT_WIFI));
|
||||
b2 = expectConnectivityAction(TYPE_VPN, DetailedState.DISCONNECTED);
|
||||
mMockVpn.expectStopVpnRunnerPrivileged();
|
||||
callback.expectCallback(CallbackEntry.LOST, mMockVpn);
|
||||
b2.expectBroadcast();
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void testLoseTrusted() throws Exception {
|
||||
final NetworkRequest trustedRequest = new NetworkRequest.Builder()
|
||||
@@ -7604,7 +7838,7 @@ public class ConnectivityServiceTest {
|
||||
lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
|
||||
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.
|
||||
final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER));
|
||||
final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(PRIMARY_USER));
|
||||
mMockVpn.establish(lp, VPN_UID, vpnRange);
|
||||
assertVpnUidRangesUpdated(true, vpnRange, VPN_UID);
|
||||
|
||||
@@ -7632,7 +7866,7 @@ public class ConnectivityServiceTest {
|
||||
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.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.
|
||||
final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER));
|
||||
final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(PRIMARY_USER));
|
||||
mMockVpn.establish(lp, Process.SYSTEM_UID, vpnRange);
|
||||
assertVpnUidRangesUpdated(true, vpnRange, Process.SYSTEM_UID);
|
||||
|
||||
@@ -7648,7 +7882,7 @@ public class ConnectivityServiceTest {
|
||||
lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, "tun0"));
|
||||
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.
|
||||
final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER));
|
||||
final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(PRIMARY_USER));
|
||||
mMockVpn.establish(lp, Process.SYSTEM_UID, vpnRange);
|
||||
assertVpnUidRangesUpdated(true, vpnRange, Process.SYSTEM_UID);
|
||||
|
||||
@@ -7663,7 +7897,7 @@ public class ConnectivityServiceTest {
|
||||
lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.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.
|
||||
final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER));
|
||||
final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(PRIMARY_USER));
|
||||
mMockVpn.establish(lp, VPN_UID, vpnRange);
|
||||
assertVpnUidRangesUpdated(true, vpnRange, VPN_UID);
|
||||
|
||||
@@ -7715,7 +7949,7 @@ public class ConnectivityServiceTest {
|
||||
lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE));
|
||||
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.
|
||||
final UidRange vpnRange = UidRange.createForUser(VPN_USER);
|
||||
final UidRange vpnRange = UidRange.createForUser(PRIMARY_USER);
|
||||
final Set<UidRange> vpnRanges = Collections.singleton(vpnRange);
|
||||
mMockVpn.establish(lp, VPN_UID, vpnRanges);
|
||||
assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID);
|
||||
@@ -7867,7 +8101,7 @@ public class ConnectivityServiceTest {
|
||||
|
||||
private void setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType)
|
||||
throws Exception {
|
||||
final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(VPN_USER));
|
||||
final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(PRIMARY_USER));
|
||||
mMockVpn.establish(new LinkProperties(), vpnOwnerUid, vpnRange);
|
||||
assertVpnUidRangesUpdated(true, vpnRange, vpnOwnerUid);
|
||||
mMockVpn.setVpnType(vpnType);
|
||||
@@ -8441,7 +8675,7 @@ public class ConnectivityServiceTest {
|
||||
lp.setInterfaceName("tun0");
|
||||
lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
|
||||
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
|
||||
final UidRange vpnRange = UidRange.createForUser(VPN_USER);
|
||||
final UidRange vpnRange = UidRange.createForUser(PRIMARY_USER);
|
||||
Set<UidRange> vpnRanges = Collections.singleton(vpnRange);
|
||||
mMockVpn.establish(lp, VPN_UID, vpnRanges);
|
||||
assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID);
|
||||
|
||||
Reference in New Issue
Block a user