Merge changes Iec22ff63,Iaca8a7cc am: 0cec61c277 am: de3c1f6764 am: 6aacbaac9c
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1528211 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I293366c6aac42f776ff23277a707d8c2ae0fd1b0
This commit is contained in:
@@ -299,6 +299,7 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import kotlin.reflect.KClass;
|
||||
|
||||
@@ -412,6 +413,7 @@ public class ConnectivityServiceTest {
|
||||
|
||||
@Spy private Resources mResources;
|
||||
private final LinkedBlockingQueue<Intent> mStartedActivities = new LinkedBlockingQueue<>();
|
||||
|
||||
// Map of permission name -> PermissionManager.Permission_{GRANTED|DENIED} constant
|
||||
private final HashMap<String, Integer> mMockedPermissions = new HashMap<>();
|
||||
|
||||
@@ -6509,6 +6511,26 @@ public class ConnectivityServiceTest {
|
||||
checkNetworkInfo(mCm.getNetworkInfo(type), type, state);
|
||||
}
|
||||
|
||||
// Checks that each of the |agents| receive a blocked status change callback with the specified
|
||||
// |blocked| value, in any order. This is needed because when an event affects multiple
|
||||
// networks, ConnectivityService does not guarantee the order in which callbacks are fired.
|
||||
private void assertBlockedCallbackInAnyOrder(TestNetworkCallback callback, boolean blocked,
|
||||
TestNetworkAgentWrapper... agents) {
|
||||
final List<Network> expectedNetworks = Arrays.asList(agents).stream()
|
||||
.map((agent) -> agent.getNetwork())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Expect exactly one blocked callback for each agent.
|
||||
for (int i = 0; i < agents.length; i++) {
|
||||
CallbackEntry e = callback.expectCallbackThat(TIMEOUT_MS, (c) ->
|
||||
c instanceof CallbackEntry.BlockedStatus
|
||||
&& ((CallbackEntry.BlockedStatus) c).getBlocked() == blocked);
|
||||
Network network = e.getNetwork();
|
||||
assertTrue("Received unexpected blocked callback for network " + network,
|
||||
expectedNetworks.remove(network));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNetworkBlockedStatusAlwaysOnVpn() throws Exception {
|
||||
mServiceContext.setPermission(
|
||||
@@ -6555,9 +6577,10 @@ public class ConnectivityServiceTest {
|
||||
assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED);
|
||||
|
||||
// Disable lockdown, expect to see the network unblocked.
|
||||
// There are no callbacks because they are not implemented yet.
|
||||
mService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList);
|
||||
expectNetworkRejectNonSecureVpn(inOrder, false, firstHalf, secondHalf);
|
||||
callback.expectBlockedStatusCallback(false, mWiFiNetworkAgent);
|
||||
defaultCallback.expectBlockedStatusCallback(false, mWiFiNetworkAgent);
|
||||
vpnUidCallback.assertNoCallback();
|
||||
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
|
||||
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
|
||||
@@ -6605,6 +6628,8 @@ public class ConnectivityServiceTest {
|
||||
allowList.clear();
|
||||
mService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */, allowList);
|
||||
expectNetworkRejectNonSecureVpn(inOrder, true, firstHalf, secondHalf);
|
||||
defaultCallback.expectBlockedStatusCallback(true, mWiFiNetworkAgent);
|
||||
assertBlockedCallbackInAnyOrder(callback, true, mWiFiNetworkAgent, mCellNetworkAgent);
|
||||
vpnUidCallback.assertNoCallback();
|
||||
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
|
||||
assertNull(mCm.getActiveNetwork());
|
||||
@@ -6614,6 +6639,8 @@ public class ConnectivityServiceTest {
|
||||
|
||||
// Disable lockdown. Everything is unblocked.
|
||||
mService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList);
|
||||
defaultCallback.expectBlockedStatusCallback(false, mWiFiNetworkAgent);
|
||||
assertBlockedCallbackInAnyOrder(callback, false, mWiFiNetworkAgent, mCellNetworkAgent);
|
||||
vpnUidCallback.assertNoCallback();
|
||||
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
|
||||
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
|
||||
@@ -6647,6 +6674,8 @@ public class ConnectivityServiceTest {
|
||||
|
||||
// Enable lockdown and connect a VPN. The VPN is not blocked.
|
||||
mService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */, allowList);
|
||||
defaultCallback.expectBlockedStatusCallback(true, mWiFiNetworkAgent);
|
||||
assertBlockedCallbackInAnyOrder(callback, true, mWiFiNetworkAgent, mCellNetworkAgent);
|
||||
vpnUidCallback.assertNoCallback();
|
||||
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
|
||||
assertNull(mCm.getActiveNetwork());
|
||||
@@ -6658,7 +6687,7 @@ public class ConnectivityServiceTest {
|
||||
defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
|
||||
vpnUidCallback.assertNoCallback(); // vpnUidCallback has NOT_VPN capability.
|
||||
assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork());
|
||||
assertEquals(null, mCm.getActiveNetworkForUid(VPN_UID)); // BUG?
|
||||
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
|
||||
assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
|
||||
assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED);
|
||||
assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED);
|
||||
|
||||
@@ -27,7 +27,6 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.AdditionalMatchers.aryEq;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
@@ -89,6 +88,7 @@ import android.security.Credentials;
|
||||
import android.security.KeyStore;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Range;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
@@ -350,7 +350,7 @@ public class VpnTest {
|
||||
|
||||
// Set always-on with lockdown.
|
||||
assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true, null, mKeyStore));
|
||||
verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(new UidRangeParcel[] {
|
||||
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
||||
new UidRangeParcel(user.start, user.start + PKG_UIDS[1] - 1),
|
||||
new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.stop)
|
||||
}));
|
||||
@@ -361,12 +361,11 @@ public class VpnTest {
|
||||
|
||||
// Switch to another app.
|
||||
assertTrue(vpn.setAlwaysOnPackage(PKGS[3], true, null, mKeyStore));
|
||||
verify(mNetd).networkRejectNonSecureVpn(eq(false), aryEq(new UidRangeParcel[] {
|
||||
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
|
||||
new UidRangeParcel(user.start, user.start + PKG_UIDS[1] - 1),
|
||||
new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.stop)
|
||||
}));
|
||||
|
||||
verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(new UidRangeParcel[] {
|
||||
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
||||
new UidRangeParcel(user.start, user.start + PKG_UIDS[3] - 1),
|
||||
new UidRangeParcel(user.start + PKG_UIDS[3] + 1, user.stop)
|
||||
}));
|
||||
@@ -383,7 +382,7 @@ public class VpnTest {
|
||||
// Set always-on with lockdown and allow app PKGS[2] from lockdown.
|
||||
assertTrue(vpn.setAlwaysOnPackage(
|
||||
PKGS[1], true, Collections.singletonList(PKGS[2]), mKeyStore));
|
||||
verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(new UidRangeParcel[] {
|
||||
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
||||
new UidRangeParcel(user.start, user.start + PKG_UIDS[1] - 1),
|
||||
new UidRangeParcel(user.start + PKG_UIDS[2] + 1, user.stop)
|
||||
}));
|
||||
@@ -392,10 +391,10 @@ public class VpnTest {
|
||||
// Change allowed app list to PKGS[3].
|
||||
assertTrue(vpn.setAlwaysOnPackage(
|
||||
PKGS[1], true, Collections.singletonList(PKGS[3]), mKeyStore));
|
||||
verify(mNetd).networkRejectNonSecureVpn(eq(false), aryEq(new UidRangeParcel[] {
|
||||
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
|
||||
new UidRangeParcel(user.start + PKG_UIDS[2] + 1, user.stop)
|
||||
}));
|
||||
verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(new UidRangeParcel[] {
|
||||
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
||||
new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.start + PKG_UIDS[3] - 1),
|
||||
new UidRangeParcel(user.start + PKG_UIDS[3] + 1, user.stop)
|
||||
}));
|
||||
@@ -405,11 +404,11 @@ public class VpnTest {
|
||||
// Change the VPN app.
|
||||
assertTrue(vpn.setAlwaysOnPackage(
|
||||
PKGS[0], true, Collections.singletonList(PKGS[3]), mKeyStore));
|
||||
verify(mNetd).networkRejectNonSecureVpn(eq(false), aryEq(new UidRangeParcel[] {
|
||||
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
|
||||
new UidRangeParcel(user.start, user.start + PKG_UIDS[1] - 1),
|
||||
new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.start + PKG_UIDS[3] - 1)
|
||||
}));
|
||||
verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(new UidRangeParcel[] {
|
||||
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
||||
new UidRangeParcel(user.start, user.start + PKG_UIDS[0] - 1),
|
||||
new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[3] - 1)
|
||||
}));
|
||||
@@ -418,11 +417,11 @@ public class VpnTest {
|
||||
|
||||
// Remove the list of allowed packages.
|
||||
assertTrue(vpn.setAlwaysOnPackage(PKGS[0], true, null, mKeyStore));
|
||||
verify(mNetd).networkRejectNonSecureVpn(eq(false), aryEq(new UidRangeParcel[] {
|
||||
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
|
||||
new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[3] - 1),
|
||||
new UidRangeParcel(user.start + PKG_UIDS[3] + 1, user.stop)
|
||||
}));
|
||||
verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(new UidRangeParcel[] {
|
||||
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
||||
new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.stop),
|
||||
}));
|
||||
assertBlocked(vpn, user.start + PKG_UIDS[1], user.start + PKG_UIDS[2],
|
||||
@@ -432,10 +431,10 @@ public class VpnTest {
|
||||
// Add the list of allowed packages.
|
||||
assertTrue(vpn.setAlwaysOnPackage(
|
||||
PKGS[0], true, Collections.singletonList(PKGS[1]), mKeyStore));
|
||||
verify(mNetd).networkRejectNonSecureVpn(eq(false), aryEq(new UidRangeParcel[] {
|
||||
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
|
||||
new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.stop)
|
||||
}));
|
||||
verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(new UidRangeParcel[] {
|
||||
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
||||
new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[1] - 1),
|
||||
new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.stop)
|
||||
}));
|
||||
@@ -450,11 +449,11 @@ public class VpnTest {
|
||||
// allowed package should change from PGKS[1] to PKGS[2].
|
||||
assertTrue(vpn.setAlwaysOnPackage(
|
||||
PKGS[0], true, Arrays.asList("com.foo.app", PKGS[2], "com.bar.app"), mKeyStore));
|
||||
verify(mNetd).networkRejectNonSecureVpn(eq(false), aryEq(new UidRangeParcel[]{
|
||||
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
|
||||
new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[1] - 1),
|
||||
new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.stop)
|
||||
}));
|
||||
verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(new UidRangeParcel[]{
|
||||
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
||||
new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[2] - 1),
|
||||
new UidRangeParcel(user.start + PKG_UIDS[2] + 1, user.stop)
|
||||
}));
|
||||
@@ -475,7 +474,7 @@ public class VpnTest {
|
||||
|
||||
// Set lockdown.
|
||||
assertTrue(vpn.setAlwaysOnPackage(PKGS[3], true, null, mKeyStore));
|
||||
verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(new UidRangeParcel[] {
|
||||
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
||||
new UidRangeParcel(user.start, user.start + PKG_UIDS[3] - 1),
|
||||
new UidRangeParcel(user.start + PKG_UIDS[3] + 1, user.stop)
|
||||
}));
|
||||
@@ -485,7 +484,7 @@ public class VpnTest {
|
||||
// Add the restricted user.
|
||||
setMockedUsers(primaryUser, tempProfile);
|
||||
vpn.onUserAdded(tempProfile.id);
|
||||
verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(new UidRangeParcel[] {
|
||||
verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
|
||||
new UidRangeParcel(profile.start, profile.start + PKG_UIDS[3] - 1),
|
||||
new UidRangeParcel(profile.start + PKG_UIDS[3] + 1, profile.stop)
|
||||
}));
|
||||
@@ -493,7 +492,7 @@ public class VpnTest {
|
||||
// Remove the restricted user.
|
||||
tempProfile.partial = true;
|
||||
vpn.onUserRemoved(tempProfile.id);
|
||||
verify(mNetd).networkRejectNonSecureVpn(eq(false), aryEq(new UidRangeParcel[] {
|
||||
verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
|
||||
new UidRangeParcel(profile.start, profile.start + PKG_UIDS[3] - 1),
|
||||
new UidRangeParcel(profile.start + PKG_UIDS[3] + 1, profile.stop)
|
||||
}));
|
||||
@@ -506,22 +505,29 @@ public class VpnTest {
|
||||
new UidRangeParcel(PRI_USER_RANGE.start, PRI_USER_RANGE.stop)};
|
||||
// Given legacy lockdown is already enabled,
|
||||
vpn.setLockdown(true);
|
||||
|
||||
verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(primaryUserRangeParcel));
|
||||
verify(mConnectivityManager, times(1)).setRequireVpnForUids(true,
|
||||
toRanges(primaryUserRangeParcel));
|
||||
|
||||
// Enabling legacy lockdown twice should do nothing.
|
||||
vpn.setLockdown(true);
|
||||
verify(mNetd, times(1))
|
||||
.networkRejectNonSecureVpn(anyBoolean(), any(UidRangeParcel[].class));
|
||||
verify(mConnectivityManager, times(1)).setRequireVpnForUids(anyBoolean(), any());
|
||||
|
||||
// And disabling should remove the rules exactly once.
|
||||
vpn.setLockdown(false);
|
||||
verify(mNetd).networkRejectNonSecureVpn(eq(false), aryEq(primaryUserRangeParcel));
|
||||
verify(mConnectivityManager, times(1)).setRequireVpnForUids(false,
|
||||
toRanges(primaryUserRangeParcel));
|
||||
|
||||
// Removing the lockdown again should have no effect.
|
||||
vpn.setLockdown(false);
|
||||
verify(mNetd, times(2)).networkRejectNonSecureVpn(
|
||||
anyBoolean(), any(UidRangeParcel[].class));
|
||||
verify(mConnectivityManager, times(2)).setRequireVpnForUids(anyBoolean(), any());
|
||||
}
|
||||
|
||||
private ArrayList<Range<Integer>> toRanges(UidRangeParcel[] ranges) {
|
||||
ArrayList<Range<Integer>> rangesArray = new ArrayList<>(ranges.length);
|
||||
for (int i = 0; i < ranges.length; i++) {
|
||||
rangesArray.add(new Range<>(ranges[i].start, ranges[i].stop));
|
||||
}
|
||||
return rangesArray;
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -535,21 +541,21 @@ public class VpnTest {
|
||||
new UidRangeParcel(entireUser[0].start + PKG_UIDS[0] + 1, entireUser[0].stop)
|
||||
};
|
||||
|
||||
final InOrder order = inOrder(mNetd);
|
||||
final InOrder order = inOrder(mConnectivityManager);
|
||||
|
||||
// Given lockdown is enabled with no package (legacy VPN),
|
||||
vpn.setLockdown(true);
|
||||
order.verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(entireUser));
|
||||
order.verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(entireUser));
|
||||
|
||||
// When a new VPN package is set the rules should change to cover that package.
|
||||
vpn.prepare(null, PKGS[0], VpnManager.TYPE_VPN_SERVICE);
|
||||
order.verify(mNetd).networkRejectNonSecureVpn(eq(false), aryEq(entireUser));
|
||||
order.verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(exceptPkg0));
|
||||
order.verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(entireUser));
|
||||
order.verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(exceptPkg0));
|
||||
|
||||
// When that VPN package is unset, everything should be undone again in reverse.
|
||||
vpn.prepare(null, VpnConfig.LEGACY_VPN, VpnManager.TYPE_VPN_SERVICE);
|
||||
order.verify(mNetd).networkRejectNonSecureVpn(eq(false), aryEq(exceptPkg0));
|
||||
order.verify(mNetd).networkRejectNonSecureVpn(eq(true), aryEq(entireUser));
|
||||
order.verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(exceptPkg0));
|
||||
order.verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(entireUser));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user