diff options
10 files changed, 353 insertions, 220 deletions
diff --git a/packages/Connectivity/framework/api/module-lib-current.txt b/packages/Connectivity/framework/api/module-lib-current.txt index 63cf8a9e82af..812796c43ab1 100644 --- a/packages/Connectivity/framework/api/module-lib-current.txt +++ b/packages/Connectivity/framework/api/module-lib-current.txt @@ -35,9 +35,18 @@ package android.net { } public final class NetworkCapabilities implements android.os.Parcelable { + method @Nullable public java.util.Set<android.util.Range<java.lang.Integer>> getUids(); field public static final int TRANSPORT_TEST = 7; // 0x7 } + public static final class NetworkCapabilities.Builder { + method @NonNull public android.net.NetworkCapabilities.Builder setUids(@Nullable java.util.Set<android.util.Range<java.lang.Integer>>); + } + + public static class NetworkRequest.Builder { + method @NonNull public android.net.NetworkRequest.Builder setUids(@Nullable java.util.Set<android.util.Range<java.lang.Integer>>); + } + public class ParseException extends java.lang.RuntimeException { ctor public ParseException(@NonNull String); ctor public ParseException(@NonNull String, @NonNull Throwable); diff --git a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java index 058f3c999dd7..182bc7141a33 100644 --- a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java +++ b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java @@ -22,6 +22,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; +import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; import android.net.ConnectivityManager.NetworkCallback; @@ -32,6 +33,7 @@ import android.os.Parcelable; import android.os.Process; import android.text.TextUtils; import android.util.ArraySet; +import android.util.Range; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.VisibleForTesting; @@ -153,7 +155,7 @@ public final class NetworkCapabilities implements Parcelable { setTransportInfo(null); } mSignalStrength = nc.mSignalStrength; - setUids(nc.mUids); // Will make the defensive copy + mUids = (nc.mUids == null) ? null : new ArraySet<>(nc.mUids); setAdministratorUids(nc.getAdministratorUids()); mOwnerUid = nc.mOwnerUid; mUnwantedNetworkCapabilities = nc.mUnwantedNetworkCapabilities; @@ -1458,9 +1460,8 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ public @NonNull NetworkCapabilities setSingleUid(int uid) { - final ArraySet<UidRange> identity = new ArraySet<>(1); - identity.add(new UidRange(uid, uid)); - setUids(identity); + mUids = new ArraySet<>(1); + mUids.add(new UidRange(uid, uid)); return this; } @@ -1469,22 +1470,34 @@ public final class NetworkCapabilities implements Parcelable { * This makes a copy of the set so that callers can't modify it after the call. * @hide */ - public @NonNull NetworkCapabilities setUids(Set<UidRange> uids) { - if (null == uids) { - mUids = null; - } else { - mUids = new ArraySet<>(uids); - } + public @NonNull NetworkCapabilities setUids(@Nullable Set<Range<Integer>> uids) { + mUids = UidRange.fromIntRanges(uids); return this; } /** * Get the list of UIDs this network applies to. * This returns a copy of the set so that callers can't modify the original object. + * + * @return the list of UIDs this network applies to. If {@code null}, then the network applies + * to all UIDs. * @hide */ - public @Nullable Set<UidRange> getUids() { - return null == mUids ? null : new ArraySet<>(mUids); + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + @SuppressLint("NullableCollection") + public @Nullable Set<Range<Integer>> getUids() { + return UidRange.toIntRanges(mUids); + } + + /** + * Get the list of UIDs this network applies to. + * This returns a copy of the set so that callers can't modify the original object. + * @hide + */ + public @Nullable Set<UidRange> getUidRanges() { + if (mUids == null) return null; + + return new ArraySet<>(mUids); } /** @@ -2655,6 +2668,21 @@ public final class NetworkCapabilities implements Parcelable { } /** + * Set the list of UIDs this network applies to. + * + * @param uids the list of UIDs this network applies to, or {@code null} if this network + * applies to all UIDs. + * @return this builder + * @hide + */ + @NonNull + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public Builder setUids(@Nullable Set<Range<Integer>> uids) { + mCaps.setUids(uids); + return this; + } + + /** * Builds the instance of the capabilities. * * @return the built instance of NetworkCapabilities. diff --git a/packages/Connectivity/framework/src/android/net/NetworkRequest.java b/packages/Connectivity/framework/src/android/net/NetworkRequest.java index dbe3ecc4d775..cf131f0df607 100644 --- a/packages/Connectivity/framework/src/android/net/NetworkRequest.java +++ b/packages/Connectivity/framework/src/android/net/NetworkRequest.java @@ -36,6 +36,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_TEST; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; +import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; import android.net.NetworkCapabilities.NetCapability; @@ -45,6 +46,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.os.Process; import android.text.TextUtils; +import android.util.Range; import android.util.proto.ProtoOutputStream; import java.util.Arrays; @@ -277,11 +279,14 @@ public class NetworkRequest implements Parcelable { * Set the watched UIDs for this request. This will be reset and wiped out unless * the calling app holds the CHANGE_NETWORK_STATE permission. * - * @param uids The watched UIDs as a set of UidRanges, or null for everything. + * @param uids The watched UIDs as a set of {@code Range<Integer>}, or null for everything. * @return The builder to facilitate chaining. * @hide */ - public Builder setUids(Set<UidRange> uids) { + @NonNull + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + @SuppressLint("MissingGetterMatchingBuilder") + public Builder setUids(@Nullable Set<Range<Integer>> uids) { mNetworkCapabilities.setUids(uids); return this; } diff --git a/packages/Connectivity/framework/src/android/net/UidRange.java b/packages/Connectivity/framework/src/android/net/UidRange.java index 26518d32edcb..bc67c745c98f 100644 --- a/packages/Connectivity/framework/src/android/net/UidRange.java +++ b/packages/Connectivity/framework/src/android/net/UidRange.java @@ -20,8 +20,11 @@ import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; +import android.util.ArraySet; +import android.util.Range; import java.util.Collection; +import java.util.Set; /** * An inclusive range of UIDs. @@ -149,4 +152,32 @@ public final class UidRange implements Parcelable { } return false; } + + /** + * Convert a set of {@code Range<Integer>} to a set of {@link UidRange}. + */ + @Nullable + public static ArraySet<UidRange> fromIntRanges(@Nullable Set<Range<Integer>> ranges) { + if (null == ranges) return null; + + final ArraySet<UidRange> uids = new ArraySet<>(); + for (Range<Integer> range : ranges) { + uids.add(new UidRange(range.getLower(), range.getUpper())); + } + return uids; + } + + /** + * Convert a set of {@link UidRange} to a set of {@code Range<Integer>}. + */ + @Nullable + public static ArraySet<Range<Integer>> toIntRanges(@Nullable Set<UidRange> ranges) { + if (null == ranges) return null; + + final ArraySet<Range<Integer>> uids = new ArraySet<>(); + for (UidRange range : ranges) { + uids.add(new Range<Integer>(range.start, range.stop)); + } + return uids; + } } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 58a921f0e3be..527c211b23b4 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -1344,7 +1344,7 @@ public class ConnectivityService extends IConnectivityManager.Stub netCap.addCapability(NET_CAPABILITY_INTERNET); netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); netCap.removeCapability(NET_CAPABILITY_NOT_VPN); - netCap.setUids(Collections.singleton(uids)); + netCap.setUids(UidRange.toIntRanges(Collections.singleton(uids))); return netCap; } @@ -2904,7 +2904,7 @@ public class ConnectivityService extends IConnectivityManager.Stub if (0 == defaultRequest.mRequests.size()) { pw.println("none, this should never occur."); } else { - pw.println(defaultRequest.mRequests.get(0).networkCapabilities.getUids()); + pw.println(defaultRequest.mRequests.get(0).networkCapabilities.getUidRanges()); } pw.decreaseIndent(); pw.decreaseIndent(); @@ -5322,9 +5322,8 @@ public class ConnectivityService extends IConnectivityManager.Stub private Set<UidRange> getUids() { // networkCapabilities.getUids() returns a defensive copy. // multilayer requests will all have the same uids so return the first one. - final Set<UidRange> uids = null == mRequests.get(0).networkCapabilities.getUids() - ? new ArraySet<>() : mRequests.get(0).networkCapabilities.getUids(); - return uids; + final Set<UidRange> uids = mRequests.get(0).networkCapabilities.getUidRanges(); + return (null == uids) ? new ArraySet<>() : uids; } NetworkRequestInfo(@NonNull final NetworkRequest r, @Nullable final PendingIntent pi, @@ -6130,7 +6129,7 @@ public class ConnectivityService extends IConnectivityManager.Stub for (final NetworkRequestInfo nri : mDefaultNetworkRequests) { // Currently, all network requests will have the same uids therefore checking the first // one is sufficient. If/when uids are tracked at the nri level, this can change. - final Set<UidRange> uids = nri.mRequests.get(0).networkCapabilities.getUids(); + final Set<UidRange> uids = nri.mRequests.get(0).networkCapabilities.getUidRanges(); if (null == uids) { continue; } @@ -6571,7 +6570,7 @@ public class ConnectivityService extends IConnectivityManager.Stub return; } - final Set<UidRange> ranges = nai.networkCapabilities.getUids(); + final Set<UidRange> ranges = nai.networkCapabilities.getUidRanges(); final int vpnAppUid = nai.networkCapabilities.getOwnerUid(); // TODO: this create a window of opportunity for apps to receive traffic between the time // when the old rules are removed and the time when new rules are added. To fix this, @@ -6936,8 +6935,8 @@ public class ConnectivityService extends IConnectivityManager.Stub private void updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc, NetworkCapabilities newNc) { - Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUids(); - Set<UidRange> newRanges = null == newNc ? null : newNc.getUids(); + Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUidRanges(); + Set<UidRange> newRanges = null == newNc ? null : newNc.getUidRanges(); if (null == prevRanges) prevRanges = new ArraySet<>(); if (null == newRanges) newRanges = new ArraySet<>(); final Set<UidRange> prevRangesCopy = new ArraySet<>(prevRanges); @@ -9268,7 +9267,7 @@ public class ConnectivityService extends IConnectivityManager.Stub final ArrayList<NetworkRequest> nrs = new ArrayList<>(); nrs.add(createNetworkRequest(NetworkRequest.Type.REQUEST, pref.capabilities)); nrs.add(createDefaultRequest()); - setNetworkRequestUids(nrs, pref.capabilities.getUids()); + setNetworkRequestUids(nrs, UidRange.fromIntRanges(pref.capabilities.getUids())); final NetworkRequestInfo nri = new NetworkRequestInfo(nrs); result.add(nri); } @@ -9484,9 +9483,8 @@ public class ConnectivityService extends IConnectivityManager.Stub private static void setNetworkRequestUids(@NonNull final List<NetworkRequest> requests, @NonNull final Set<UidRange> uids) { - final Set<UidRange> ranges = new ArraySet<>(uids); for (final NetworkRequest req : requests) { - req.networkCapabilities.setUids(ranges); + req.networkCapabilities.setUids(UidRange.toIntRanges(uids)); } } diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 124c3741ad57..8d09d784147d 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -19,6 +19,7 @@ package com.android.server.connectivity; import static android.Manifest.permission.BIND_VPN_SERVICE; import static android.net.ConnectivityManager.NETID_UNSET; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; +import static android.os.UserHandle.PER_USER_RANGE; import static android.net.RouteInfo.RTN_THROW; import static android.net.RouteInfo.RTN_UNREACHABLE; import static android.net.VpnManager.NOTIFICATION_CHANNEL_VPN; @@ -69,7 +70,6 @@ import android.net.NetworkInfo.DetailedState; import android.net.NetworkProvider; import android.net.NetworkRequest; import android.net.RouteInfo; -import android.net.UidRange; import android.net.UidRangeParcel; import android.net.UnderlyingNetworkInfo; import android.net.VpnManager; @@ -1346,7 +1346,7 @@ public class Vpn { String oldInterface = mInterface; Connection oldConnection = mConnection; NetworkAgent oldNetworkAgent = mNetworkAgent; - Set<UidRange> oldUsers = mNetworkCapabilities.getUids(); + Set<Range<Integer>> oldUsers = mNetworkCapabilities.getUids(); // Configure the interface. Abort if any of these steps fails. ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(jniCreate(config.mtu)); @@ -1452,7 +1452,7 @@ public class Vpn { } /** - * Creates a {@link Set} of non-intersecting {@link UidRange} objects including all UIDs + * Creates a {@link Set} of non-intersecting {@code Range<Integer>} objects including all UIDs * associated with one user, and any restricted profiles attached to that user. * * <p>If one of {@param allowedApplications} or {@param disallowedApplications} is provided, @@ -1465,10 +1465,10 @@ public class Vpn { * @param disallowedApplications (optional) List of applications to deny. */ @VisibleForTesting - Set<UidRange> createUserAndRestrictedProfilesRanges(@UserIdInt int userId, + Set<Range<Integer>> createUserAndRestrictedProfilesRanges(@UserIdInt int userId, @Nullable List<String> allowedApplications, @Nullable List<String> disallowedApplications) { - final Set<UidRange> ranges = new ArraySet<>(); + final Set<Range<Integer>> ranges = new ArraySet<>(); // Assign the top-level user to the set of ranges addUserToRanges(ranges, userId, allowedApplications, disallowedApplications); @@ -1492,20 +1492,20 @@ public class Vpn { } /** - * Updates a {@link Set} of non-intersecting {@link UidRange} objects to include all UIDs + * Updates a {@link Set} of non-intersecting {@code Range<Integer>} objects to include all UIDs * associated with one user. * * <p>If one of {@param allowedApplications} or {@param disallowedApplications} is provided, * the UID ranges will match the app allowlist or denylist specified there. Otherwise, all UIDs * in the user will be included. * - * @param ranges {@link Set} of {@link UidRange}s to which to add. + * @param ranges {@link Set} of {@code Range<Integer>}s to which to add. * @param userId The userId to add to {@param ranges}. * @param allowedApplications (optional) allowlist of applications to include. * @param disallowedApplications (optional) denylist of applications to exclude. */ @VisibleForTesting - void addUserToRanges(@NonNull Set<UidRange> ranges, @UserIdInt int userId, + void addUserToRanges(@NonNull Set<Range<Integer>> ranges, @UserIdInt int userId, @Nullable List<String> allowedApplications, @Nullable List<String> disallowedApplications) { if (allowedApplications != null) { @@ -1515,40 +1515,41 @@ public class Vpn { if (start == -1) { start = uid; } else if (uid != stop + 1) { - ranges.add(new UidRange(start, stop)); + ranges.add(new Range<Integer>(start, stop)); start = uid; } stop = uid; } - if (start != -1) ranges.add(new UidRange(start, stop)); + if (start != -1) ranges.add(new Range<Integer>(start, stop)); } else if (disallowedApplications != null) { // Add all ranges for user skipping UIDs for disallowedApplications. - final UidRange userRange = UidRange.createForUser(UserHandle.of(userId)); - int start = userRange.start; + final Range<Integer> userRange = createUidRangeForUser(userId); + int start = userRange.getLower(); for (int uid : getAppsUids(disallowedApplications, userId)) { if (uid == start) { start++; } else { - ranges.add(new UidRange(start, uid - 1)); + ranges.add(new Range<Integer>(start, uid - 1)); start = uid + 1; } } - if (start <= userRange.stop) ranges.add(new UidRange(start, userRange.stop)); + if (start <= userRange.getUpper()) { + ranges.add(new Range<Integer>(start, userRange.getUpper())); + } } else { // Add all UIDs for the user. - ranges.add(UidRange.createForUser(UserHandle.of(userId))); + ranges.add(createUidRangeForUser(userId)); } } // Returns the subset of the full list of active UID ranges the VPN applies to (mVpnUsers) that // apply to userId. - private static List<UidRange> uidRangesForUser(int userId, Set<UidRange> existingRanges) { - // UidRange#createForUser returns the entire range of UIDs available to a macro-user. - // This is something like 0-99999 ; {@see UserHandle#PER_USER_RANGE} - final UidRange userRange = UidRange.createForUser(UserHandle.of(userId)); - final List<UidRange> ranges = new ArrayList<>(); - for (UidRange range : existingRanges) { - if (userRange.containsRange(range)) { + private static List<Range<Integer>> uidRangesForUser(int userId, + Set<Range<Integer>> existingRanges) { + final Range<Integer> userRange = createUidRangeForUser(userId); + final List<Range<Integer>> ranges = new ArrayList<>(); + for (Range<Integer> range : existingRanges) { + if (userRange.contains(range)) { ranges.add(range); } } @@ -1565,7 +1566,7 @@ public class Vpn { UserInfo user = mUserManager.getUserInfo(userId); if (user.isRestricted() && user.restrictedProfileParentId == mUserId) { synchronized(Vpn.this) { - final Set<UidRange> existingRanges = mNetworkCapabilities.getUids(); + final Set<Range<Integer>> existingRanges = mNetworkCapabilities.getUids(); if (existingRanges != null) { try { addUserToRanges(existingRanges, userId, mConfig.allowedApplications, @@ -1593,10 +1594,10 @@ public class Vpn { UserInfo user = mUserManager.getUserInfo(userId); if (user.isRestricted() && user.restrictedProfileParentId == mUserId) { synchronized(Vpn.this) { - final Set<UidRange> existingRanges = mNetworkCapabilities.getUids(); + final Set<Range<Integer>> existingRanges = mNetworkCapabilities.getUids(); if (existingRanges != null) { try { - final List<UidRange> removedRanges = + final List<Range<Integer>> removedRanges = uidRangesForUser(userId, existingRanges); existingRanges.removeAll(removedRanges); mNetworkCapabilities.setUids(existingRanges); @@ -1657,7 +1658,7 @@ public class Vpn { final Set<UidRangeParcel> rangesToRemove = new ArraySet<>(mBlockedUidsAsToldToConnectivity); final Set<UidRangeParcel> rangesToAdd; if (enforce) { - final Set<UidRange> restrictedProfilesRanges = + final Set<Range<Integer>> restrictedProfilesRanges = createUserAndRestrictedProfilesRanges(mUserId, /* allowedApplications */ null, /* disallowedApplications */ exemptedPackages); @@ -1666,11 +1667,12 @@ public class Vpn { // The UID range of the first user (0-99999) would block the IPSec traffic, which comes // directly from the kernel and is marked as uid=0. So we adjust the range to allow // it through (b/69873852). - for (UidRange range : restrictedProfilesRanges) { - if (range.start == 0 && range.stop != 0) { - rangesThatShouldBeBlocked.add(new UidRangeParcel(1, range.stop)); - } else if (range.start != 0) { - rangesThatShouldBeBlocked.add(new UidRangeParcel(range.start, range.stop)); + for (Range<Integer> range : restrictedProfilesRanges) { + if (range.getLower() == 0 && range.getUpper() != 0) { + rangesThatShouldBeBlocked.add(new UidRangeParcel(1, range.getUpper())); + } else if (range.getLower() != 0) { + rangesThatShouldBeBlocked.add( + new UidRangeParcel(range.getLower(), range.getUpper())); } } @@ -1692,12 +1694,12 @@ public class Vpn { } /** - * Tell ConnectivityService to add or remove a list of {@link UidRange}s to the list of UIDs - * that are only allowed to make connections through sockets that have had {@code protect()} - * called on them. + * Tell ConnectivityService to add or remove a list of {@link UidRangeParcel}s to the list of + * UIDs that are only allowed to make connections through sockets that have had + * {@code protect()} called on them. * * @param enforce {@code true} to add to the denylist, {@code false} to remove. - * @param ranges {@link Collection} of {@link UidRange}s to add (if {@param enforce} is + * @param ranges {@link Collection} of {@link UidRangeParcel}s to add (if {@param enforce} is * {@code true}) or to remove. * @return {@code true} if all of the UIDs were added/removed. {@code false} otherwise, * including added ranges that already existed or removed ones that didn't. @@ -3338,4 +3340,12 @@ public class Vpn { firstChildSessionCallback); } } + + /** + * Returns the entire range of UIDs available to a macro-user. This is something like 0-99999. + */ + @VisibleForTesting + static Range<Integer> createUidRangeForUser(int userId) { + return new Range<Integer>(userId * PER_USER_RANGE, (userId + 1) * PER_USER_RANGE - 1); + } } diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java index 0dfec7592274..a7ad69564136 100644 --- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java +++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java @@ -69,6 +69,7 @@ import android.net.wifi.aware.WifiAwareNetworkSpecifier; import android.os.Build; import android.test.suitebuilder.annotation.SmallTest; import android.util.ArraySet; +import android.util.Range; import androidx.test.runner.AndroidJUnit4; @@ -240,72 +241,93 @@ public class NetworkCapabilitiesTest { @Test public void testSetUids() { final NetworkCapabilities netCap = new NetworkCapabilities(); - final Set<UidRange> uids = new ArraySet<>(); - uids.add(new UidRange(50, 100)); - uids.add(new UidRange(3000, 4000)); - netCap.setUids(uids); - assertTrue(netCap.appliesToUid(50)); - assertTrue(netCap.appliesToUid(80)); - assertTrue(netCap.appliesToUid(100)); + // Null uids match all UIDs + netCap.setUids(null); + assertTrue(netCap.appliesToUid(10)); + assertTrue(netCap.appliesToUid(200)); assertTrue(netCap.appliesToUid(3000)); - assertTrue(netCap.appliesToUid(3001)); - assertFalse(netCap.appliesToUid(10)); - assertFalse(netCap.appliesToUid(25)); - assertFalse(netCap.appliesToUid(49)); - assertFalse(netCap.appliesToUid(101)); - assertFalse(netCap.appliesToUid(2000)); - assertFalse(netCap.appliesToUid(100000)); - + assertTrue(netCap.appliesToUid(10010)); assertTrue(netCap.appliesToUidRange(new UidRange(50, 100))); assertTrue(netCap.appliesToUidRange(new UidRange(70, 72))); assertTrue(netCap.appliesToUidRange(new UidRange(3500, 3912))); - assertFalse(netCap.appliesToUidRange(new UidRange(1, 100))); - assertFalse(netCap.appliesToUidRange(new UidRange(49, 100))); - assertFalse(netCap.appliesToUidRange(new UidRange(1, 10))); - assertFalse(netCap.appliesToUidRange(new UidRange(60, 101))); - assertFalse(netCap.appliesToUidRange(new UidRange(60, 3400))); - - NetworkCapabilities netCap2 = new NetworkCapabilities(); - // A new netcap object has null UIDs, so anything will satisfy it. - assertTrue(netCap2.satisfiedByUids(netCap)); - // Still not equal though. - assertFalse(netCap2.equalsUids(netCap)); - netCap2.setUids(uids); - assertTrue(netCap2.satisfiedByUids(netCap)); - assertTrue(netCap.equalsUids(netCap2)); - assertTrue(netCap2.equalsUids(netCap)); - - uids.add(new UidRange(600, 700)); - netCap2.setUids(uids); - assertFalse(netCap2.satisfiedByUids(netCap)); - assertFalse(netCap.appliesToUid(650)); - assertTrue(netCap2.appliesToUid(650)); - netCap.combineCapabilities(netCap2); - assertTrue(netCap2.satisfiedByUids(netCap)); - assertTrue(netCap.appliesToUid(650)); - assertFalse(netCap.appliesToUid(500)); - - assertTrue(new NetworkCapabilities().satisfiedByUids(netCap)); - netCap.combineCapabilities(new NetworkCapabilities()); - assertTrue(netCap.appliesToUid(500)); assertTrue(netCap.appliesToUidRange(new UidRange(1, 100000))); - assertFalse(netCap2.appliesToUid(500)); - assertFalse(netCap2.appliesToUidRange(new UidRange(1, 100000))); - assertTrue(new NetworkCapabilities().satisfiedByUids(netCap)); + + if (isAtLeastS()) { + final Set<Range<Integer>> uids = new ArraySet<>(); + uids.add(uidRange(50, 100)); + uids.add(uidRange(3000, 4000)); + netCap.setUids(uids); + assertTrue(netCap.appliesToUid(50)); + assertTrue(netCap.appliesToUid(80)); + assertTrue(netCap.appliesToUid(100)); + assertTrue(netCap.appliesToUid(3000)); + assertTrue(netCap.appliesToUid(3001)); + assertFalse(netCap.appliesToUid(10)); + assertFalse(netCap.appliesToUid(25)); + assertFalse(netCap.appliesToUid(49)); + assertFalse(netCap.appliesToUid(101)); + assertFalse(netCap.appliesToUid(2000)); + assertFalse(netCap.appliesToUid(100000)); + + assertTrue(netCap.appliesToUidRange(new UidRange(50, 100))); + assertTrue(netCap.appliesToUidRange(new UidRange(70, 72))); + assertTrue(netCap.appliesToUidRange(new UidRange(3500, 3912))); + assertFalse(netCap.appliesToUidRange(new UidRange(1, 100))); + assertFalse(netCap.appliesToUidRange(new UidRange(49, 100))); + assertFalse(netCap.appliesToUidRange(new UidRange(1, 10))); + assertFalse(netCap.appliesToUidRange(new UidRange(60, 101))); + assertFalse(netCap.appliesToUidRange(new UidRange(60, 3400))); + + NetworkCapabilities netCap2 = new NetworkCapabilities(); + // A new netcap object has null UIDs, so anything will satisfy it. + assertTrue(netCap2.satisfiedByUids(netCap)); + // Still not equal though. + assertFalse(netCap2.equalsUids(netCap)); + netCap2.setUids(uids); + assertTrue(netCap2.satisfiedByUids(netCap)); + assertTrue(netCap.equalsUids(netCap2)); + assertTrue(netCap2.equalsUids(netCap)); + + uids.add(uidRange(600, 700)); + netCap2.setUids(uids); + assertFalse(netCap2.satisfiedByUids(netCap)); + assertFalse(netCap.appliesToUid(650)); + assertTrue(netCap2.appliesToUid(650)); + netCap.combineCapabilities(netCap2); + assertTrue(netCap2.satisfiedByUids(netCap)); + assertTrue(netCap.appliesToUid(650)); + assertFalse(netCap.appliesToUid(500)); + + assertTrue(new NetworkCapabilities().satisfiedByUids(netCap)); + netCap.combineCapabilities(new NetworkCapabilities()); + assertTrue(netCap.appliesToUid(500)); + assertTrue(netCap.appliesToUidRange(new UidRange(1, 100000))); + assertFalse(netCap2.appliesToUid(500)); + assertFalse(netCap2.appliesToUidRange(new UidRange(1, 100000))); + assertTrue(new NetworkCapabilities().satisfiedByUids(netCap)); + + // Null uids satisfies everything. + netCap.setUids(null); + assertTrue(netCap2.satisfiedByUids(netCap)); + assertTrue(netCap.satisfiedByUids(netCap2)); + netCap2.setUids(null); + assertTrue(netCap2.satisfiedByUids(netCap)); + assertTrue(netCap.satisfiedByUids(netCap2)); + } } @Test public void testParcelNetworkCapabilities() { - final Set<UidRange> uids = new ArraySet<>(); - uids.add(new UidRange(50, 100)); - uids.add(new UidRange(3000, 4000)); + final Set<Range<Integer>> uids = new ArraySet<>(); + uids.add(uidRange(50, 100)); + uids.add(uidRange(3000, 4000)); final NetworkCapabilities netCap = new NetworkCapabilities() .addCapability(NET_CAPABILITY_INTERNET) - .setUids(uids) .addCapability(NET_CAPABILITY_EIMS) .addCapability(NET_CAPABILITY_NOT_METERED); if (isAtLeastS()) { netCap.setSubIds(Set.of(TEST_SUBID1, TEST_SUBID2)); + netCap.setUids(uids); } else if (isAtLeastR()) { netCap.setOwnerUid(123); netCap.setAdministratorUids(new int[] {5, 11}); @@ -540,12 +562,16 @@ public class NetworkCapabilitiesTest { assertFalse(nc1.satisfiedByNetworkCapabilities(nc2)); } - private ArraySet<UidRange> uidRange(int from, int to) { - final ArraySet<UidRange> range = new ArraySet<>(1); - range.add(new UidRange(from, to)); + private ArraySet<Range<Integer>> uidRanges(int from, int to) { + final ArraySet<Range<Integer>> range = new ArraySet<>(1); + range.add(uidRange(from, to)); return range; } + private Range<Integer> uidRange(int from, int to) { + return new Range<Integer>(from, to); + } + @Test @IgnoreUpTo(Build.VERSION_CODES.Q) public void testSetAdministratorUids() { NetworkCapabilities nc = @@ -601,23 +627,23 @@ public class NetworkCapabilitiesTest { } catch (IllegalStateException expected) {} nc1.setSSID(TEST_SSID); - nc1.setUids(uidRange(10, 13)); - assertNotEquals(nc1, nc2); - nc2.combineCapabilities(nc1); // Everything + 10~13 is still everything. - assertNotEquals(nc1, nc2); - nc1.combineCapabilities(nc2); // 10~13 + everything is everything. - assertEquals(nc1, nc2); - nc1.setUids(uidRange(10, 13)); - nc2.setUids(uidRange(20, 23)); - assertNotEquals(nc1, nc2); - nc1.combineCapabilities(nc2); - assertTrue(nc1.appliesToUid(12)); - assertFalse(nc2.appliesToUid(12)); - assertTrue(nc1.appliesToUid(22)); - assertTrue(nc2.appliesToUid(22)); - - // Verify the subscription id list can be combined only when they are equal. if (isAtLeastS()) { + nc1.setUids(uidRanges(10, 13)); + assertNotEquals(nc1, nc2); + nc2.combineCapabilities(nc1); // Everything + 10~13 is still everything. + assertNotEquals(nc1, nc2); + nc1.combineCapabilities(nc2); // 10~13 + everything is everything. + assertEquals(nc1, nc2); + nc1.setUids(uidRanges(10, 13)); + nc2.setUids(uidRanges(20, 23)); + assertNotEquals(nc1, nc2); + nc1.combineCapabilities(nc2); + assertTrue(nc1.appliesToUid(12)); + assertFalse(nc2.appliesToUid(12)); + assertTrue(nc1.appliesToUid(22)); + assertTrue(nc2.appliesToUid(22)); + + // Verify the subscription id list can be combined only when they are equal. nc1.setSubIds(Set.of(TEST_SUBID1, TEST_SUBID2)); nc2.setSubIds(Set.of(TEST_SUBID2)); assertThrows(IllegalStateException.class, () -> nc2.combineCapabilities(nc1)); @@ -773,8 +799,11 @@ public class NetworkCapabilitiesTest { if (isAtLeastR()) { assertTrue(DIFFERENT_TEST_SSID.equals(nc2.getSsid())); } - - nc1.setUids(uidRange(10, 13)); + if (isAtLeastS()) { + nc1.setUids(uidRanges(10, 13)); + } else { + nc1.setUids(null); + } nc2.set(nc1); // Overwrites, as opposed to combineCapabilities assertEquals(nc1, nc2); diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java index 01d8186c7d1b..e2d43cbb8efd 100644 --- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java +++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java @@ -44,11 +44,11 @@ import android.net.NetworkProvider; import android.net.NetworkSpecifier; import android.net.QosFilter; import android.net.SocketKeepalive; -import android.net.UidRange; import android.os.ConditionVariable; import android.os.HandlerThread; import android.os.Message; import android.util.Log; +import android.util.Range; import com.android.net.module.util.ArrayTrackRecord; import com.android.server.connectivity.ConnectivityConstants; @@ -222,7 +222,7 @@ public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork { mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities); } - public void setUids(Set<UidRange> uids) { + public void setUids(Set<Range<Integer>> uids) { mNetworkCapabilities.setUids(uids); mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities); } diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 7ac488d7de21..b25a5419732d 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -267,6 +267,7 @@ import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; import android.util.Pair; +import android.util.Range; import android.util.SparseArray; import androidx.test.InstrumentationRegistry; @@ -1159,7 +1160,7 @@ public class ConnectivityServiceTest { } public void setUids(Set<UidRange> uids) { - mNetworkCapabilities.setUids(uids); + mNetworkCapabilities.setUids(UidRange.toIntRanges(uids)); if (mAgentRegistered) { mMockNetworkAgent.setNetworkCapabilities(mNetworkCapabilities, true); } @@ -1464,6 +1465,8 @@ public class ConnectivityServiceTest { } private static final int PRIMARY_USER = 0; + private static final UidRange PRIMARY_UIDRANGE = + UidRange.createForUser(UserHandle.of(PRIMARY_USER)); 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); @@ -6946,7 +6949,7 @@ public class ConnectivityServiceTest { final int uid = Process.myUid(); NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); assertNotNull("nc=" + nc, nc.getUids()); - assertEquals(nc.getUids(), uidRangesForUids(uid)); + assertEquals(nc.getUids(), UidRange.toIntRanges(uidRangesForUids(uid))); assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE); // Set an underlying network and expect to see the VPN transports change. @@ -6971,10 +6974,13 @@ public class ConnectivityServiceTest { // Expect that the VPN UID ranges contain both |uid| and the UID range for the newly-added // restricted user. + final UidRange rRange = UidRange.createForUser(UserHandle.of(RESTRICTED_USER)); + final Range<Integer> restrictUidRange = new Range<Integer>(rRange.start, rRange.stop); + final Range<Integer> singleUidRange = new Range<Integer>(uid, uid); callback.expectCapabilitiesThat(mMockVpn, (caps) -> caps.getUids().size() == 2 - && caps.getUids().contains(new UidRange(uid, uid)) - && caps.getUids().contains(createUidRange(RESTRICTED_USER)) + && caps.getUids().contains(singleUidRange) + && caps.getUids().contains(restrictUidRange) && caps.hasTransport(TRANSPORT_VPN) && caps.hasTransport(TRANSPORT_WIFI)); @@ -6983,8 +6989,8 @@ public class ConnectivityServiceTest { callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); callback.expectCapabilitiesThat(mMockVpn, (caps) -> caps.getUids().size() == 2 - && caps.getUids().contains(new UidRange(uid, uid)) - && caps.getUids().contains(createUidRange(RESTRICTED_USER)) + && caps.getUids().contains(singleUidRange) + && caps.getUids().contains(restrictUidRange) && caps.hasTransport(TRANSPORT_VPN) && !caps.hasTransport(TRANSPORT_WIFI)); @@ -6998,7 +7004,7 @@ public class ConnectivityServiceTest { // change made just before that (i.e., loss of TRANSPORT_WIFI) is preserved. callback.expectCapabilitiesThat(mMockVpn, (caps) -> caps.getUids().size() == 1 - && caps.getUids().contains(new UidRange(uid, uid)) + && caps.getUids().contains(singleUidRange) && caps.hasTransport(TRANSPORT_VPN) && !caps.hasTransport(TRANSPORT_WIFI)); } @@ -7656,7 +7662,7 @@ public class ConnectivityServiceTest { assertNotNull(underlying); mMockVpn.setVpnType(VpnManager.TYPE_VPN_LEGACY); // The legacy lockdown VPN only supports userId 0. - final Set<UidRange> ranges = Collections.singleton(createUidRange(PRIMARY_USER)); + final Set<UidRange> ranges = Collections.singleton(PRIMARY_UIDRANGE); mMockVpn.registerAgent(ranges); mMockVpn.setUnderlyingNetworks(new Network[]{underlying}); mMockVpn.connect(true); @@ -8618,7 +8624,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(createUidRange(PRIMARY_USER)); + final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); mMockVpn.establish(lp, VPN_UID, vpnRange); assertVpnUidRangesUpdated(true, vpnRange, VPN_UID); @@ -8646,7 +8652,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(createUidRange(PRIMARY_USER)); + final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); mMockVpn.establish(lp, Process.SYSTEM_UID, vpnRange); assertVpnUidRangesUpdated(true, vpnRange, Process.SYSTEM_UID); @@ -8662,7 +8668,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(createUidRange(PRIMARY_USER)); + final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); mMockVpn.establish(lp, Process.SYSTEM_UID, vpnRange); assertVpnUidRangesUpdated(true, vpnRange, Process.SYSTEM_UID); @@ -8677,7 +8683,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(createUidRange(PRIMARY_USER)); + final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); mMockVpn.establish(lp, VPN_UID, vpnRange); assertVpnUidRangesUpdated(true, vpnRange, VPN_UID); @@ -8729,7 +8735,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 = createUidRange(PRIMARY_USER); + final UidRange vpnRange = PRIMARY_UIDRANGE; final Set<UidRange> vpnRanges = Collections.singleton(vpnRange); mMockVpn.establish(lp, VPN_UID, vpnRanges); assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID); @@ -9010,7 +9016,7 @@ public class ConnectivityServiceTest { private void setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType) throws Exception { - final Set<UidRange> vpnRange = Collections.singleton(createUidRange(PRIMARY_USER)); + final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); mMockVpn.setVpnType(vpnType); mMockVpn.establish(new LinkProperties(), vpnOwnerUid, vpnRange); assertVpnUidRangesUpdated(true, vpnRange, vpnOwnerUid); @@ -9570,7 +9576,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 = createUidRange(PRIMARY_USER); + final UidRange vpnRange = PRIMARY_UIDRANGE; Set<UidRange> vpnRanges = Collections.singleton(vpnRange); mMockVpn.establish(lp, VPN_UID, vpnRanges); assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID); @@ -9768,7 +9774,7 @@ public class ConnectivityServiceTest { .thenReturn(hasFeature); } - private UidRange getNriFirstUidRange( + private Range<Integer> getNriFirstUidRange( @NonNull final ConnectivityService.NetworkRequestInfo nri) { return nri.mRequests.get(0).networkCapabilities.getUids().iterator().next(); } @@ -9951,11 +9957,11 @@ public class ConnectivityServiceTest { pref)); // Sort by uid to access nris by index - nris.sort(Comparator.comparingInt(nri -> getNriFirstUidRange(nri).start)); - assertEquals(TEST_PACKAGE_UID, getNriFirstUidRange(nris.get(0)).start); - assertEquals(TEST_PACKAGE_UID, getNriFirstUidRange(nris.get(0)).stop); - assertEquals(testPackageNameUid2, getNriFirstUidRange(nris.get(1)).start); - assertEquals(testPackageNameUid2, getNriFirstUidRange(nris.get(1)).stop); + nris.sort(Comparator.comparingInt(nri -> getNriFirstUidRange(nri).getLower())); + assertEquals(TEST_PACKAGE_UID, (int) getNriFirstUidRange(nris.get(0)).getLower()); + assertEquals(TEST_PACKAGE_UID, (int) getNriFirstUidRange(nris.get(0)).getUpper()); + assertEquals(testPackageNameUid2, (int) getNriFirstUidRange(nris.get(1)).getLower()); + assertEquals(testPackageNameUid2, (int) getNriFirstUidRange(nris.get(1)).getUpper()); } @Test @@ -9985,17 +9991,17 @@ public class ConnectivityServiceTest { // UIDs for all users and all managed packages should be present. // Two users each with two packages. final int expectedUidSize = 2; - final List<UidRange> uids = + final List<Range<Integer>> uids = new ArrayList<>(nris.get(0).mRequests.get(0).networkCapabilities.getUids()); assertEquals(expectedUidSize, uids.size()); // Sort by uid to access nris by index - uids.sort(Comparator.comparingInt(uid -> uid.start)); + uids.sort(Comparator.comparingInt(uid -> uid.getLower())); final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID); - assertEquals(TEST_PACKAGE_UID, uids.get(0).start); - assertEquals(TEST_PACKAGE_UID, uids.get(0).stop); - assertEquals(secondUserTestPackageUid, uids.get(1).start); - assertEquals(secondUserTestPackageUid, uids.get(1).stop); + assertEquals(TEST_PACKAGE_UID, (int) uids.get(0).getLower()); + assertEquals(TEST_PACKAGE_UID, (int) uids.get(0).getUpper()); + assertEquals(secondUserTestPackageUid, (int) uids.get(1).getLower()); + assertEquals(secondUserTestPackageUid, (int) uids.get(1).getUpper()); } @Test diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java index 11fcea60d98d..6ad4900989f5 100644 --- a/tests/net/java/com/android/server/connectivity/VpnTest.java +++ b/tests/net/java/com/android/server/connectivity/VpnTest.java @@ -23,6 +23,7 @@ import static android.content.pm.UserInfo.FLAG_RESTRICTED; import static android.net.ConnectivityManager.NetworkCallback; import static android.net.INetd.IF_STATE_DOWN; import static android.net.INetd.IF_STATE_UP; +import static android.os.UserHandle.PER_USER_RANGE; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -74,7 +75,6 @@ import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkInfo.DetailedState; import android.net.RouteInfo; -import android.net.UidRange; import android.net.UidRangeParcel; import android.net.VpnManager; import android.net.VpnService; @@ -181,8 +181,7 @@ public class VpnTest { mPackages.put(PKGS[i], PKG_UIDS[i]); } } - private static final UidRange PRI_USER_RANGE = - UidRange.createForUser(UserHandle.of(primaryUser.id)); + private static final Range<Integer> PRI_USER_RANGE = uidRangeForUser(primaryUser.id); @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext; @Mock private UserManager mUserManager; @@ -260,6 +259,21 @@ public class VpnTest { .thenReturn(tunnelResp); } + private Set<Range<Integer>> rangeSet(Range<Integer> ... ranges) { + final Set<Range<Integer>> range = new ArraySet<>(); + for (Range<Integer> r : ranges) range.add(r); + + return range; + } + + private static Range<Integer> uidRangeForUser(int userId) { + return new Range<Integer>(userId * PER_USER_RANGE, (userId + 1) * PER_USER_RANGE - 1); + } + + private Range<Integer> uidRange(int start, int stop) { + return new Range<Integer>(start, stop); + } + @Test public void testRestrictedProfilesAreAddedToVpn() { setMockedUsers(primaryUser, secondaryUser, restrictedProfileA, restrictedProfileB); @@ -268,12 +282,10 @@ public class VpnTest { // Assume the user can have restricted profiles. doReturn(true).when(mUserManager).canHaveRestrictedProfile(); - final Set<UidRange> ranges = + final Set<Range<Integer>> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, null, null); - assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] { - PRI_USER_RANGE, UidRange.createForUser(UserHandle.of(restrictedProfileA.id)) - })), ranges); + assertEquals(rangeSet(PRI_USER_RANGE, uidRangeForUser(restrictedProfileA.id)), ranges); } @Test @@ -281,10 +293,10 @@ public class VpnTest { setMockedUsers(primaryUser, managedProfileA); final Vpn vpn = createVpn(primaryUser.id); - final Set<UidRange> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, + final Set<Range<Integer>> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, null, null); - assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] { PRI_USER_RANGE })), ranges); + assertEquals(rangeSet(PRI_USER_RANGE), ranges); } @Test @@ -292,35 +304,38 @@ public class VpnTest { setMockedUsers(primaryUser, restrictedProfileA, managedProfileA); final Vpn vpn = createVpn(primaryUser.id); - final Set<UidRange> ranges = new ArraySet<>(); + final Set<Range<Integer>> ranges = new ArraySet<>(); vpn.addUserToRanges(ranges, primaryUser.id, null, null); - assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] { PRI_USER_RANGE })), ranges); + assertEquals(rangeSet(PRI_USER_RANGE), ranges); } @Test public void testUidAllowAndDenylist() throws Exception { final Vpn vpn = createVpn(primaryUser.id); - final UidRange user = PRI_USER_RANGE; + final Range<Integer> user = PRI_USER_RANGE; + final int userStart = user.getLower(); + final int userStop = user.getUpper(); final String[] packages = {PKGS[0], PKGS[1], PKGS[2]}; // Allowed list - final Set<UidRange> allow = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, - Arrays.asList(packages), null); - assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] { - new UidRange(user.start + PKG_UIDS[0], user.start + PKG_UIDS[0]), - new UidRange(user.start + PKG_UIDS[1], user.start + PKG_UIDS[2]) - })), allow); + final Set<Range<Integer>> allow = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, + Arrays.asList(packages), null /* disallowedApplications */); + assertEquals(rangeSet( + uidRange(userStart + PKG_UIDS[0], userStart + PKG_UIDS[0]), + uidRange(userStart + PKG_UIDS[1], userStart + PKG_UIDS[2])), + allow); // Denied list - final Set<UidRange> disallow = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, - null, Arrays.asList(packages)); - assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] { - new UidRange(user.start, user.start + PKG_UIDS[0] - 1), - new UidRange(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[1] - 1), - /* Empty range between UIDS[1] and UIDS[2], should be excluded, */ - new UidRange(user.start + PKG_UIDS[2] + 1, user.stop) - })), disallow); + final Set<Range<Integer>> disallow = + vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, + null /* allowedApplications */, Arrays.asList(packages)); + assertEquals(rangeSet( + uidRange(userStart, userStart + PKG_UIDS[0] - 1), + uidRange(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[1] - 1), + /* Empty range between UIDS[1] and UIDS[2], should be excluded, */ + uidRange(userStart + PKG_UIDS[2] + 1, userStop)), + disallow); } @Test @@ -350,84 +365,86 @@ public class VpnTest { @Test public void testLockdownChangingPackage() throws Exception { final Vpn vpn = createVpn(primaryUser.id); - final UidRange user = PRI_USER_RANGE; - + final Range<Integer> user = PRI_USER_RANGE; + final int userStart = user.getLower(); + final int userStop = user.getUpper(); // Set always-on without lockdown. assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false, null)); // Set always-on with lockdown. assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true, null)); 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) + new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1), + new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStop) })); // Switch to another app. assertTrue(vpn.setAlwaysOnPackage(PKGS[3], true, null)); 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) + new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1), + new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStop) })); 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) + new UidRangeParcel(userStart, userStart + PKG_UIDS[3] - 1), + new UidRangeParcel(userStart + PKG_UIDS[3] + 1, userStop) })); } @Test public void testLockdownAllowlist() throws Exception { final Vpn vpn = createVpn(primaryUser.id); - final UidRange user = PRI_USER_RANGE; - + final Range<Integer> user = PRI_USER_RANGE; + final int userStart = user.getLower(); + final int userStop = user.getUpper(); // Set always-on with lockdown and allow app PKGS[2] from lockdown. assertTrue(vpn.setAlwaysOnPackage( PKGS[1], true, Collections.singletonList(PKGS[2]))); - 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) + verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { + new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1), + new UidRangeParcel(userStart + PKG_UIDS[2] + 1, userStop) })); // Change allowed app list to PKGS[3]. assertTrue(vpn.setAlwaysOnPackage( PKGS[1], true, Collections.singletonList(PKGS[3]))); verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] { - new UidRangeParcel(user.start + PKG_UIDS[2] + 1, user.stop) + new UidRangeParcel(userStart + PKG_UIDS[2] + 1, userStop) })); 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) + new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStart + PKG_UIDS[3] - 1), + new UidRangeParcel(userStart + PKG_UIDS[3] + 1, userStop) })); // Change the VPN app. assertTrue(vpn.setAlwaysOnPackage( PKGS[0], true, Collections.singletonList(PKGS[3]))); 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) + new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1), + new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStart + PKG_UIDS[3] - 1) })); 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) + new UidRangeParcel(userStart, userStart + PKG_UIDS[0] - 1), + new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[3] - 1) })); // Remove the list of allowed packages. assertTrue(vpn.setAlwaysOnPackage(PKGS[0], true, null)); 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) + new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[3] - 1), + new UidRangeParcel(userStart + PKG_UIDS[3] + 1, userStop) })); verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { - new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.stop), + new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStop), })); // Add the list of allowed packages. assertTrue(vpn.setAlwaysOnPackage( PKGS[0], true, Collections.singletonList(PKGS[1]))); verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] { - new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.stop) + new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStop) })); 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) + new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[1] - 1), + new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStop) })); // Try allowing a package with a comma, should be rejected. @@ -439,12 +456,12 @@ public class VpnTest { assertTrue(vpn.setAlwaysOnPackage( PKGS[0], true, Arrays.asList("com.foo.app", PKGS[2], "com.bar.app"))); 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) + new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[1] - 1), + new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStop) })); 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) + new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[2] - 1), + new UidRangeParcel(userStart + PKG_UIDS[2] + 1, userStop) })); } @@ -452,7 +469,7 @@ public class VpnTest { public void testLockdownRuleRepeatability() throws Exception { final Vpn vpn = createVpn(primaryUser.id); final UidRangeParcel[] primaryUserRangeParcel = new UidRangeParcel[] { - new UidRangeParcel(PRI_USER_RANGE.start, PRI_USER_RANGE.stop)}; + new UidRangeParcel(PRI_USER_RANGE.getLower(), PRI_USER_RANGE.getUpper())}; // Given legacy lockdown is already enabled, vpn.setLockdown(true); verify(mConnectivityManager, times(1)).setRequireVpnForUids(true, @@ -484,7 +501,7 @@ public class VpnTest { public void testLockdownRuleReversibility() throws Exception { final Vpn vpn = createVpn(primaryUser.id); final UidRangeParcel[] entireUser = { - new UidRangeParcel(PRI_USER_RANGE.start, PRI_USER_RANGE.stop) + new UidRangeParcel(PRI_USER_RANGE.getLower(), PRI_USER_RANGE.getUpper()) }; final UidRangeParcel[] exceptPkg0 = { new UidRangeParcel(entireUser[0].start, entireUser[0].start + PKG_UIDS[0] - 1), |