From cf52cee4435a2ceb3e48becede5109aeea5061f3 Mon Sep 17 00:00:00 2001 From: lucaslin Date: Tue, 20 Dec 2022 09:02:15 +0000 Subject: [PATCH] Add HostsideVpnTests for testing setVpnDefaultForUids() The test will check if the VPN will be the only default network for the app after ConnectivityManager#setVpnDefaultForUids() is called. Bug: 231749077 Test: atest CtsHostsideNetworkTests:HostsideVpnTests Change-Id: I02758ad7d948342797b6a4b00dfec3acdf44775d --- .../com/android/cts/net/hostside/VpnTest.java | 66 +++++++++++++++++-- .../com/android/cts/net/HostsideVpnTests.java | 4 ++ .../net/cts/ConnectivityManagerTest.java | 4 +- 3 files changed, 68 insertions(+), 6 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java index 8c18a899cf..a62ef8adf4 100755 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java @@ -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 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 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); } diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java index 4d90a4a4d2..10a2821e4c 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java @@ -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"); + } } diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 3093243330..0e04a80772 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -2379,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); } @@ -2432,7 +2432,7 @@ public class ConnectivityManagerTest { final List allCallbacks = List.of(myUidCallback, otherUidCallback); for (DetailedBlockedStatusCallback callback : allCallbacks) { - callback.expectAvailableCallbacks(defaultNetwork); + callback.expectAvailableCallbacksWithBlockedReasonNone(defaultNetwork); } final Range myUidRange = new Range<>(myUid, myUid);