[VCN06.1] Add CTS for request background network
Test: android.net.cts.ConnectivityManagerTest#testRequestBackgroundNetwork
Bug: 175662146
Change-Id: Icd7d2bc18c4b328291e96fc3f18828d0421f5b6e
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index cbf43e7..bd52bf9 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -25,10 +25,12 @@
import static android.content.pm.PackageManager.FEATURE_WIFI;
import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
+import static android.net.NetworkCapabilities.TRANSPORT_TEST;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.cts.util.CtsNetUtils.ConnectivityActionReceiver;
import static android.net.cts.util.CtsNetUtils.HTTP_PORT;
@@ -43,6 +45,7 @@
import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+import static com.android.testutils.MiscAsserts.assertThrows;
import static com.android.testutils.TestPermissionUtil.runAsShell;
import static org.junit.Assert.assertEquals;
@@ -68,8 +71,10 @@
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
+import android.net.InetAddresses;
import android.net.IpSecManager;
import android.net.IpSecManager.UdpEncapsulationSocket;
+import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
@@ -80,6 +85,9 @@
import android.net.NetworkRequest;
import android.net.NetworkUtils;
import android.net.SocketKeepalive;
+import android.net.StringNetworkSpecifier;
+import android.net.TestNetworkInterface;
+import android.net.TestNetworkManager;
import android.net.cts.util.CtsNetUtils;
import android.net.util.KeepaliveUtils;
import android.net.wifi.WifiManager;
@@ -104,10 +112,10 @@
import com.android.testutils.SkipPresubmit;
import com.android.testutils.TestableNetworkCallback;
-import libcore.io.Streams;
-
import junit.framework.AssertionFailedError;
+import libcore.io.Streams;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -176,6 +184,9 @@
private static final String KEEPALIVE_RESERVED_PER_SLOT_RES_NAME =
"config_reservedPrivilegedKeepaliveSlots";
+ private static final LinkAddress TEST_LINKADDR = new LinkAddress(
+ InetAddresses.parseNumericAddress("2001:db8::8"), 64);
+
private Context mContext;
private Instrumentation mInstrumentation;
private ConnectivityManager mCm;
@@ -1531,4 +1542,71 @@
throw new AssertionFailedError("Captive portal server URL is invalid: " + e);
}
}
+
+ /**
+ * Verify background request can only be requested when acquiring
+ * {@link android.Manifest.permission.NETWORK_SETTINGS}.
+ */
+ @Test
+ public void testRequestBackgroundNetwork() throws Exception {
+ // Create a tun interface. Use the returned interface name as the specifier to create
+ // a test network request.
+ final TestNetworkInterface testNetworkInterface = runWithShellPermissionIdentity(() -> {
+ final TestNetworkManager tnm =
+ mContext.getSystemService(TestNetworkManager.class);
+ return tnm.createTunInterface(new LinkAddress[]{TEST_LINKADDR});
+ }, android.Manifest.permission.MANAGE_TEST_NETWORKS,
+ android.Manifest.permission.NETWORK_SETTINGS);
+ assertNotNull(testNetworkInterface);
+
+ final NetworkRequest testRequest = new NetworkRequest.Builder()
+ .addTransportType(TRANSPORT_TEST)
+ // Test networks do not have NOT_VPN or TRUSTED capabilities by default
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
+ .setNetworkSpecifier(
+ new StringNetworkSpecifier(testNetworkInterface.getInterfaceName()))
+ .build();
+
+ // Verify background network cannot be requested without NETWORK_SETTINGS permission.
+ final TestableNetworkCallback callback = new TestableNetworkCallback();
+ assertThrows(SecurityException.class,
+ () -> mCm.requestBackgroundNetwork(testRequest, null, callback));
+
+ try {
+ // Request background test network via Shell identity which has NETWORK_SETTINGS
+ // permission granted.
+ runWithShellPermissionIdentity(
+ () -> mCm.requestBackgroundNetwork(testRequest, null, callback),
+ android.Manifest.permission.NETWORK_SETTINGS);
+
+ // Register the test network agent which has no foreground request associated to it.
+ // And verify it can satisfy the background network request just fired.
+ final Binder binder = new Binder();
+ runWithShellPermissionIdentity(() -> {
+ final TestNetworkManager tnm =
+ mContext.getSystemService(TestNetworkManager.class);
+ tnm.setupTestNetwork(testNetworkInterface.getInterfaceName(), binder);
+ }, android.Manifest.permission.MANAGE_TEST_NETWORKS,
+ android.Manifest.permission.NETWORK_SETTINGS);
+ waitForAvailable(callback);
+ final Network testNetwork = callback.getLastAvailableNetwork();
+ assertNotNull(testNetwork);
+
+ // The test network that has just connected is a foreground network,
+ // non-listen requests will get available callback before it can be put into
+ // background if no foreground request can be satisfied. Thus, wait for a short
+ // period is needed to let foreground capability go away.
+ callback.eventuallyExpect(CallbackEntry.NETWORK_CAPS_UPDATED,
+ callback.getDefaultTimeoutMs(),
+ c -> c instanceof CallbackEntry.CapabilitiesChanged
+ && !((CallbackEntry.CapabilitiesChanged) c).getCaps()
+ .hasCapability(NET_CAPABILITY_FOREGROUND));
+ final NetworkCapabilities nc = mCm.getNetworkCapabilities(testNetwork);
+ assertFalse("expected background network, but got " + nc,
+ nc.hasCapability(NET_CAPABILITY_FOREGROUND));
+ } finally {
+ mCm.unregisterNetworkCallback(callback);
+ }
+ }
}