CTS test for eth manager allowed UIDs

CTS tests for using the EthernetManager#updateConfiguration API to
set NetworkCapabilities.Builder#setAllowedUids functionality.

Bug: 210487893
Test: atest CtsNetTestCases
:android.net.cts.EthernetManagerTest --iterations

Change-Id: Iefb2e49bd6c05c9cf9ae678bd94b39b051664584
diff --git a/tests/cts/net/src/android/net/cts/EthernetManagerTest.kt b/tests/cts/net/src/android/net/cts/EthernetManagerTest.kt
index d3839d9..74e57c9 100644
--- a/tests/cts/net/src/android/net/cts/EthernetManagerTest.kt
+++ b/tests/cts/net/src/android/net/cts/EthernetManagerTest.kt
@@ -41,6 +41,7 @@
 import android.net.MacAddress
 import android.net.Network
 import android.net.NetworkCapabilities
+import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED
 import android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED
 import android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED
 import android.net.NetworkCapabilities.TRANSPORT_ETHERNET
@@ -56,6 +57,7 @@
 import android.os.Looper
 import android.os.OutcomeReceiver
 import android.os.SystemProperties
+import android.os.Process
 import android.platform.test.annotations.AppModeFull
 import android.util.ArraySet
 import androidx.test.platform.app.InstrumentationRegistry
@@ -72,6 +74,7 @@
 import com.android.testutils.TapPacketReader
 import com.android.testutils.TestableNetworkCallback
 import com.android.testutils.anyNetwork
+import com.android.testutils.assertThrows
 import com.android.testutils.runAsShell
 import com.android.testutils.waitForIdle
 import org.junit.After
@@ -80,8 +83,10 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import java.io.IOException
 import java.net.Inet6Address
 import java.util.Random
+import java.net.Socket
 import java.util.concurrent.CompletableFuture
 import java.util.concurrent.ExecutionException
 import java.util.concurrent.TimeUnit
@@ -919,4 +924,37 @@
         cb.expectAvailable()
         cb.expectCapabilitiesWith(testCapability)
     }
+
+    @Test
+    fun testUpdateConfiguration_forAllowedUids() {
+        // Configure a restricted network.
+        val iface = createInterface()
+        val request = NetworkRequest.Builder(ETH_REQUEST.copyWithEthernetSpecifier(iface.name))
+                .removeCapability(NET_CAPABILITY_NOT_RESTRICTED).build()
+        updateConfiguration(iface, capabilities = request.networkCapabilities)
+                .expectResult(iface.name)
+
+        // Request the restricted network as the shell with CONNECTIVITY_USE_RESTRICTED_NETWORKS.
+        val cb = runAsShell(CONNECTIVITY_USE_RESTRICTED_NETWORKS) { requestNetwork(request) }
+        val network = cb.expectAvailable()
+        cb.assertNeverLost(network)
+
+        // The network is restricted therefore binding to it when available will fail.
+        Socket().use { socket ->
+            assertThrows(IOException::class.java, { network.bindSocket(socket) })
+        }
+
+        // Add the test process UID to the allowed UIDs for the network and ultimately bind again.
+        val allowedUids = setOf(Process.myUid())
+        val nc = NetworkCapabilities.Builder(request.networkCapabilities)
+                .setAllowedUids(allowedUids).build()
+        updateConfiguration(iface, capabilities = nc).expectResult(iface.name)
+
+        // UpdateConfiguration() currently does a restart on the ethernet interface therefore lost
+        // will be expected first before available, as part of the restart.
+        cb.expectLost(network)
+        val updatedNetwork = cb.expectAvailable()
+        // With the test process UID allowed, binding to a restricted network should be successful.
+        Socket().use { socket -> updatedNetwork.bindSocket(socket) }
+    }
 }