Merge "Fix TestNetworkTracker on Q" am: 9617402272

Original change: https://android-review.googlesource.com/c/platform/frameworks/libs/net/+/2116497

Change-Id: Ie177b6be9d31e79c3feab96476045b87d1277a8d
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/TestNetworkTracker.kt b/staticlibs/testutils/devicetests/com/android/testutils/TestNetworkTracker.kt
index bdea6c7..5ae2439 100644
--- a/staticlibs/testutils/devicetests/com/android/testutils/TestNetworkTracker.kt
+++ b/staticlibs/testutils/devicetests/com/android/testutils/TestNetworkTracker.kt
@@ -27,14 +27,18 @@
 import android.net.TestNetworkInterface
 import android.net.TestNetworkManager
 import android.os.Binder
+import android.os.Build
+import androidx.annotation.RequiresApi
+import com.android.modules.utils.build.SdkLevel.isAtLeastR
 import com.android.modules.utils.build.SdkLevel.isAtLeastS
 import java.util.concurrent.CompletableFuture
 import java.util.concurrent.TimeUnit
+import kotlin.test.assertTrue
 
 /**
  * Create a test network based on a TUN interface with a LinkAddress.
- * TODO: remove this function after fixing all the callers.
  *
+ * TODO: remove this function after fixing all the callers to use a list of LinkAddresses.
  * This method will block until the test network is available. Requires
  * [android.Manifest.permission.CHANGE_NETWORK_STATE] and
  * [android.Manifest.permission.MANAGE_TEST_NETWORKS].
@@ -44,9 +48,22 @@
     interfaceAddr: LinkAddress,
     setupTimeoutMs: Long = 10_000L
 ): TestNetworkTracker {
-    val lp = LinkProperties()
-    lp.addLinkAddress(interfaceAddr)
-    return initTestNetwork(context, lp, setupTimeoutMs)
+    return initTestNetwork(context, listOf(interfaceAddr), setupTimeoutMs)
+}
+
+/**
+ * Create a test network based on a TUN interface with a LinkAddress list.
+ *
+ * This method will block until the test network is available. Requires
+ * [android.Manifest.permission.CHANGE_NETWORK_STATE] and
+ * [android.Manifest.permission.MANAGE_TEST_NETWORKS].
+ */
+fun initTestNetwork(
+    context: Context,
+    linkAddrs: List<LinkAddress>,
+    setupTimeoutMs: Long = 10_000L
+): TestNetworkTracker {
+    return initTestNetwork(context, linkAddrs, lp = null, setupTimeoutMs = setupTimeoutMs)
 }
 
 /**
@@ -55,17 +72,32 @@
  * This method will block until the test network is available. Requires
  * [android.Manifest.permission.CHANGE_NETWORK_STATE] and
  * [android.Manifest.permission.MANAGE_TEST_NETWORKS].
+ *
+ * This is only usable starting from R as [TestNetworkManager] has no support for specifying
+ * LinkProperties on Q.
  */
+@RequiresApi(Build.VERSION_CODES.R)
 fun initTestNetwork(
     context: Context,
     lp: LinkProperties,
     setupTimeoutMs: Long = 10_000L
 ): TestNetworkTracker {
+    return initTestNetwork(context, lp.linkAddresses, lp, setupTimeoutMs)
+}
+
+private fun initTestNetwork(
+    context: Context,
+    linkAddrs: List<LinkAddress>,
+    lp: LinkProperties?,
+    setupTimeoutMs: Long = 10_000L
+): TestNetworkTracker {
     val tnm = context.getSystemService(TestNetworkManager::class.java)
-    val iface = if (isAtLeastS()) tnm.createTunInterface(lp.getLinkAddresses())
-            else tnm.createTunInterface(lp.getLinkAddresses().toTypedArray())
-    lp.setInterfaceName(iface.interfaceName)
-    return TestNetworkTracker(context, iface, tnm, lp, setupTimeoutMs)
+    val iface = if (isAtLeastS()) tnm.createTunInterface(linkAddrs)
+    else tnm.createTunInterface(linkAddrs.toTypedArray())
+    val lpWithIface = if (lp == null) null else LinkProperties(lp).apply {
+        interfaceName = iface.interfaceName
+    }
+    return TestNetworkTracker(context, iface, tnm, lpWithIface, setupTimeoutMs)
 }
 
 /**
@@ -77,7 +109,7 @@
     val context: Context,
     val iface: TestNetworkInterface,
     val tnm: TestNetworkManager,
-    val lp: LinkProperties,
+    val lp: LinkProperties?,
     setupTimeoutMs: Long
 ) {
     private val cm = context.getSystemService(ConnectivityManager::class.java)
@@ -103,11 +135,16 @@
         }
         cm.requestNetwork(networkRequest, networkCallback)
 
-        try {
-            tnm.setupTestNetwork(lp, true /* isMetered */, binder)
-            network = networkFuture.get(setupTimeoutMs, TimeUnit.MILLISECONDS)
+        network = try {
+            if (lp != null) {
+                assertTrue(isAtLeastR(), "Cannot specify TestNetwork LinkProperties before R")
+                tnm.setupTestNetwork(lp, true /* isMetered */, binder)
+            } else {
+                tnm.setupTestNetwork(iface.interfaceName, binder)
+            }
+            networkFuture.get(setupTimeoutMs, TimeUnit.MILLISECONDS)
         } catch (e: Throwable) {
-            teardown()
+            cm.unregisterNetworkCallback(networkCallback)
             throw e
         }