Wrap use of test interface in EthernetTestInterface

NsdManagerDownstreamTetheringTest closed the test interface without
waiting on the STATE_ABSENT callback from ethernet service. This meant
that during setUp, an ethernet test interface might
still have been present from the previous test causing the test to be
flaky.

Note that flakiness was not uncovered until a recent change in
EthernetTetheringTestBase, which skips tests when a built-in ethernet
interface is present. This check used to throw an assumption failure if
any interface for tethering was already available, but was recently
changed to only throw the assumption failure if said interface is not
named testtap%d. So this test has always been broken, it just was not
obvious because the flakes would result in the test getting skipped.

Test: atest NsdManagerDownstreamTetheringTest --iterations 20
Bug: 348064142
Change-Id: I15f2aeacdf621a4413bda032331abb64c75d86a7
diff --git a/tests/cts/net/src/android/net/cts/NsdManagerDownstreamTetheringTest.kt b/tests/cts/net/src/android/net/cts/NsdManagerDownstreamTetheringTest.kt
index f45f881..4dd56d0 100644
--- a/tests/cts/net/src/android/net/cts/NsdManagerDownstreamTetheringTest.kt
+++ b/tests/cts/net/src/android/net/cts/NsdManagerDownstreamTetheringTest.kt
@@ -17,12 +17,14 @@
 
 import android.net.EthernetTetheringTestBase
 import android.net.LinkAddress
-import android.net.TestNetworkInterface
 import android.net.TetheringManager.CONNECTIVITY_SCOPE_LOCAL
 import android.net.TetheringManager.TETHERING_ETHERNET
 import android.net.TetheringManager.TetheringRequest
+import android.net.cts.util.EthernetTestInterface
 import android.net.nsd.NsdManager
 import android.os.Build
+import android.os.Handler
+import android.os.HandlerThread
 import android.platform.test.annotations.AppModeFull
 import androidx.test.filters.SmallTest
 import com.android.testutils.ConnectivityModuleTest
@@ -41,6 +43,8 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
+private const val TAG = "NsdManagerDownstreamTetheringTest"
+
 @RunWith(DevSdkIgnoreRunner::class)
 @SmallTest
 @ConnectivityModuleTest
@@ -50,14 +54,24 @@
     private val nsdManager by lazy { context.getSystemService(NsdManager::class.java)!! }
     private val serviceType = "_nmt%09d._tcp".format(Random().nextInt(1_000_000_000))
 
+    private val handlerThread = HandlerThread("$TAG thread").apply { start() }
+    private val handler = Handler(handlerThread.looper)
+    private lateinit var downstreamIface: EthernetTestInterface
+
     @Before
     override fun setUp() {
         super.setUp()
-        setIncludeTestInterfaces(true)
+        val iface = createTestInterface()
+        downstreamIface = EthernetTestInterface(context, handler, iface)
     }
 
     @After
     override fun tearDown() {
+        if (::downstreamIface.isInitialized) {
+            downstreamIface.destroy()
+        }
+        handlerThread.quitSafely()
+        handlerThread.join()
         super.tearDown()
     }
 
@@ -65,16 +79,14 @@
     fun testMdnsDiscoveryCanSendPacketOnLocalOnlyDownstreamTetheringInterface() {
         assumeFalse(isInterfaceForTetheringAvailable())
 
-        var downstreamIface: TestNetworkInterface? = null
         var tetheringEventCallback: MyTetheringEventCallback? = null
         var downstreamReader: TapPacketReader? = null
 
         val discoveryRecord = NsdDiscoveryRecord()
 
         tryTest {
-            downstreamIface = createTestInterface()
             val iface = mTetheredInterfaceRequester.getInterface()
-            assertEquals(iface, downstreamIface?.interfaceName)
+            assertEquals(downstreamIface.name, iface)
             val request = TetheringRequest.Builder(TETHERING_ETHERNET)
                 .setConnectivityScope(CONNECTIVITY_SCOPE_LOCAL).build()
             tetheringEventCallback = enableEthernetTethering(
@@ -85,7 +97,7 @@
             }
             // This shouldn't be flaky because the TAP interface will buffer all packets even
             // before the reader is started.
-            downstreamReader = makePacketReader(downstreamIface)
+            downstreamReader = makePacketReader(downstreamIface.testIface)
             waitForRouterAdvertisement(downstreamReader, iface, WAIT_RA_TIMEOUT_MS)
 
             nsdManager.discoverServices(serviceType, NsdManager.PROTOCOL_DNS_SD, discoveryRecord)
@@ -96,8 +108,6 @@
             discoveryRecord.expectCallback<NsdDiscoveryRecord.DiscoveryEvent.DiscoveryStopped>()
         } cleanupStep {
             maybeStopTapPacketReader(downstreamReader)
-        } cleanupStep {
-            maybeCloseTestInterface(downstreamIface)
         } cleanup {
             maybeUnregisterTetheringEventCallback(tetheringEventCallback)
         }
@@ -107,16 +117,14 @@
     fun testMdnsDiscoveryWorkOnTetheringInterface() {
         assumeFalse(isInterfaceForTetheringAvailable())
 
-        var downstreamIface: TestNetworkInterface? = null
         var tetheringEventCallback: MyTetheringEventCallback? = null
         var downstreamReader: TapPacketReader? = null
 
         val discoveryRecord = NsdDiscoveryRecord()
 
         tryTest {
-            downstreamIface = createTestInterface()
             val iface = mTetheredInterfaceRequester.getInterface()
-            assertEquals(iface, downstreamIface?.interfaceName)
+            assertEquals(downstreamIface.name, iface)
 
             val localAddr = LinkAddress("192.0.2.3/28")
             val clientAddr = LinkAddress("192.0.2.2/28")
@@ -130,9 +138,9 @@
                 awaitInterfaceTethered()
             }
 
-            val fd = downstreamIface?.fileDescriptor?.fileDescriptor
+            val fd = downstreamIface.testIface.fileDescriptor?.fileDescriptor
             assertNotNull(fd)
-            downstreamReader = makePacketReader(fd, getMTU(downstreamIface))
+            downstreamReader = makePacketReader(fd, getMTU(downstreamIface.testIface))
 
             nsdManager.discoverServices(serviceType, NsdManager.PROTOCOL_DNS_SD, discoveryRecord)
             discoveryRecord.expectCallback<NsdDiscoveryRecord.DiscoveryEvent.DiscoveryStarted>()
@@ -143,8 +151,6 @@
             discoveryRecord.expectCallback<NsdDiscoveryRecord.DiscoveryEvent.DiscoveryStopped>()
         } cleanupStep {
             maybeStopTapPacketReader(downstreamReader)
-        } cleanupStep {
-            maybeCloseTestInterface(downstreamIface)
         } cleanup {
             maybeUnregisterTetheringEventCallback(tetheringEventCallback)
         }