Merge changes from topics "ADD_JVMOVERLOADS", "VPN_NETWORK_PREFERENCE"
* changes: Add HostsideVpnTests for testing setVpnDefaultForUids() Add CTS for ConnectivityManager#setVpnDefaultForUids() Create a new API to make a set of UIDs use only VPN by default
This commit is contained in:
@@ -31,6 +31,7 @@ package android.net {
|
||||
method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setProfileNetworkPreferences(@NonNull android.os.UserHandle, @NonNull java.util.List<android.net.ProfileNetworkPreference>, @Nullable java.util.concurrent.Executor, @Nullable Runnable);
|
||||
method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void setRequireVpnForUids(boolean, @NonNull java.util.Collection<android.util.Range<java.lang.Integer>>);
|
||||
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setUidFirewallRule(int, int, int);
|
||||
method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void setVpnDefaultForUids(@NonNull String, @NonNull java.util.Collection<android.util.Range<java.lang.Integer>>);
|
||||
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_TEST_NETWORKS, android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle);
|
||||
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void startCaptivePortalApp(@NonNull android.net.Network);
|
||||
method public void systemReady();
|
||||
|
||||
@@ -1378,6 +1378,17 @@ public class ConnectivityManager {
|
||||
}
|
||||
}
|
||||
|
||||
private static UidRange[] getUidRangeArray(@NonNull Collection<Range<Integer>> ranges) {
|
||||
Objects.requireNonNull(ranges);
|
||||
final UidRange[] rangesArray = new UidRange[ranges.size()];
|
||||
int index = 0;
|
||||
for (Range<Integer> range : ranges) {
|
||||
rangesArray[index++] = new UidRange(range.getLower(), range.getUpper());
|
||||
}
|
||||
|
||||
return rangesArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds or removes a requirement for given UID ranges to use the VPN.
|
||||
*
|
||||
@@ -1397,6 +1408,12 @@ public class ConnectivityManager {
|
||||
* {@link NetworkCallback#onBlockedStatusChanged} callbacks called after the changes take
|
||||
* effect.
|
||||
* <p>
|
||||
* This method will block the specified UIDs from accessing non-VPN networks, but does not
|
||||
* affect what the UIDs get as their default network.
|
||||
* Compare {@link #setVpnDefaultForUids(String, Collection)}, which declares that the UIDs
|
||||
* should only have a VPN as their default network, but does not block them from accessing other
|
||||
* networks if they request them explicitly with the {@link Network} API.
|
||||
* <p>
|
||||
* This method should be called only by the VPN code.
|
||||
*
|
||||
* @param ranges the UID ranges to restrict
|
||||
@@ -1416,11 +1433,7 @@ public class ConnectivityManager {
|
||||
// This method is not necessarily expected to be used outside the system server, so
|
||||
// parceling may not be necessary, but it could be used out-of-process, e.g., by the network
|
||||
// stack process, or by tests.
|
||||
UidRange[] rangesArray = new UidRange[ranges.size()];
|
||||
int index = 0;
|
||||
for (Range<Integer> range : ranges) {
|
||||
rangesArray[index++] = new UidRange(range.getLower(), range.getUpper());
|
||||
}
|
||||
final UidRange[] rangesArray = getUidRangeArray(ranges);
|
||||
try {
|
||||
mService.setRequireVpnForUids(requireVpn, rangesArray);
|
||||
} catch (RemoteException e) {
|
||||
@@ -1428,6 +1441,41 @@ public class ConnectivityManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inform the system that this VPN session should manage the passed UIDs.
|
||||
*
|
||||
* A VPN with the specified session ID may call this method to inform the system that the UIDs
|
||||
* in the specified range are subject to a VPN.
|
||||
* When this is called, the system will only choose a VPN for the default network of the UIDs in
|
||||
* the specified ranges.
|
||||
*
|
||||
* This method declares that the UIDs in the range will only have a VPN for their default
|
||||
* network, but does not block the UIDs from accessing other networks (permissions allowing) by
|
||||
* explicitly requesting it with the {@link Network} API.
|
||||
* Compare {@link #setRequireVpnForUids(boolean, Collection)}, which does not affect what
|
||||
* network the UIDs get as default, but will block them from accessing non-VPN networks.
|
||||
*
|
||||
* @param session The VPN session which manages the passed UIDs.
|
||||
* @param ranges The uid ranges which will treat VPN as their only default network.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(anyOf = {
|
||||
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
|
||||
android.Manifest.permission.NETWORK_STACK,
|
||||
android.Manifest.permission.NETWORK_SETTINGS})
|
||||
@SystemApi(client = MODULE_LIBRARIES)
|
||||
public void setVpnDefaultForUids(@NonNull String session,
|
||||
@NonNull Collection<Range<Integer>> ranges) {
|
||||
Objects.requireNonNull(ranges);
|
||||
final UidRange[] rangesArray = getUidRangeArray(ranges);
|
||||
try {
|
||||
mService.setVpnNetworkPreference(session, rangesArray);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Informs ConnectivityService of whether the legacy lockdown VPN, as implemented by
|
||||
* LockdownVpnTracker, is in use. This is deprecated for new devices starting from Android 12
|
||||
|
||||
@@ -249,4 +249,6 @@ interface IConnectivityManager
|
||||
void replaceFirewallChain(int chain, in int[] uids);
|
||||
|
||||
IBinder getCompanionDeviceManagerProxyService();
|
||||
|
||||
void setVpnNetworkPreference(String session, in UidRange[] ranges);
|
||||
}
|
||||
|
||||
@@ -286,6 +286,7 @@ import com.android.server.connectivity.ProfileNetworkPreferenceInfo;
|
||||
import com.android.server.connectivity.ProxyTracker;
|
||||
import com.android.server.connectivity.QosCallbackTracker;
|
||||
import com.android.server.connectivity.UidRangeUtils;
|
||||
import com.android.server.connectivity.VpnNetworkPreferenceInfo;
|
||||
import com.android.server.connectivity.wear.CompanionDeviceManagerProxyService;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
@@ -746,6 +747,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
*/
|
||||
private static final int EVENT_USER_DOES_NOT_WANT = 58;
|
||||
|
||||
/**
|
||||
* Event to set VPN as preferred network for specific apps.
|
||||
* obj = VpnNetworkPreferenceInfo
|
||||
*/
|
||||
private static final int EVENT_SET_VPN_NETWORK_PREFERENCE = 59;
|
||||
|
||||
/**
|
||||
* Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
|
||||
* should be shown.
|
||||
@@ -1625,6 +1632,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
TYPE_NONE, NetworkRequest.Type.REQUEST);
|
||||
}
|
||||
|
||||
private NetworkRequest createVpnRequest() {
|
||||
final NetworkCapabilities netCap = new NetworkCapabilities.Builder()
|
||||
.withoutDefaultCapabilities()
|
||||
.addTransportType(TRANSPORT_VPN)
|
||||
.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
|
||||
.addCapability(NET_CAPABILITY_NOT_RESTRICTED)
|
||||
.build();
|
||||
netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
|
||||
return createNetworkRequest(NetworkRequest.Type.REQUEST, netCap);
|
||||
}
|
||||
|
||||
private NetworkRequest createDefaultInternetRequestForTransport(
|
||||
int transportType, NetworkRequest.Type type) {
|
||||
final NetworkCapabilities netCap = new NetworkCapabilities();
|
||||
@@ -5532,6 +5550,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
nai.onPreventAutomaticReconnect();
|
||||
nai.disconnect();
|
||||
break;
|
||||
case EVENT_SET_VPN_NETWORK_PREFERENCE:
|
||||
handleSetVpnNetworkPreference((VpnNetworkPreferenceInfo) msg.obj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7123,6 +7144,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
private NetworkPreferenceList<UserHandle, ProfileNetworkPreferenceInfo>
|
||||
mProfileNetworkPreferences = new NetworkPreferenceList<>();
|
||||
|
||||
// Current VPN network preferences. This object follows the same threading rules as the OEM
|
||||
// network preferences above.
|
||||
@NonNull
|
||||
private NetworkPreferenceList<String, VpnNetworkPreferenceInfo>
|
||||
mVpnNetworkPreferences = new NetworkPreferenceList<>();
|
||||
|
||||
// A set of UIDs that should use mobile data preferentially if available. This object follows
|
||||
// the same threading rules as the OEM network preferences above.
|
||||
@NonNull
|
||||
@@ -11112,6 +11139,60 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
new Pair<>(preference, listener)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specified UIDs to get/receive the VPN as the only default network.
|
||||
*
|
||||
* Calling this will overwrite the existing network preference for this session, and the
|
||||
* specified UIDs won't get any default network when no VPN is connected.
|
||||
*
|
||||
* @param session The VPN session which manages the passed UIDs.
|
||||
* @param ranges The uid ranges which will treat VPN as the only preferred network. Clear the
|
||||
* setting for this session if the array is empty. Null is not allowed, the
|
||||
* method will use {@link Objects#requireNonNull(Object)} to check this variable.
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
public void setVpnNetworkPreference(String session, UidRange[] ranges) {
|
||||
Objects.requireNonNull(ranges);
|
||||
enforceNetworkStackOrSettingsPermission();
|
||||
final UidRange[] sortedRanges = UidRangeUtils.sortRangesByStartUid(ranges);
|
||||
if (UidRangeUtils.sortedRangesContainOverlap(sortedRanges)) {
|
||||
throw new IllegalArgumentException(
|
||||
"setVpnNetworkPreference: Passed UID ranges overlap");
|
||||
}
|
||||
|
||||
mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_VPN_NETWORK_PREFERENCE,
|
||||
new VpnNetworkPreferenceInfo(session,
|
||||
new ArraySet<UidRange>(Arrays.asList(ranges)))));
|
||||
}
|
||||
|
||||
private void handleSetVpnNetworkPreference(VpnNetworkPreferenceInfo preferenceInfo) {
|
||||
Log.d(TAG, "handleSetVpnNetworkPreference: preferenceInfo = " + preferenceInfo);
|
||||
|
||||
mVpnNetworkPreferences = mVpnNetworkPreferences.minus(preferenceInfo.getKey());
|
||||
mVpnNetworkPreferences = mVpnNetworkPreferences.plus(preferenceInfo);
|
||||
|
||||
removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_VPN);
|
||||
addPerAppDefaultNetworkRequests(createNrisForVpnNetworkPreference(mVpnNetworkPreferences));
|
||||
// Finally, rematch.
|
||||
rematchAllNetworksAndRequests();
|
||||
}
|
||||
|
||||
private ArraySet<NetworkRequestInfo> createNrisForVpnNetworkPreference(
|
||||
@NonNull NetworkPreferenceList<String, VpnNetworkPreferenceInfo> preferenceList) {
|
||||
final ArraySet<NetworkRequestInfo> nris = new ArraySet<>();
|
||||
for (VpnNetworkPreferenceInfo preferenceInfo : preferenceList) {
|
||||
final List<NetworkRequest> requests = new ArrayList<>();
|
||||
// Request VPN only, so other networks won't be the fallback options when VPN is not
|
||||
// connected temporarily.
|
||||
requests.add(createVpnRequest());
|
||||
final Set<UidRange> uidRanges = new ArraySet(preferenceInfo.getUidRangesNoCopy());
|
||||
setNetworkRequestUids(requests, uidRanges);
|
||||
nris.add(new NetworkRequestInfo(Process.myUid(), requests, PREFERENCE_ORDER_VPN));
|
||||
}
|
||||
return nris;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the validity of an OEM network preference to be used for testing purposes.
|
||||
* @param preference the preference to validate
|
||||
|
||||
@@ -184,4 +184,41 @@ public final class UidRangeUtils {
|
||||
uidRangeSet.add(new UidRange(start, stop));
|
||||
return uidRangeSet;
|
||||
}
|
||||
|
||||
private static int compare(UidRange range1, UidRange range2) {
|
||||
return range1.start - range2.start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the given UidRange array.
|
||||
*
|
||||
* @param ranges The array of UidRange which is going to be sorted.
|
||||
* @return Array of UidRange.
|
||||
*/
|
||||
public static UidRange[] sortRangesByStartUid(UidRange[] ranges) {
|
||||
final ArrayList uidRanges = new ArrayList(Arrays.asList(ranges));
|
||||
Collections.sort(uidRanges, UidRangeUtils::compare);
|
||||
return (UidRange[]) uidRanges.toArray(new UidRange[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given sorted UidRange array contains overlap or not.
|
||||
*
|
||||
* Note that the sorted UidRange array must be sorted by increasing lower bound. If it's not,
|
||||
* the behavior is undefined.
|
||||
*
|
||||
* @param ranges The sorted UidRange array which is going to be checked if there is an overlap
|
||||
* or not.
|
||||
* @return A boolean to indicate if the given sorted UidRange array contains overlap or not.
|
||||
*/
|
||||
public static boolean sortedRangesContainOverlap(UidRange[] ranges) {
|
||||
final ArrayList uidRanges = new ArrayList(Arrays.asList(ranges));
|
||||
for (int i = 0; i + 1 < uidRanges.size(); i++) {
|
||||
if (((UidRange) uidRanges.get(i + 1)).start <= ((UidRange) uidRanges.get(i)).stop) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.connectivity;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.net.UidRange;
|
||||
import android.util.ArraySet;
|
||||
|
||||
/**
|
||||
* Record the session and UidRange for a VPN preference.
|
||||
*/
|
||||
public class VpnNetworkPreferenceInfo
|
||||
implements NetworkPreferenceList.NetworkPreference<String> {
|
||||
|
||||
@NonNull
|
||||
public final String mSession;
|
||||
|
||||
@NonNull
|
||||
public final ArraySet<UidRange> mUidRanges;
|
||||
|
||||
public VpnNetworkPreferenceInfo(@NonNull String session,
|
||||
@NonNull ArraySet<UidRange> uidRanges) {
|
||||
this.mSession = session;
|
||||
this.mUidRanges = uidRanges;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancel() {
|
||||
return mUidRanges.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public String getKey() {
|
||||
return mSession;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public ArraySet<UidRange> getUidRangesNoCopy() {
|
||||
return mUidRanges;
|
||||
}
|
||||
|
||||
/** toString */
|
||||
public String toString() {
|
||||
return "[VpnNetworkPreference session = " + mSession
|
||||
+ " uidRanges = " + mUidRanges
|
||||
+ "]";
|
||||
}
|
||||
}
|
||||
@@ -97,6 +97,7 @@ import android.system.StructPollfd;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.test.MoreAsserts;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
import android.util.Range;
|
||||
|
||||
@@ -108,6 +109,7 @@ import com.android.net.module.util.PacketBuilder;
|
||||
import com.android.testutils.DevSdkIgnoreRule;
|
||||
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
|
||||
import com.android.testutils.RecorderCallback;
|
||||
import com.android.testutils.RecorderCallback.CallbackEntry;
|
||||
import com.android.testutils.TestableNetworkCallback;
|
||||
|
||||
import org.junit.After;
|
||||
@@ -136,6 +138,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -839,8 +842,13 @@ public class VpnTest {
|
||||
callback.eventuallyExpect(RecorderCallback.CallbackEntry.NETWORK_CAPS_UPDATED,
|
||||
NETWORK_CALLBACK_TIMEOUT_MS,
|
||||
entry -> (Objects.equals(expectUnderlyingNetworks,
|
||||
((RecorderCallback.CallbackEntry.CapabilitiesChanged) entry)
|
||||
.getCaps().getUnderlyingNetworks())));
|
||||
entry.getCaps().getUnderlyingNetworks())));
|
||||
}
|
||||
|
||||
private void expectVpnNetwork(TestableNetworkCallback callback) {
|
||||
callback.eventuallyExpect(RecorderCallback.CallbackEntry.NETWORK_CAPS_UPDATED,
|
||||
NETWORK_CALLBACK_TIMEOUT_MS,
|
||||
entry -> entry.getCaps().hasTransport(TRANSPORT_VPN));
|
||||
}
|
||||
|
||||
@Test @IgnoreUpTo(SC_V2) // TODO: Use to Build.VERSION_CODES.SC_V2 when available
|
||||
@@ -1622,7 +1630,7 @@ public class VpnTest {
|
||||
mCM.registerDefaultNetworkCallbackForUid(remoteUid, remoteUidCallback,
|
||||
new Handler(Looper.getMainLooper()));
|
||||
}, NETWORK_SETTINGS);
|
||||
remoteUidCallback.expectAvailableCallbacks(network);
|
||||
remoteUidCallback.expectAvailableCallbacksWithBlockedReasonNone(network);
|
||||
|
||||
// The remote UDP socket can receive packets coming from the TUN interface
|
||||
checkBlockIncomingPacket(tunFd, remoteUdpFd, EXPECT_PASS);
|
||||
@@ -1666,6 +1674,56 @@ public class VpnTest {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetVpnDefaultForUids() throws Exception {
|
||||
assumeTrue(supportedHardware());
|
||||
assumeTrue(SdkLevel.isAtLeastU());
|
||||
|
||||
final Network defaultNetwork = mCM.getActiveNetwork();
|
||||
assertNotNull("There must be a default network", defaultNetwork);
|
||||
|
||||
final TestableNetworkCallback defaultNetworkCallback = new TestableNetworkCallback();
|
||||
final String session = UUID.randomUUID().toString();
|
||||
final int myUid = Process.myUid();
|
||||
|
||||
testAndCleanup(() -> {
|
||||
mCM.registerDefaultNetworkCallback(defaultNetworkCallback);
|
||||
defaultNetworkCallback.expectAvailableCallbacks(defaultNetwork);
|
||||
|
||||
final Range<Integer> myUidRange = new Range<>(myUid, myUid);
|
||||
runWithShellPermissionIdentity(() -> {
|
||||
mCM.setVpnDefaultForUids(session, List.of(myUidRange));
|
||||
}, NETWORK_SETTINGS);
|
||||
|
||||
// The VPN will be the only default network for the app, so it's expected to receive
|
||||
// onLost() callback.
|
||||
defaultNetworkCallback.eventuallyExpect(CallbackEntry.LOST);
|
||||
|
||||
final ArrayList<Network> underlyingNetworks = new ArrayList<>();
|
||||
underlyingNetworks.add(defaultNetwork);
|
||||
startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"} /* addresses */,
|
||||
new String[] {"0.0.0.0/0", "::/0"} /* routes */,
|
||||
"" /* allowedApplications */, "" /* disallowedApplications */,
|
||||
null /* proxyInfo */, underlyingNetworks, false /* isAlwaysMetered */);
|
||||
|
||||
expectVpnNetwork(defaultNetworkCallback);
|
||||
}, /* cleanup */ () -> {
|
||||
stopVpn();
|
||||
defaultNetworkCallback.eventuallyExpect(CallbackEntry.LOST);
|
||||
}, /* cleanup */ () -> {
|
||||
runWithShellPermissionIdentity(() -> {
|
||||
mCM.setVpnDefaultForUids(session, new ArraySet<>());
|
||||
}, NETWORK_SETTINGS);
|
||||
// The default network of the app will be changed back to wifi when the VPN network
|
||||
// preference feature is disabled.
|
||||
defaultNetworkCallback.eventuallyExpect(CallbackEntry.AVAILABLE,
|
||||
NETWORK_CALLBACK_TIMEOUT_MS,
|
||||
entry -> defaultNetwork.equals(entry.getNetwork()));
|
||||
}, /* cleanup */ () -> {
|
||||
mCM.unregisterNetworkCallback(defaultNetworkCallback);
|
||||
});
|
||||
}
|
||||
|
||||
private ByteBuffer buildIpv4UdpPacket(final Inet4Address dstAddr, final Inet4Address srcAddr,
|
||||
final short dstPort, final short srcPort, final byte[] payload) throws IOException {
|
||||
|
||||
@@ -1756,7 +1814,7 @@ public class VpnTest {
|
||||
}
|
||||
|
||||
private class DetailedBlockedStatusCallback extends TestableNetworkCallback {
|
||||
public void expectAvailableCallbacks(Network network) {
|
||||
public void expectAvailableCallbacksWithBlockedReasonNone(Network network) {
|
||||
super.expectAvailableCallbacks(network, false /* suspended */, true /* validated */,
|
||||
BLOCKED_REASON_NONE, NETWORK_CALLBACK_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
@@ -120,4 +120,8 @@ public class HostsideVpnTests extends HostsideNetworkTestCase {
|
||||
public void testBlockIncomingPackets() throws Exception {
|
||||
runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testBlockIncomingPackets");
|
||||
}
|
||||
|
||||
public void testSetVpnDefaultForUids() throws Exception {
|
||||
runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testSetVpnDefaultForUids");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,6 +233,7 @@ import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Executor;
|
||||
@@ -2378,7 +2379,7 @@ public class ConnectivityManagerTest {
|
||||
}
|
||||
|
||||
private class DetailedBlockedStatusCallback extends TestableNetworkCallback {
|
||||
public void expectAvailableCallbacks(Network network) {
|
||||
public void expectAvailableCallbacksWithBlockedReasonNone(Network network) {
|
||||
super.expectAvailableCallbacks(network, false /* suspended */, true /* validated */,
|
||||
BLOCKED_REASON_NONE, NETWORK_CALLBACK_TIMEOUT_MS);
|
||||
}
|
||||
@@ -2431,7 +2432,7 @@ public class ConnectivityManagerTest {
|
||||
final List<DetailedBlockedStatusCallback> allCallbacks =
|
||||
List.of(myUidCallback, otherUidCallback);
|
||||
for (DetailedBlockedStatusCallback callback : allCallbacks) {
|
||||
callback.expectAvailableCallbacks(defaultNetwork);
|
||||
callback.expectAvailableCallbacksWithBlockedReasonNone(defaultNetwork);
|
||||
}
|
||||
|
||||
final Range<Integer> myUidRange = new Range<>(myUid, myUid);
|
||||
@@ -2469,6 +2470,17 @@ public class ConnectivityManagerTest {
|
||||
runWithShellPermissionIdentity(() -> doTestBlockedStatusCallback(), NETWORK_SETTINGS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetVpnDefaultForUids() {
|
||||
assumeTrue(TestUtils.shouldTestUApis());
|
||||
final String session = UUID.randomUUID().toString();
|
||||
assertThrows(NullPointerException.class, () -> mCm.setVpnDefaultForUids(session, null));
|
||||
assertThrows(SecurityException.class,
|
||||
() -> mCm.setVpnDefaultForUids(session, new ArraySet<>()));
|
||||
// For testing the complete behavior of setVpnDefaultForUids(), please refer to
|
||||
// HostsideVpnTests.
|
||||
}
|
||||
|
||||
private void doTestLegacyLockdownEnabled() throws Exception {
|
||||
NetworkInfo info = mCm.getActiveNetworkInfo();
|
||||
assertNotNull(info);
|
||||
|
||||
@@ -402,4 +402,27 @@ public class UidRangeUtilsTest {
|
||||
expected.add(uids20_24);
|
||||
assertEquals(expected, UidRangeUtils.convertArrayToUidRange(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSortRangesByStartUid() throws Exception {
|
||||
final UidRange uid1 = new UidRange(100, 110);
|
||||
final UidRange uid2 = new UidRange(120, 130);
|
||||
final UidRange[] unsortedRanges = new UidRange[] {uid2, uid1};
|
||||
final UidRange[] sortedRanges = UidRangeUtils.sortRangesByStartUid(unsortedRanges);
|
||||
assertEquals(uid1, sortedRanges[0]);
|
||||
assertEquals(uid2, sortedRanges[1]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSortedRangesContainOverlap() throws Exception {
|
||||
final UidRange uid1 = new UidRange(100, 110);
|
||||
final UidRange uid2 = new UidRange(109, 120);
|
||||
final UidRange uid3 = new UidRange(120, 130);
|
||||
final UidRange[] overlapRanges1 = new UidRange[] {uid1, uid2};
|
||||
final UidRange[] overlapRanges2 = new UidRange[] {uid2, uid3};
|
||||
final UidRange[] notOverlapRanges = new UidRange[] {uid1, uid3};
|
||||
assertTrue(UidRangeUtils.sortedRangesContainOverlap(overlapRanges1));
|
||||
assertTrue(UidRangeUtils.sortedRangesContainOverlap(overlapRanges2));
|
||||
assertFalse(UidRangeUtils.sortedRangesContainOverlap(notOverlapRanges));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user