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
This commit is contained in:
paulhu
2021-06-18 09:50:21 +00:00
parent a244f13f21
commit 342ee18b57

View File

@@ -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<Boolean> 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<Integer> 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<Integer> 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);
}
}
}