From 342ee18b5770ff1f40d6929f303b246e98a76b47 Mon Sep 17 00:00:00 2001 From: paulhu Date: Fri, 18 Jun 2021 09:50:21 +0000 Subject: [PATCH] Add test for CSM#[get|set]UidsAllowedOnRestrictedNetworks Bug: 185149952 Test: atest ConnectivityManagerTest Original-Change: https://android-review.googlesource.com/1740740 Merged-In: Ie9391d9332ded58cf1e63c8c5c6f5ba85c950bc6 Change-Id: Ie9391d9332ded58cf1e63c8c5c6f5ba85c950bc6 --- .../net/cts/ConnectivityManagerTest.java | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 06a4004134..4c967b8c30 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -115,11 +115,15 @@ import android.net.IpSecManager.UdpEncapsulationSocket; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.Network; +import android.net.NetworkAgent; +import android.net.NetworkAgentConfig; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; +import android.net.NetworkProvider; import android.net.NetworkRequest; +import android.net.NetworkScore; import android.net.NetworkSpecifier; import android.net.NetworkStateSnapshot; import android.net.NetworkUtils; @@ -207,6 +211,8 @@ import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -245,6 +251,9 @@ public class ConnectivityManagerTest { // Airplane Mode BroadcastReceiver Timeout private static final long AIRPLANE_MODE_CHANGE_TIMEOUT_MS = 10_000L; + // Timeout for applying uids allowed on restricted networks + private static final long APPLYING_UIDS_ALLOWED_ON_RESTRICTED_NETWORKS_TIMEOUT_MS = 3_000L; + // Minimum supported keepalive counts for wifi and cellular. public static final int MIN_SUPPORTED_CELLULAR_KEEPALIVE_COUNT = 1; public static final int MIN_SUPPORTED_WIFI_KEEPALIVE_COUNT = 3; @@ -2847,4 +2856,110 @@ public class ConnectivityManagerTest { mContext, mobileDataPreferredUids); } } + + /** Wait for assigned time. */ + private void waitForMs(long ms) { + try { + Thread.sleep(ms); + } catch (InterruptedException e) { + fail("Thread was interrupted"); + } + } + + private void assertBindSocketToNetworkSuccess(final Network network) throws Exception { + final CompletableFuture future = new CompletableFuture<>(); + final ExecutorService executor = Executors.newSingleThreadExecutor(); + try { + executor.execute(() -> { + for (int i = 0; i < 30; i++) { + waitForMs(100); + + try (Socket socket = new Socket()) { + network.bindSocket(socket); + future.complete(true); + return; + } catch (IOException e) { } + } + }); + assertTrue(future.get(APPLYING_UIDS_ALLOWED_ON_RESTRICTED_NETWORKS_TIMEOUT_MS, + TimeUnit.MILLISECONDS)); + } finally { + executor.shutdown(); + } + } + + @AppModeFull(reason = "WRITE_SECURE_SETTINGS permission can't be granted to instant apps") + @Test + public void testUidsAllowedOnRestrictedNetworks() throws Exception { + assumeTrue(TestUtils.shouldTestSApis()); + + final int uid = mPackageManager.getPackageUid(mContext.getPackageName(), 0 /* flag */); + final Set originalUidsAllowedOnRestrictedNetworks = + ConnectivitySettingsManager.getUidsAllowedOnRestrictedNetworks(mContext); + // CtsNetTestCases uid should not list in UIDS_ALLOWED_ON_RESTRICTED_NETWORKS setting + // because it has been just installed to device. In case the uid is existed in setting + // mistakenly, try to remove the uid and set correct uids to setting. + originalUidsAllowedOnRestrictedNetworks.remove(uid); + ConnectivitySettingsManager.setUidsAllowedOnRestrictedNetworks(mContext, + originalUidsAllowedOnRestrictedNetworks); + + final Handler h = new Handler(Looper.getMainLooper()); + final TestableNetworkCallback testNetworkCb = new TestableNetworkCallback(); + mCm.registerBestMatchingNetworkCallback(new NetworkRequest.Builder().clearCapabilities() + .addTransportType(NetworkCapabilities.TRANSPORT_TEST).build(), testNetworkCb, h); + + // Create test network agent with restricted network. + final NetworkCapabilities nc = new NetworkCapabilities.Builder() + .addTransportType(NetworkCapabilities.TRANSPORT_TEST) + .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED) + .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING) + .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED) + .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED) + .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) + .build(); + final NetworkScore score = new NetworkScore.Builder() + .setExiting(false) + .setTransportPrimary(false) + .setKeepConnectedReason(NetworkScore.KEEP_CONNECTED_FOR_HANDOVER) + .build(); + final NetworkAgent agent = new NetworkAgent(mContext, Looper.getMainLooper(), + TAG, nc, new LinkProperties(), score, new NetworkAgentConfig.Builder().build(), + new NetworkProvider(mContext, Looper.getMainLooper(), TAG)) {}; + runWithShellPermissionIdentity(() -> agent.register(), + android.Manifest.permission.MANAGE_TEST_NETWORKS); + agent.markConnected(); + + final Network network = agent.getNetwork(); + + try (Socket socket = new Socket()) { + testNetworkCb.eventuallyExpect(CallbackEntry.AVAILABLE, NETWORK_CALLBACK_TIMEOUT_MS, + entry -> network.equals(entry.getNetwork())); + // Verify that the network is restricted. + final NetworkCapabilities testNetworkNc = mCm.getNetworkCapabilities(network); + assertNotNull(testNetworkNc); + assertFalse(testNetworkNc.hasCapability( + NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)); + // CtsNetTestCases package doesn't hold CONNECTIVITY_USE_RESTRICTED_NETWORKS, so it + // does not allow to bind socket to restricted network. + assertThrows(IOException.class, () -> network.bindSocket(socket)); + + // Add CtsNetTestCases uid to UIDS_ALLOWED_ON_RESTRICTED_NETWORKS setting, then it can + // bind socket to restricted network normally. + final Set newUidsAllowedOnRestrictedNetworks = + new ArraySet<>(originalUidsAllowedOnRestrictedNetworks); + newUidsAllowedOnRestrictedNetworks.add(uid); + ConnectivitySettingsManager.setUidsAllowedOnRestrictedNetworks(mContext, + newUidsAllowedOnRestrictedNetworks); + // Wait a while for sending allowed uids on the restricted network to netd. + // TODD: Have a significant signal to know the uids has been send to netd. + assertBindSocketToNetworkSuccess(network); + } finally { + mCm.unregisterNetworkCallback(testNetworkCb); + agent.unregister(); + + // Restore setting. + ConnectivitySettingsManager.setUidsAllowedOnRestrictedNetworks(mContext, + originalUidsAllowedOnRestrictedNetworks); + } + } }