diff --git a/staticlibs/testutils/Android.bp b/staticlibs/testutils/Android.bp
new file mode 100644
index 0000000..5fe7ac3
--- /dev/null
+++ b/staticlibs/testutils/Android.bp
@@ -0,0 +1,88 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_library {
+    name: "net-tests-utils",
+    srcs: [
+        "devicetests/**/*.java",
+        "devicetests/**/*.kt",
+    ],
+    defaults: [
+        "framework-connectivity-test-defaults",
+        "lib_mockito_extended"
+    ],
+    libs: [
+        "androidx.annotation_annotation",
+        "net-utils-device-common-bpf",  // TestBpfMap extends IBpfMap.
+    ],
+    static_libs: [
+        "androidx.test.ext.junit",
+        "kotlin-reflect",
+        "libnanohttpd",
+        "net-tests-utils-host-device-common",
+        "net-utils-device-common",
+        "net-utils-device-common-async",
+        "net-utils-device-common-netlink",
+        "net-utils-device-common-wear",
+        "modules-utils-build_system",
+    ],
+    lint: { strict_updatability_linting: true },
+}
+
+java_library {
+    // Consider using net-tests-utils instead if writing device code.
+    // That library has a lot more useful tools into it for users that
+    // work on Android and includes this lib.
+    name: "net-tests-utils-host-device-common",
+    srcs: [
+        "hostdevice/**/*.java",
+        "hostdevice/**/*.kt",
+    ],
+    host_supported: true,
+    visibility: [
+        "//packages/modules/Connectivity/staticlibs/tests:__subpackages__",
+        "//packages/modules/Connectivity/staticlibs/client-libs/tests:__subpackages__",
+        "//packages/modules/Connectivity/tests/cts/hostside",
+    ],
+    // There are downstream branches using an old version of Kotlin
+    // that used to reserve the right to make breaking changes to the
+    // Result type and disallowed returning an instance of it.
+    // Later versions allowed this and there was never a change,
+    // so no matter the version returning Result is always fine,
+    // but on sc-mainline-prod the compiler rejects it without
+    // the following flag.
+    kotlincflags: ["-Xallow-result-return-type"],
+    libs: [
+        "jsr305",
+    ],
+    static_libs: [
+        "kotlin-test"
+    ],
+    lint: { strict_updatability_linting: true },
+}
+
+java_test_host {
+    name: "net-tests-utils-host-common",
+    srcs: [
+        "host/**/*.java",
+        "host/**/*.kt",
+    ],
+    libs: ["tradefed"],
+    test_suites: ["ats", "device-tests", "general-tests", "cts", "mts-networking"],
+    data: [":ConnectivityTestPreparer"],
+}
diff --git a/staticlibs/testutils/app/connectivitychecker/Android.bp b/staticlibs/testutils/app/connectivitychecker/Android.bp
new file mode 100644
index 0000000..f7118cf
--- /dev/null
+++ b/staticlibs/testutils/app/connectivitychecker/Android.bp
@@ -0,0 +1,34 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+    name: "ConnectivityTestPreparer",
+    srcs: ["src/**/*.kt"],
+    sdk_version: "system_current",
+    // Allow running the test on any device with SDK Q+, even when built from a branch that uses
+    // an unstable SDK, by targeting a stable SDK regardless of the build SDK.
+    min_sdk_version: "29",
+    target_sdk_version: "30",
+    static_libs: [
+        "androidx.test.rules",
+        "modules-utils-build_system",
+        "net-tests-utils",
+    ],
+    host_required: ["net-tests-utils-host-common"],
+    lint: { strict_updatability_linting: true },
+}
diff --git a/staticlibs/testutils/app/connectivitychecker/AndroidManifest.xml b/staticlibs/testutils/app/connectivitychecker/AndroidManifest.xml
new file mode 100644
index 0000000..015b41f
--- /dev/null
+++ b/staticlibs/testutils/app/connectivitychecker/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.testutils.connectivitypreparer">
+
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <!-- For wifi scans -->
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.testutils.connectivitypreparer"
+                     android:label="Connectivity test target preparer" />
+</manifest>
diff --git a/staticlibs/testutils/app/connectivitychecker/src/com/android/testutils/connectivitypreparer/ConnectivityCheckTest.kt b/staticlibs/testutils/app/connectivitychecker/src/com/android/testutils/connectivitypreparer/ConnectivityCheckTest.kt
new file mode 100644
index 0000000..f1f0975
--- /dev/null
+++ b/staticlibs/testutils/app/connectivitychecker/src/com/android/testutils/connectivitypreparer/ConnectivityCheckTest.kt
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils.connectivitypreparer
+
+import android.content.pm.PackageManager.FEATURE_TELEPHONY
+import android.content.pm.PackageManager.FEATURE_WIFI
+import android.net.ConnectivityManager
+import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
+import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
+import android.net.NetworkRequest
+import android.telephony.TelephonyManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.testutils.ConnectUtil
+import com.android.testutils.RecorderCallback
+import com.android.testutils.TestableNetworkCallback
+import com.android.testutils.tryTest
+import kotlin.test.assertTrue
+import kotlin.test.fail
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class ConnectivityCheckTest {
+    val context by lazy { InstrumentationRegistry.getInstrumentation().context }
+    val pm by lazy { context.packageManager }
+
+    @Test
+    fun testCheckConnectivity() {
+        checkWifiSetup()
+        checkTelephonySetup()
+    }
+
+    private fun checkWifiSetup() {
+        if (!pm.hasSystemFeature(FEATURE_WIFI)) return
+        ConnectUtil(context).ensureWifiConnected()
+    }
+
+    private fun checkTelephonySetup() {
+        if (!pm.hasSystemFeature(FEATURE_TELEPHONY)) return
+        val tm = context.getSystemService(TelephonyManager::class.java)
+                ?: fail("Could not get telephony service")
+
+        val commonError = "Check the test bench. To run the tests anyway for quick & dirty local " +
+                "testing, you can use atest X -- " +
+                "--test-arg com.android.testutils.ConnectivityTestTargetPreparer" +
+                ":ignore-connectivity-check:true"
+        // Do not use assertEquals: it outputs "expected X, was Y", which looks like a test failure
+        if (tm.simState == TelephonyManager.SIM_STATE_ABSENT) {
+            fail("The device has no SIM card inserted. $commonError")
+        } else if (tm.simState != TelephonyManager.SIM_STATE_READY) {
+            fail("The device is not setup with a usable SIM card. Sim state was ${tm.simState}. " +
+                    commonError)
+        }
+        assertTrue(tm.isDataConnectivityPossible,
+            "The device is not setup with a SIM card that supports data connectivity. " +
+                    commonError)
+        val cb = TestableNetworkCallback()
+        val cm = context.getSystemService(ConnectivityManager::class.java)
+                ?: fail("Could not get ConnectivityManager")
+        cm.requestNetwork(
+                NetworkRequest.Builder()
+                        .addTransportType(TRANSPORT_CELLULAR)
+                        .addCapability(NET_CAPABILITY_INTERNET).build(), cb)
+        tryTest {
+            cb.poll { it is RecorderCallback.CallbackEntry.Available }
+                    ?: fail("The device does not have mobile data available. Check that it is " +
+                            "setup with a SIM card that has a working data plan, and that the " +
+                            "APN configuration is valid.")
+        } cleanup {
+            cm.unregisterNetworkCallback(cb)
+        }
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/ArpResponder.kt b/staticlibs/testutils/devicetests/com/android/testutils/ArpResponder.kt
new file mode 100644
index 0000000..cf0490c
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/ArpResponder.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import android.net.MacAddress
+import com.android.net.module.util.NetworkStackConstants.ETHER_HEADER_LEN
+import java.net.Inet4Address
+import java.net.InetAddress
+import java.nio.ByteBuffer
+
+private const val ARP_SENDER_MAC_OFFSET = ETHER_HEADER_LEN + 8
+private const val ARP_TARGET_IPADDR_OFFSET = ETHER_HEADER_LEN + 24
+
+private val TYPE_ARP = byteArrayOf(0x08, 0x06)
+// Arp reply header for IPv4 over ethernet
+private val ARP_REPLY_IPV4 = byteArrayOf(0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x02)
+
+/**
+ * A class that can be used to reply to ARP packets on a [TapPacketReader].
+ */
+class ArpResponder(
+    reader: TapPacketReader,
+    table: Map<Inet4Address, MacAddress>,
+    name: String = ArpResponder::class.java.simpleName
+) : PacketResponder(reader, ArpRequestFilter(), name) {
+    // Copy the map if not already immutable (toMap) to make sure it is not modified
+    private val table = table.toMap()
+
+    override fun replyToPacket(packet: ByteArray, reader: TapPacketReader) {
+        val targetIp = InetAddress.getByAddress(
+                packet.copyFromIndexWithLength(ARP_TARGET_IPADDR_OFFSET, 4))
+                as Inet4Address
+
+        val macAddr = table[targetIp]?.toByteArray() ?: return
+        val senderMac = packet.copyFromIndexWithLength(ARP_SENDER_MAC_OFFSET, 6)
+        reader.sendResponse(ByteBuffer.wrap(
+                // Ethernet header
+                senderMac + macAddr + TYPE_ARP +
+                        // ARP message
+                        ARP_REPLY_IPV4 +
+                        macAddr /* sender MAC */ +
+                        targetIp.address /* sender IP addr */ +
+                        macAddr /* target mac */ +
+                        targetIp.address /* target IP addr */
+        ))
+    }
+}
+
+private fun ByteArray.copyFromIndexWithLength(start: Int, len: Int) =
+        copyOfRange(start, start + len)
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/CompatUtil.kt b/staticlibs/testutils/devicetests/com/android/testutils/CompatUtil.kt
new file mode 100644
index 0000000..82f1d9b
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/CompatUtil.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import android.net.NetworkSpecifier
+import com.android.modules.utils.build.SdkLevel.isAtLeastS
+
+/**
+ * Test utility to create [NetworkSpecifier]s on different SDK versions.
+ */
+object CompatUtil {
+    @JvmStatic
+    fun makeTestNetworkSpecifier(ifName: String): NetworkSpecifier {
+        // Until R, there was no TestNetworkSpecifier, StringNetworkSpecifier was used instead
+        if (!isAtLeastS()) {
+            return makeNetworkSpecifierInternal("android.net.StringNetworkSpecifier", ifName)
+        }
+        // TestNetworkSpecifier is not part of the SDK in some branches using this utility
+        // TODO: replace with a direct call to the constructor
+        return makeNetworkSpecifierInternal("android.net.TestNetworkSpecifier", ifName)
+    }
+
+    @JvmStatic
+    fun makeEthernetNetworkSpecifier(ifName: String): NetworkSpecifier {
+        // Until R, there was no EthernetNetworkSpecifier, StringNetworkSpecifier was used instead
+        if (!isAtLeastS()) {
+            return makeNetworkSpecifierInternal("android.net.StringNetworkSpecifier", ifName)
+        }
+        // EthernetNetworkSpecifier is not part of the SDK in some branches using this utility
+        // TODO: replace with a direct call to the constructor
+        return makeNetworkSpecifierInternal("android.net.EthernetNetworkSpecifier", ifName)
+    }
+
+    private fun makeNetworkSpecifierInternal(clazz: String, specifier: String): NetworkSpecifier {
+        // StringNetworkSpecifier was removed after R (and was hidden API before that)
+        return Class.forName(clazz)
+                .getConstructor(String::class.java).newInstance(specifier) as NetworkSpecifier
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/ConcurrentInterpreter.kt b/staticlibs/testutils/devicetests/com/android/testutils/ConcurrentInterpreter.kt
new file mode 100644
index 0000000..9e72f4b
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/ConcurrentInterpreter.kt
@@ -0,0 +1,240 @@
+package com.android.testutils
+
+import android.os.SystemClock
+import java.util.concurrent.CyclicBarrier
+import kotlin.test.assertEquals
+import kotlin.test.assertFails
+import kotlin.test.assertNull
+import kotlin.test.assertTrue
+
+// The table contains pairs associating a regexp with the code to run. The statement is matched
+// against each matcher in sequence and when a match is found the associated code is run, passing
+// it the TrackRecord under test and the result of the regexp match.
+typealias InterpretMatcher<T> = Pair<Regex, (ConcurrentInterpreter<T>, T, MatchResult) -> Any?>
+
+// The default unit of time for interpreted tests
+const val INTERPRET_TIME_UNIT = 60L // ms
+
+/**
+ * A small interpreter for testing parallel code.
+ *
+ * The interpreter will read a list of lines consisting of "|"-separated statements, e.g. :
+ *   sleep 2 ; unblock thread2 | wait thread2 time 2..5
+ *   sendMessage "x"           | obtainMessage = "x" time 0..1
+ *
+ * Each column runs in a different concurrent thread and all threads wait for each other in
+ * between lines. Each statement is split on ";" then matched with regular expressions in the
+ * instructionTable constant, which contains the code associated with each statement. The
+ * interpreter supports an object being passed to the interpretTestSpec() method to be passed
+ * in each lambda (think about the object under test), and an optional transform function to be
+ * executed on the object at the start of every thread.
+ *
+ * The time unit is defined in milliseconds by the interpretTimeUnit member, which has a default
+ * value but can be passed to the constructor. Whitespace is ignored.
+ *
+ * The interpretation table has to be passed as an argument. It's a table associating a regexp
+ * with the code that should execute, as a function taking three arguments : the interpreter,
+ * the regexp match, and the object. See the individual tests for the DSL of that test.
+ * Implementors for new interpreting languages are encouraged to look at the defaultInterpretTable
+ * constant below for an example of how to write an interpreting table.
+ * Some expressions already exist by default and can be used by all interpreters. Refer to
+ * getDefaultInstructions() below for a list and documentation.
+ */
+open class ConcurrentInterpreter<T>(localInterpretTable: List<InterpretMatcher<T>>) {
+    private val interpretTable: List<InterpretMatcher<T>> =
+            localInterpretTable + getDefaultInstructions()
+    // The last time the thread became blocked, with base System.currentTimeMillis(). This should
+    // be set immediately before any time the thread gets blocked.
+    internal val lastBlockedTime = ThreadLocal<Long>()
+
+    // Split the line into multiple statements separated by ";" and execute them. Return whatever
+    // the last statement returned.
+    fun interpretMultiple(instr: String, r: T): Any? {
+        return instr.split(";").map { interpret(it.trim(), r) }.last()
+    }
+
+    // Match the statement to a regex and interpret it.
+    fun interpret(instr: String, r: T): Any? {
+        val (matcher, code) =
+                interpretTable.find { instr matches it.first } ?: throw SyntaxException(instr)
+        val match = matcher.matchEntire(instr) ?: throw SyntaxException(instr)
+        return code(this, r, match)
+    }
+
+    /**
+     * Spins as many threads as needed by the test spec and interpret each program concurrently.
+     *
+     * All threads wait on a CyclicBarrier after each line.
+     * |lineShift| says how many lines after the call the spec starts. This is used for error
+     * reporting. Unfortunately AFAICT there is no way to get the line of an argument rather
+     * than the line at which the expression starts.
+     *
+     * This method is mostly meant for implementations that extend the ConcurrentInterpreter
+     * class to add their own directives and instructions. These may need to operate on some
+     * data, which can be passed in |initial|. For example, an interpreter specialized in callbacks
+     * may want to pass the callback there. In some cases, it's necessary that each thread
+     * performs a transformation *after* it starts on that value before starting ; in this case,
+     * the transformation can be passed to |threadTransform|. The default is to return |initial| as
+     * is. Look at some existing child classes of this interpreter for some examples of how this
+     * can be used.
+     *
+     * @param spec The test spec, as a string of lines separated by pipes.
+     * @param initial An initial value passed to all threads.
+     * @param lineShift How many lines after the call the spec starts, for error reporting.
+     * @param threadTransform an optional transformation that each thread will apply to |initial|
+     */
+    fun interpretTestSpec(
+        spec: String,
+        initial: T,
+        lineShift: Int = 0,
+        threadTransform: (T) -> T = { it }
+    ) {
+        // For nice stack traces
+        val callSite = getCallingMethod()
+        val lines = spec.trim().trim('\n').split("\n").map { it.split("|") }
+        // |lines| contains arrays of strings that make up the statements of a thread : in other
+        // words, it's an array that contains a list of statements for each column in the spec.
+        // E.g. if the string is """
+        //   a | b | c
+        //   d | e | f
+        // """, then lines is [ [ "a", "b", "c" ], [ "d", "e", "f" ] ].
+        val threadCount = lines[0].size
+        assertTrue(lines.all { it.size == threadCount })
+        val threadInstructions = (0 until threadCount).map { i -> lines.map { it[i].trim() } }
+        // |threadInstructions| is a list where each element is the list of instructions for the
+        // thread at the index. In other words, it's just |lines| transposed. In the example
+        // above, it would be [ [ "a", "d" ], [ "b", "e" ], [ "c", "f" ] ]
+        // mapIndexed below will pass in |instructions| the list of instructions for this thread.
+        val barrier = CyclicBarrier(threadCount)
+        var crash: InterpretException? = null
+        threadInstructions.mapIndexed { threadIndex, instructions ->
+            Thread {
+                val threadLocal = threadTransform(initial)
+                lastBlockedTime.set(System.currentTimeMillis())
+                barrier.await()
+                var lineNum = 0
+                instructions.forEach {
+                    if (null != crash) return@Thread
+                    lineNum += 1
+                    try {
+                        interpretMultiple(it, threadLocal)
+                    } catch (e: Throwable) {
+                        // If fail() or some exception was called, the thread will come here ; if
+                        // the exception isn't caught the process will crash, which is not nice for
+                        // testing. Instead, catch the exception, cancel other threads, and report
+                        // nicely. Catch throwable because fail() is AssertionError, which inherits
+                        // from Error.
+                        crash = InterpretException(threadIndex, it,
+                                callSite.lineNumber + lineNum + lineShift,
+                                callSite.className, callSite.methodName, callSite.fileName, e)
+                    }
+                    lastBlockedTime.set(System.currentTimeMillis())
+                    barrier.await()
+                }
+            }.also { it.start() }
+        }.forEach { it.join() }
+        // If the test failed, crash with line number
+        crash?.let { throw it }
+    }
+
+    // Helper to get the stack trace for a calling method
+    private fun getCallingStackTrace(): Array<StackTraceElement> {
+        try {
+            throw RuntimeException()
+        } catch (e: RuntimeException) {
+            return e.stackTrace
+        }
+    }
+
+    // Find the calling method. This is the first method in the stack trace that is annotated
+    // with @Test.
+    fun getCallingMethod(): StackTraceElement {
+        val stackTrace = getCallingStackTrace()
+        return stackTrace.find { element ->
+            val clazz = Class.forName(element.className)
+            // Because the stack trace doesn't list the formal arguments, find all methods with
+            // this name and return this name if any of them is annotated with @Test.
+            clazz.declaredMethods
+                    .filter { method -> method.name == element.methodName }
+                    .any { method -> method.getAnnotation(org.junit.Test::class.java) != null }
+        } ?: stackTrace[3]
+        // If no method is annotated return the 4th one, because that's what it usually is :
+        // 0 is getCallingStackTrace, 1 is this method, 2 is ConcurrentInterpreter#interpretTestSpec
+    }
+}
+
+/**
+ * Default instructions available to all interpreters.
+ * sleep(x) : sleeps for x time units and returns Unit ; sleep alone means sleep(1)
+ * EXPR = VALUE : asserts that EXPR equals VALUE. EXPR is interpreted. VALUE can either be the
+ *   string "null" or an int. Returns Unit.
+ * EXPR time x..y : measures the time taken by EXPR and asserts it took at least x and at most
+ *   y time units.
+ * EXPR // any text : comments are ignored.
+ * EXPR fails : checks that EXPR throws some exception.
+ */
+private fun <T> getDefaultInstructions() = listOf<InterpretMatcher<T>>(
+    // Interpret an empty line as doing nothing.
+    Regex("") to { _, _, _ -> null },
+    // Ignore comments.
+    Regex("(.*)//.*") to { i, t, r -> i.interpret(r.strArg(1), t) },
+    // Interpret "XXX time x..y" : run XXX and check it took at least x and not more than y
+    Regex("""(.*)\s*time\s*(\d+)\.\.(\d+)""") to { i, t, r ->
+        val lateStart = System.currentTimeMillis()
+        i.interpret(r.strArg(1), t)
+        val end = System.currentTimeMillis()
+        // There is uncertainty in measuring time.
+        // It takes some (small) time for the thread to even measure the time at which it
+        // starts interpreting the instruction. It is therefore possible that thread A sleeps for
+        // n milliseconds, and B expects to have waited for at least n milliseconds, but because
+        // B started measuring after 1ms or so, B thinks it didn't wait long enough.
+        // To avoid this, when the `time` instruction tests the instruction took at least X and
+        // at most Y, it tests X against a time measured since *before* the thread blocked but
+        // Y against a time measured as late as possible. This ensures that the timer is
+        // sufficiently lenient in both directions that there are no flaky measures.
+        val minTime = end - lateStart
+        val maxTime = end - i.lastBlockedTime.get()!!
+
+        assertTrue(maxTime >= r.timeArg(2),
+                "Should have taken at least ${r.timeArg(2)} but took less than $maxTime")
+        assertTrue(minTime <= r.timeArg(3),
+                "Should have taken at most ${r.timeArg(3)} but took more than $minTime")
+    },
+    // Interpret "XXX = YYY" : run XXX and assert its return value is equal to YYY. "null" supported
+    Regex("""(.*)\s*=\s*(null|\d+)""") to { i, t, r ->
+        i.interpret(r.strArg(1), t).also {
+            if ("null" == r.strArg(2)) assertNull(it) else assertEquals(r.intArg(2), it)
+        }
+    },
+    // Interpret sleep. Optional argument for the count, in INTERPRET_TIME_UNIT units.
+    Regex("""sleep(\((\d+)\))?""") to { i, t, r ->
+        SystemClock.sleep(if (r.strArg(2).isEmpty()) INTERPRET_TIME_UNIT else r.timeArg(2))
+    },
+    Regex("""(.*)\s*fails""") to { i, t, r ->
+        assertFails { i.interpret(r.strArg(1), t) }
+    }
+)
+
+class SyntaxException(msg: String, cause: Throwable? = null) : RuntimeException(msg, cause)
+class InterpretException(
+    threadIndex: Int,
+    instr: String,
+    lineNum: Int,
+    className: String,
+    methodName: String,
+    fileName: String,
+    cause: Throwable
+) : RuntimeException("Failure: $instr", cause) {
+    init {
+        stackTrace = arrayOf(StackTraceElement(
+                className,
+                "$methodName:thread$threadIndex",
+                fileName,
+                lineNum)) + super.getStackTrace()
+    }
+}
+
+// Some small helpers to avoid to say the large ".groupValues[index].trim()" every time
+fun MatchResult.strArg(index: Int) = this.groupValues[index].trim()
+fun MatchResult.intArg(index: Int) = strArg(index).toInt()
+fun MatchResult.timeArg(index: Int) = INTERPRET_TIME_UNIT * intArg(index)
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/ConnectUtil.kt b/staticlibs/testutils/devicetests/com/android/testutils/ConnectUtil.kt
new file mode 100644
index 0000000..71f7877
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/ConnectUtil.kt
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import android.Manifest.permission
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.net.ConnectivityManager
+import android.net.Network
+import android.net.NetworkCapabilities.TRANSPORT_WIFI
+import android.net.NetworkRequest
+import android.net.wifi.ScanResult
+import android.net.wifi.WifiConfiguration
+import android.net.wifi.WifiManager
+import android.os.ParcelFileDescriptor
+import android.os.SystemClock
+import android.util.Log
+import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
+import com.android.testutils.RecorderCallback.CallbackEntry
+import java.util.concurrent.CompletableFuture
+import java.util.concurrent.TimeUnit
+import kotlin.test.assertNotNull
+import kotlin.test.assertTrue
+import kotlin.test.fail
+
+private const val MAX_WIFI_CONNECT_RETRIES = 10
+private const val WIFI_CONNECT_INTERVAL_MS = 500L
+private const val WIFI_CONNECT_TIMEOUT_MS = 30_000L
+
+// Constants used by WifiManager.ActionListener#onFailure. Although onFailure is SystemApi,
+// the error code constants are not (b/204277752)
+private const val WIFI_ERROR_IN_PROGRESS = 1
+private const val WIFI_ERROR_BUSY = 2
+
+class ConnectUtil(private val context: Context) {
+    private val TAG = ConnectUtil::class.java.simpleName
+
+    private val cm = context.getSystemService(ConnectivityManager::class.java)
+            ?: fail("Could not find ConnectivityManager")
+    private val wifiManager = context.getSystemService(WifiManager::class.java)
+            ?: fail("Could not find WifiManager")
+
+    fun ensureWifiConnected(): Network {
+        val callback = TestableNetworkCallback()
+        cm.registerNetworkCallback(NetworkRequest.Builder()
+                .addTransportType(TRANSPORT_WIFI)
+                .build(), callback)
+
+        try {
+            val connInfo = wifiManager.connectionInfo
+            Log.d(TAG, "connInfo=" + connInfo)
+            if (connInfo == null || connInfo.networkId == -1) {
+                clearWifiBlocklist()
+                val pfd = getInstrumentation().uiAutomation.executeShellCommand("svc wifi enable")
+                // Read the output stream to ensure the command has completed
+                ParcelFileDescriptor.AutoCloseInputStream(pfd).use { it.readBytes() }
+                val config = getOrCreateWifiConfiguration()
+                connectToWifiConfig(config)
+            }
+            val cb = callback.poll(WIFI_CONNECT_TIMEOUT_MS) { it is CallbackEntry.Available }
+            assertNotNull(cb, "Could not connect to a wifi access point within " +
+                    "$WIFI_CONNECT_TIMEOUT_MS ms. Check that the test device has a wifi network " +
+                    "configured, and that the test access point is functioning properly.")
+            return cb.network
+        } finally {
+            cm.unregisterNetworkCallback(callback)
+        }
+    }
+
+    private fun connectToWifiConfig(config: WifiConfiguration) {
+        repeat(MAX_WIFI_CONNECT_RETRIES) {
+            val error = runAsShell(permission.NETWORK_SETTINGS) {
+                val listener = ConnectWifiListener()
+                wifiManager.connect(config, listener)
+                listener.connectFuture.get(WIFI_CONNECT_TIMEOUT_MS, TimeUnit.MILLISECONDS)
+            } ?: return // Connect succeeded
+
+            // Only retry for IN_PROGRESS and BUSY
+            if (error != WIFI_ERROR_IN_PROGRESS && error != WIFI_ERROR_BUSY) {
+                fail("Failed to connect to " + config.SSID + ": " + error)
+            }
+            Log.w(TAG, "connect failed with $error; waiting before retry")
+            SystemClock.sleep(WIFI_CONNECT_INTERVAL_MS)
+        }
+        fail("Failed to connect to ${config.SSID} after $MAX_WIFI_CONNECT_RETRIES retries")
+    }
+
+    private class ConnectWifiListener : WifiManager.ActionListener {
+        /**
+         * Future completed when the connect process ends. Provides the error code or null if none.
+         */
+        val connectFuture = CompletableFuture<Int?>()
+        override fun onSuccess() {
+            connectFuture.complete(null)
+        }
+
+        override fun onFailure(reason: Int) {
+            connectFuture.complete(reason)
+        }
+    }
+
+    private fun getOrCreateWifiConfiguration(): WifiConfiguration {
+        val configs = runAsShell(permission.NETWORK_SETTINGS) {
+            wifiManager.getConfiguredNetworks()
+        }
+        // If no network is configured, add a config for virtual access points if applicable
+        if (configs.size == 0) {
+            val scanResults = getWifiScanResults()
+            val virtualConfig = maybeConfigureVirtualNetwork(scanResults)
+            assertNotNull(virtualConfig, "The device has no configured wifi network")
+            return virtualConfig
+        }
+        // No need to add a configuration: there is already one.
+        if (configs.size > 1) {
+            // For convenience in case of local testing on devices with multiple saved configs,
+            // prefer the first configuration that is in range.
+            // In actual tests, there should only be one configuration, and it should be usable as
+            // assumed by WifiManagerTest.testConnect.
+            Log.w(TAG, "Multiple wifi configurations found: " +
+                    configs.joinToString(", ") { it.SSID })
+            val scanResultsList = getWifiScanResults()
+            Log.i(TAG, "Scan results: " + scanResultsList.joinToString(", ") {
+                "${it.SSID} (${it.level})"
+            })
+
+            val scanResults = scanResultsList.map { "\"${it.SSID}\"" }.toSet()
+            return configs.firstOrNull { scanResults.contains(it.SSID) } ?: configs[0]
+        }
+        return configs[0]
+    }
+
+    private fun getWifiScanResults(): List<ScanResult> {
+        val scanResultsFuture = CompletableFuture<List<ScanResult>>()
+        runAsShell(permission.NETWORK_SETTINGS) {
+            val receiver: BroadcastReceiver = object : BroadcastReceiver() {
+                override fun onReceive(context: Context, intent: Intent) {
+                    scanResultsFuture.complete(wifiManager.scanResults)
+                }
+            }
+            context.registerReceiver(receiver,
+                    IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION))
+            wifiManager.startScan()
+        }
+        return try {
+            scanResultsFuture.get(WIFI_CONNECT_TIMEOUT_MS, TimeUnit.MILLISECONDS)
+        } catch (e: Exception) {
+            throw AssertionError("Wifi scan results not received within timeout", e)
+        }
+    }
+
+    /**
+     * If a virtual wifi network is detected, add a configuration for that network.
+     * TODO(b/158150376): have the test infrastructure add virtual wifi networks when appropriate.
+     */
+    private fun maybeConfigureVirtualNetwork(scanResults: List<ScanResult>): WifiConfiguration? {
+        // Virtual wifi networks used on the emulator and cloud testing infrastructure
+        val virtualSsids = listOf("VirtWifi", "AndroidWifi")
+        Log.d(TAG, "Wifi scan results: $scanResults")
+        val virtualScanResult = scanResults.firstOrNull { virtualSsids.contains(it.SSID) }
+                ?: return null
+
+        // Only add the virtual configuration if the virtual AP is detected in scans
+        val virtualConfig = WifiConfiguration()
+        // ASCII SSIDs need to be surrounded by double quotes
+        virtualConfig.SSID = "\"${virtualScanResult.SSID}\""
+        virtualConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
+        runAsShell(permission.NETWORK_SETTINGS) {
+            val networkId = wifiManager.addNetwork(virtualConfig)
+            assertTrue(networkId >= 0)
+            assertTrue(wifiManager.enableNetwork(networkId, false /* attemptConnect */))
+        }
+        return virtualConfig
+    }
+
+    /**
+     * Re-enable wifi networks that were blocked, typically because no internet connection was
+     * detected the last time they were connected. This is necessary to make sure wifi can reconnect
+     * to them.
+     */
+    private fun clearWifiBlocklist() {
+        runAsShell(permission.NETWORK_SETTINGS, permission.ACCESS_WIFI_STATE) {
+            for (cfg in wifiManager.configuredNetworks) {
+                assertTrue(wifiManager.enableNetwork(cfg.networkId, false /* attemptConnect */))
+            }
+        }
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/ContextUtils.kt b/staticlibs/testutils/devicetests/com/android/testutils/ContextUtils.kt
new file mode 100644
index 0000000..936b568
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/ContextUtils.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:JvmName("ContextUtils")
+
+package com.android.testutils
+
+import android.content.Context
+import android.os.UserHandle
+import org.mockito.AdditionalAnswers.delegatesTo
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mockito.doAnswer
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.mock
+import java.util.function.BiConsumer
+
+// Helper function so that Java doesn't have to pass a method that returns Unit
+fun mockContextAsUser(context: Context, functor: BiConsumer<Context, UserHandle>? = null) =
+    mockContextAsUser(context) { c, h -> functor?.accept(c, h) }
+
+/**
+ * Return a context with assigned user and delegate to original context.
+ *
+ * @param context the mock context to set up createContextAsUser on. After this function
+ *                is called, client code can call createContextAsUser and expect a context that
+ *                will return the correct user and userId.
+ *
+ * @param functor additional code to run on the created context-as-user instances, for example to
+ *                set up further mocks on these contexts.
+ */
+fun mockContextAsUser(context: Context, functor: ((Context, UserHandle) -> Unit)? = null) {
+    doAnswer { invocation ->
+        val asUserContext = mock(Context::class.java, delegatesTo<Context>(context))
+        val user = invocation.arguments[0] as UserHandle
+        val userId = user.identifier
+        doReturn(user).`when`(asUserContext).user
+        doReturn(userId).`when`(asUserContext).userId
+        functor?.let { it(asUserContext, user) }
+        asUserContext
+    }.`when`(context).createContextAsUser(any(UserHandle::class.java), anyInt() /* flags */)
+}
+
+/**
+ * Helper function to mock the desired system service.
+ *
+ * @param context the mock context to set up the getSystemService and getSystemServiceName.
+ * @param clazz the system service class that intents to mock.
+ * @param service the system service name that intents to mock.
+ */
+fun <T> mockService(context: Context, clazz: Class<T>, name: String, service: T) {
+    doReturn(service).`when`(context).getSystemService(name)
+    doReturn(name).`when`(context).getSystemServiceName(clazz)
+}
\ No newline at end of file
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/DevSdkIgnoreRule.kt b/staticlibs/testutils/devicetests/com/android/testutils/DevSdkIgnoreRule.kt
new file mode 100644
index 0000000..35f22b9
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/DevSdkIgnoreRule.kt
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import android.os.Build
+import androidx.test.InstrumentationRegistry
+import com.android.modules.utils.build.UnboundedSdkLevel
+import java.util.regex.Pattern
+import org.junit.Assume.assumeTrue
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
+
+@Deprecated("Use Build.VERSION_CODES", ReplaceWith("Build.VERSION_CODES.S_V2"))
+const val SC_V2 = Build.VERSION_CODES.S_V2
+
+private val MAX_TARGET_SDK_ANNOTATION_RE = Pattern.compile("MaxTargetSdk([0-9]+)$")
+private val targetSdk = InstrumentationRegistry.getContext().applicationInfo.targetSdkVersion
+
+private fun isDevSdkInRange(minExclusive: String?, maxInclusive: String?): Boolean {
+    return (minExclusive == null || !isAtMost(minExclusive)) &&
+            (maxInclusive == null || isAtMost(maxInclusive))
+}
+
+private fun isAtMost(sdkVersionOrCodename: String): Boolean {
+    // UnboundedSdkLevel does not support builds < Q, and may stop supporting Q as well since it
+    // is intended for mainline modules that are now R+.
+    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
+        // Assume that any codename passed as argument from current code is a more recent build than
+        // Q: this util did not exist before Q, and codenames are only used before the corresponding
+        // build is finalized. This util could list 28 older codenames to check against (as per
+        // ro.build.version.known_codenames in more recent builds), but this does not seem valuable.
+        val intVersion = sdkVersionOrCodename.toIntOrNull() ?: return true
+        return Build.VERSION.SDK_INT <= intVersion
+    }
+    return UnboundedSdkLevel.isAtMost(sdkVersionOrCodename)
+}
+
+/**
+ * Returns true if the development SDK version of the device is in the provided annotation range.
+ *
+ * If the device is not using a release SDK, the development SDK differs from
+ * [Build.VERSION.SDK_INT], and is indicated by the device codenames; see [UnboundedSdkLevel].
+ */
+fun isDevSdkInRange(
+    ignoreUpTo: DevSdkIgnoreRule.IgnoreUpTo?,
+    ignoreAfter: DevSdkIgnoreRule.IgnoreAfter?
+): Boolean {
+    val minExclusive =
+            if (ignoreUpTo?.value == 0) ignoreUpTo.codename
+            else ignoreUpTo?.value?.toString()
+    val maxInclusive =
+            if (ignoreAfter?.value == 0) ignoreAfter.codename
+            else ignoreAfter?.value?.toString()
+    return isDevSdkInRange(minExclusive, maxInclusive)
+}
+
+private fun getMaxTargetSdk(description: Description): Int? {
+    return description.annotations.firstNotNullOfOrNull {
+        MAX_TARGET_SDK_ANNOTATION_RE.matcher(it.annotationClass.simpleName).let { m ->
+            if (m.find()) m.group(1).toIntOrNull() else null
+        }
+    }
+}
+
+/**
+ * A test rule to ignore tests based on the development SDK level.
+ *
+ * If the device is not using a release SDK, the development SDK is considered to be higher than
+ * [Build.VERSION.SDK_INT].
+ *
+ * @param ignoreClassUpTo Skip all tests in the class if the device dev SDK is <= this codename or
+ *                        SDK level.
+ * @param ignoreClassAfter Skip all tests in the class if the device dev SDK is > this codename or
+ *                         SDK level.
+ */
+class DevSdkIgnoreRule @JvmOverloads constructor(
+    private val ignoreClassUpTo: String? = null,
+    private val ignoreClassAfter: String? = null
+) : TestRule {
+    /**
+     * @param ignoreClassUpTo Skip all tests in the class if the device dev SDK is <= this value.
+     * @param ignoreClassAfter Skip all tests in the class if the device dev SDK is > this value.
+     */
+    @JvmOverloads
+    constructor(ignoreClassUpTo: Int?, ignoreClassAfter: Int? = null) : this(
+            ignoreClassUpTo?.toString(), ignoreClassAfter?.toString())
+
+    override fun apply(base: Statement, description: Description): Statement {
+        return IgnoreBySdkStatement(base, description)
+    }
+
+    /**
+     * Ignore the test for any development SDK that is strictly after [value].
+     *
+     * If the device is not using a release SDK, the development SDK is considered to be higher
+     * than [Build.VERSION.SDK_INT].
+     */
+    annotation class IgnoreAfter(val value: Int = 0, val codename: String = "")
+
+    /**
+     * Ignore the test for any development SDK that lower than or equal to [value].
+     *
+     * If the device is not using a release SDK, the development SDK is considered to be higher
+     * than [Build.VERSION.SDK_INT].
+     */
+    annotation class IgnoreUpTo(val value: Int = 0, val codename: String = "")
+
+    private inner class IgnoreBySdkStatement(
+        private val base: Statement,
+        private val description: Description
+    ) : Statement() {
+        override fun evaluate() {
+            val ignoreAfter = description.getAnnotation(IgnoreAfter::class.java)
+            val ignoreUpTo = description.getAnnotation(IgnoreUpTo::class.java)
+
+            val devSdkMessage = "Skipping test for build ${Build.VERSION.CODENAME} " +
+                    "with SDK ${Build.VERSION.SDK_INT}"
+            assumeTrue(devSdkMessage, isDevSdkInRange(ignoreClassUpTo, ignoreClassAfter))
+            assumeTrue(devSdkMessage, isDevSdkInRange(ignoreUpTo, ignoreAfter))
+
+            val maxTargetSdk = getMaxTargetSdk(description)
+            if (maxTargetSdk != null) {
+                assumeTrue("Skipping test, target SDK $targetSdk greater than $maxTargetSdk",
+                        targetSdk <= maxTargetSdk)
+            }
+            base.evaluate()
+        }
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/DevSdkIgnoreRunner.kt b/staticlibs/testutils/devicetests/com/android/testutils/DevSdkIgnoreRunner.kt
new file mode 100644
index 0000000..2e73666
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/DevSdkIgnoreRunner.kt
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
+import org.junit.runner.Description
+import org.junit.runner.Runner
+import org.junit.runner.manipulation.Filter
+import org.junit.runner.manipulation.Filterable
+import org.junit.runner.manipulation.NoTestsRemainException
+import org.junit.runner.manipulation.Sortable
+import org.junit.runner.manipulation.Sorter
+import org.junit.runner.notification.RunNotifier
+import kotlin.jvm.Throws
+
+/**
+ * A runner that can skip tests based on the development SDK as defined in [DevSdkIgnoreRule].
+ *
+ * Generally [DevSdkIgnoreRule] should be used for that purpose (using rules is preferable over
+ * replacing the test runner), however JUnit runners inspect all methods in the test class before
+ * processing test rules. This may cause issues if the test methods are referencing classes that do
+ * not exist on the SDK of the device the test is run on.
+ *
+ * This runner inspects [IgnoreAfter] and [IgnoreUpTo] annotations on the test class, and will skip
+ * the whole class if they do not match the development SDK as defined in [DevSdkIgnoreRule].
+ * Otherwise, it will delegate to [AndroidJUnit4] to run the test as usual.
+ *
+ * Example usage:
+ *
+ *     @RunWith(DevSdkIgnoreRunner::class)
+ *     @IgnoreUpTo(Build.VERSION_CODES.Q)
+ *     class MyTestClass { ... }
+ */
+class DevSdkIgnoreRunner(private val klass: Class<*>) : Runner(), Filterable, Sortable {
+    private val baseRunner = klass.let {
+        val ignoreAfter = it.getAnnotation(IgnoreAfter::class.java)
+        val ignoreUpTo = it.getAnnotation(IgnoreUpTo::class.java)
+
+        if (isDevSdkInRange(ignoreUpTo, ignoreAfter)) AndroidJUnit4(klass) else null
+    }
+
+    override fun run(notifier: RunNotifier) {
+        if (baseRunner != null) {
+            baseRunner.run(notifier)
+            return
+        }
+
+        // Report a single, skipped placeholder test for this class, as the class is expected to
+        // report results when run. In practice runners that apply the Filterable implementation
+        // would see a NoTestsRemainException and not call the run method.
+        notifier.fireTestIgnored(
+                Description.createTestDescription(klass, "skippedClassForDevSdkMismatch"))
+    }
+
+    override fun getDescription(): Description {
+        return baseRunner?.description ?: Description.createSuiteDescription(klass)
+    }
+
+    /**
+     * Get the test count before applying the [Filterable] implementation.
+     */
+    override fun testCount(): Int {
+        // When ignoring the tests, a skipped placeholder test is reported, so test count is 1.
+        return baseRunner?.testCount() ?: 1
+    }
+
+    @Throws(NoTestsRemainException::class)
+    override fun filter(filter: Filter?) {
+        baseRunner?.filter(filter) ?: throw NoTestsRemainException()
+    }
+
+    override fun sort(sorter: Sorter?) {
+        baseRunner?.sort(sorter)
+    }
+}
\ No newline at end of file
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/DeviceConfigRule.kt b/staticlibs/testutils/devicetests/com/android/testutils/DeviceConfigRule.kt
new file mode 100644
index 0000000..3d98cc3
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/DeviceConfigRule.kt
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import android.Manifest.permission.READ_DEVICE_CONFIG
+import android.Manifest.permission.WRITE_DEVICE_CONFIG
+import android.provider.DeviceConfig
+import android.util.Log
+import com.android.modules.utils.build.SdkLevel
+import com.android.testutils.FunctionalUtils.ThrowingRunnable
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
+import java.util.concurrent.CompletableFuture
+import java.util.concurrent.Executor
+import java.util.concurrent.TimeUnit
+
+private val TAG = DeviceConfigRule::class.simpleName
+
+private const val TIMEOUT_MS = 20_000L
+
+/**
+ * A [TestRule] that helps set [DeviceConfig] for tests and clean up the test configuration
+ * automatically on teardown.
+ *
+ * The rule can also optionally retry tests when they fail following an external change of
+ * DeviceConfig before S; this typically happens because device config flags are synced while the
+ * test is running, and DisableConfigSyncTargetPreparer is only usable starting from S.
+ *
+ * @param retryCountBeforeSIfConfigChanged if > 0, when the test fails before S, check if
+ *        the configs that were set through this rule were changed, and retry the test
+ *        up to the specified number of times if yes.
+ */
+class DeviceConfigRule @JvmOverloads constructor(
+    val retryCountBeforeSIfConfigChanged: Int = 0
+) : TestRule {
+    // Maps (namespace, key) -> value
+    private val originalConfig = mutableMapOf<Pair<String, String>, String?>()
+    private val usedConfig = mutableMapOf<Pair<String, String>, String?>()
+
+    /**
+     * Actions to be run after cleanup of the config, for the current test only.
+     */
+    private val currentTestCleanupActions = mutableListOf<ThrowingRunnable>()
+
+    override fun apply(base: Statement, description: Description): Statement {
+        return TestValidationUrlStatement(base, description)
+    }
+
+    private inner class TestValidationUrlStatement(
+        private val base: Statement,
+        private val description: Description
+    ) : Statement() {
+        override fun evaluate() {
+            var retryCount = if (SdkLevel.isAtLeastS()) 1 else retryCountBeforeSIfConfigChanged + 1
+            while (retryCount > 0) {
+                retryCount--
+                tryTest {
+                    base.evaluate()
+                    // Can't use break/return out of a loop here because this is a tryTest lambda,
+                    // so set retryCount to exit instead
+                    retryCount = 0
+                }.catch<Throwable> { e -> // junit AssertionFailedError does not extend Exception
+                    if (retryCount == 0) throw e
+                    usedConfig.forEach { (key, value) ->
+                        val currentValue = runAsShell(READ_DEVICE_CONFIG) {
+                            DeviceConfig.getProperty(key.first, key.second)
+                        }
+                        if (currentValue != value) {
+                            Log.w(TAG, "Test failed with unexpected device config change, retrying")
+                            return@catch
+                        }
+                    }
+                    throw e
+                } cleanupStep {
+                    runAsShell(WRITE_DEVICE_CONFIG) {
+                        originalConfig.forEach { (key, value) ->
+                            DeviceConfig.setProperty(
+                                    key.first, key.second, value, false /* makeDefault */)
+                        }
+                    }
+                } cleanupStep {
+                    originalConfig.clear()
+                    usedConfig.clear()
+                } cleanup {
+                    // Fold all cleanup actions into cleanup steps of an empty tryTest, so they are
+                    // all run even if exceptions are thrown, and exceptions are reported properly.
+                    currentTestCleanupActions.fold(tryTest { }) {
+                        tryBlock, action -> tryBlock.cleanupStep { action.run() }
+                    }.cleanup {
+                        currentTestCleanupActions.clear()
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Set a configuration key/value. After the test case ends, it will be restored to the value it
+     * had when this method was first called.
+     */
+    fun setConfig(namespace: String, key: String, value: String?): String? {
+        Log.i(TAG, "Setting config \"$key\" to \"$value\"")
+        val readWritePermissions = arrayOf(READ_DEVICE_CONFIG, WRITE_DEVICE_CONFIG)
+
+        val keyPair = Pair(namespace, key)
+        val existingValue = runAsShell(*readWritePermissions) {
+            DeviceConfig.getProperty(namespace, key)
+        }
+        if (!originalConfig.containsKey(keyPair)) {
+            originalConfig[keyPair] = existingValue
+        }
+        usedConfig[keyPair] = value
+        if (existingValue == value) {
+            // Already the correct value. There may be a race if a change is already in flight,
+            // but if multiple threads update the config there is no way to fix that anyway.
+            Log.i(TAG, "\"$key\" already had value \"$value\"")
+            return value
+        }
+
+        val future = CompletableFuture<String>()
+        val listener = DeviceConfig.OnPropertiesChangedListener {
+            // The listener receives updates for any change to any key, so don't react to
+            // changes that do not affect the relevant key
+            if (!it.keyset.contains(key)) return@OnPropertiesChangedListener
+            // "null" means absent in DeviceConfig : there is no such thing as a present but
+            // null value, so the following works even if |value| is null.
+            if (it.getString(key, null) == value) {
+                future.complete(value)
+            }
+        }
+
+        return tryTest {
+            runAsShell(*readWritePermissions) {
+                DeviceConfig.addOnPropertiesChangedListener(
+                        DeviceConfig.NAMESPACE_CONNECTIVITY,
+                        inlineExecutor,
+                        listener)
+                DeviceConfig.setProperty(
+                        DeviceConfig.NAMESPACE_CONNECTIVITY,
+                        key,
+                        value,
+                        false /* makeDefault */)
+                // Don't drop the permission until the config is applied, just in case
+                future.get(TIMEOUT_MS, TimeUnit.MILLISECONDS)
+            }.also {
+                Log.i(TAG, "Config \"$key\" successfully set to \"$value\"")
+            }
+        } cleanup {
+            DeviceConfig.removeOnPropertiesChangedListener(listener)
+        }
+    }
+
+    private val inlineExecutor get() = Executor { r -> r.run() }
+
+    /**
+     * Add an action to be run after config cleanup when the current test case ends.
+     */
+    fun runAfterNextCleanup(action: ThrowingRunnable) {
+        currentTestCleanupActions.add(action)
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/DeviceInfoUtils.java b/staticlibs/testutils/devicetests/com/android/testutils/DeviceInfoUtils.java
new file mode 100644
index 0000000..ce55fdc
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/DeviceInfoUtils.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils;
+
+import android.os.VintfRuntimeInfo;
+import android.text.TextUtils;
+import android.util.Pair;
+
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Utilities for device information.
+ */
+public class DeviceInfoUtils {
+    /**
+     * Class for a three-part kernel version number.
+     */
+    public static class KVersion {
+        public final int major;
+        public final int minor;
+        public final int sub;
+
+        public KVersion(int major, int minor, int sub) {
+            this.major = major;
+            this.minor = minor;
+            this.sub = sub;
+        }
+
+        /**
+         * Compares with other version numerically.
+         *
+         * @param  other the other version to compare
+         * @return the value 0 if this == other;
+         *         a value less than 0 if this < other and
+         *         a value greater than 0 if this > other.
+         */
+        public int compareTo(final KVersion other) {
+            int res = Integer.compare(this.major, other.major);
+            if (res == 0) {
+                res = Integer.compare(this.minor, other.minor);
+            }
+            if (res == 0) {
+                res = Integer.compare(this.sub, other.sub);
+            }
+            return res;
+        }
+
+        /**
+         * At least satisfied with the given version.
+         *
+         * @param  from the start version to compare
+         * @return return true if this version is at least satisfied with the given version.
+         *         otherwise, return false.
+         */
+        public boolean isAtLeast(final KVersion from) {
+            return compareTo(from) >= 0;
+        }
+
+        /**
+         * Falls within the given range [from, to).
+         *
+         * @param  from the start version to compare
+         * @param  to   the end version to compare
+         * @return return true if this version falls within the given range.
+         *         otherwise, return false.
+         */
+        public boolean isInRange(final KVersion from, final KVersion to) {
+            return isAtLeast(from) && !isAtLeast(to);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof KVersion)) return false;
+            KVersion that = (KVersion) o;
+            return this.major == that.major
+                    && this.minor == that.minor
+                    && this.sub == that.sub;
+        }
+    };
+
+    /**
+     * Get a two-part kernel version number (major and minor) from a given string.
+     *
+     * TODO: use class KVersion.
+     */
+    private static Pair<Integer, Integer> getMajorMinorVersion(String version) {
+        // Only gets major and minor number of the version string.
+        final Pattern versionPattern = Pattern.compile("^(\\d+)(\\.(\\d+))?.*");
+        final Matcher m = versionPattern.matcher(version);
+        if (m.matches()) {
+            final int major = Integer.parseInt(m.group(1));
+            final int minor = TextUtils.isEmpty(m.group(3)) ? 0 : Integer.parseInt(m.group(3));
+            return new Pair<>(major, minor);
+        } else {
+            return new Pair<>(0, 0);
+        }
+    }
+
+    /**
+     * Compares two version strings numerically. Compare only major and minor number of the
+     * version string. The version comparison uses #Integer.compare. Possible version
+     * 5, 5.10, 5-beta1, 4.8-RC1, 4.7.10.10 and so on.
+     *
+     * @param  s1 the first version string to compare
+     * @param  s2 the second version string to compare
+     * @return the value 0 if s1 == s2;
+     *         a value less than 0 if s1 < s2 and
+     *         a value greater than 0 if s1 > s2.
+     *
+     * TODO: use class KVersion.
+     */
+    public static int compareMajorMinorVersion(final String s1, final String s2) {
+        final Pair<Integer, Integer> v1 = getMajorMinorVersion(s1);
+        final Pair<Integer, Integer> v2 = getMajorMinorVersion(s2);
+
+        if (Objects.equals(v1.first, v2.first)) {
+            return Integer.compare(v1.second, v2.second);
+        } else {
+            return Integer.compare(v1.first, v2.first);
+        }
+    }
+
+    /**
+     * Get a three-part kernel version number (major, minor and subminor) from a given string.
+     * Any version string must at least have major and minor number. If the subminor number can't
+     * be parsed from string. Assign zero as subminor number. Invalid version is treated as
+     * version 0.0.0.
+     */
+    public static KVersion getMajorMinorSubminorVersion(final String version) {
+        // The kernel version is a three-part version number (major, minor and subminor). Get
+        // the three-part version numbers and discard the remaining stuff if any.
+        // For example:
+        //   4.19.220-g500ede0aed22-ab8272303 --> 4.19.220
+        //   5.17-rc6-g52099515ca00-ab8032400 --> 5.17.0
+        final Pattern versionPattern = Pattern.compile("^(\\d+)\\.(\\d+)(\\.(\\d+))?.*");
+        final Matcher m = versionPattern.matcher(version);
+        if (m.matches()) {
+            final int major = Integer.parseInt(m.group(1));
+            final int minor = Integer.parseInt(m.group(2));
+            final int sub = TextUtils.isEmpty(m.group(4)) ? 0 : Integer.parseInt(m.group(4));
+            return new KVersion(major, minor, sub);
+        } else {
+            return new KVersion(0, 0, 0);
+        }
+    }
+
+    /**
+     * Check if the current kernel version is at least satisfied with the given version.
+     *
+     * @param  version the start version to compare
+     * @return return true if the current version is at least satisfied with the given version.
+     *         otherwise, return false.
+     */
+    public static boolean isKernelVersionAtLeast(final String version) {
+        final String kernelVersion = VintfRuntimeInfo.getKernelVersion();
+        final KVersion current = DeviceInfoUtils.getMajorMinorSubminorVersion(kernelVersion);
+        final KVersion from = DeviceInfoUtils.getMajorMinorSubminorVersion(version);
+        return current.isAtLeast(from);
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/DnsAnswerProvider.kt b/staticlibs/testutils/devicetests/com/android/testutils/DnsAnswerProvider.kt
new file mode 100644
index 0000000..6a804bf
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/DnsAnswerProvider.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import android.net.DnsResolver.CLASS_IN
+import com.android.net.module.util.DnsPacket
+import com.android.net.module.util.DnsPacket.ANSECTION
+import java.net.InetAddress
+import java.util.concurrent.ConcurrentHashMap
+
+const val DEFAULT_TTL_S = 5L
+
+/**
+ * Helper class to store the mapping of DNS queries.
+ *
+ * DnsAnswerProvider is built atop a ConcurrentHashMap and as such it provides the same
+ * guarantees as ConcurrentHashMap between writing and reading elements. Specifically :
+ * - Setting an answer happens-before reading the same answer.
+ * - Callers can read and write concurrently from DnsAnswerProvider and expect no
+ *   ConcurrentModificationException.
+ * Freshness of the answers depends on ordering of the threads ; if callers need a
+ * freshness guarantee, they need to provide the happens-before relationship from a
+ * write that they want to observe to the read that they need to be observed.
+ */
+class DnsAnswerProvider {
+    private val mDnsKeyToRecords = ConcurrentHashMap<String, List<DnsPacket.DnsRecord>>()
+
+    /**
+     * Get answer for the specified hostname.
+     *
+     * @param query the target hostname.
+     * @param type type of record, could be A or AAAA.
+     *
+     * @return list of [DnsPacket.DnsRecord] associated to the query. Empty if no record matches.
+     */
+    fun getAnswer(query: String, type: Int) = mDnsKeyToRecords[query]
+            .orEmpty().filter { it.nsType == type }
+
+    /** Set answer for the specified {@code query}.
+     *
+     * @param query the target hostname
+     * @param addresses [List<InetAddress>] which could be used to generate multiple A or AAAA
+     *                  RRs with the corresponding addresses.
+     */
+    fun setAnswer(query: String, hosts: List<InetAddress>) = mDnsKeyToRecords.put(query, hosts.map {
+            DnsPacket.DnsRecord.makeAOrAAAARecord(ANSECTION, query, CLASS_IN, DEFAULT_TTL_S, it)
+        })
+
+    fun clearAnswer(query: String) = mDnsKeyToRecords.remove(query)
+    fun clearAll() = mDnsKeyToRecords.clear()
+}
\ No newline at end of file
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/DumpTestUtils.java b/staticlibs/testutils/devicetests/com/android/testutils/DumpTestUtils.java
new file mode 100644
index 0000000..d103748
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/DumpTestUtils.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils;
+
+import static com.android.testutils.TestPermissionUtil.runAsShell;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.system.ErrnoException;
+import android.system.Os;
+
+import libcore.io.IoUtils;
+import libcore.io.Streams;
+
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Utilities for testing output of service dumps.
+ */
+public class DumpTestUtils {
+
+    private static String dumpService(String serviceName, boolean adoptPermission, String... args)
+            throws RemoteException, InterruptedException, ErrnoException {
+        final IBinder ib = ServiceManager.getService(serviceName);
+        FileDescriptor[] pipe = Os.pipe();
+
+        // Start a thread to read the dump output, or dump might block if it fills the pipe.
+        final CountDownLatch latch = new CountDownLatch(1);
+        AtomicReference<String> output = new AtomicReference<>();
+        // Used to send exceptions back to the main thread to ensure that the test fails cleanly.
+        AtomicReference<Exception> exception = new AtomicReference<>();
+        new Thread(() -> {
+            try {
+                output.set(Streams.readFully(
+                        new InputStreamReader(new FileInputStream(pipe[0]),
+                                StandardCharsets.UTF_8)));
+                latch.countDown();
+            } catch (Exception e) {
+                exception.set(e);
+                latch.countDown();
+            }
+        }).start();
+
+        final int timeoutMs = 5_000;
+        final String what = "service '" + serviceName + "' with args: " + Arrays.toString(args);
+        try {
+            if (adoptPermission) {
+                runAsShell(android.Manifest.permission.DUMP, () -> ib.dump(pipe[1], args));
+            } else {
+                ib.dump(pipe[1], args);
+            }
+            IoUtils.closeQuietly(pipe[1]);
+            assertTrue("Dump of " + what + " timed out after " + timeoutMs + "ms",
+                    latch.await(timeoutMs, TimeUnit.MILLISECONDS));
+        } finally {
+            // Closing the fds will terminate the thread if it's blocked on read.
+            IoUtils.closeQuietly(pipe[0]);
+            if (pipe[1].valid()) IoUtils.closeQuietly(pipe[1]);
+        }
+        if (exception.get() != null) {
+            fail("Exception dumping " + what + ": " + exception.get());
+        }
+        return output.get();
+    }
+
+    /**
+     * Dumps the specified service and returns a string. Sends a dump IPC to the given service
+     * with the specified args and a pipe, then reads from the pipe in a separate thread.
+     * The current process must already have the DUMP permission.
+     *
+     * @param serviceName the service to dump.
+     * @param args the arguments to pass to the dump function.
+     * @return The dump text.
+     * @throws RemoteException dumping the service failed.
+     * @throws InterruptedException the dump timed out.
+     * @throws ErrnoException opening or closing the pipe for the dump failed.
+     */
+    public static String dumpService(String serviceName, String... args)
+            throws RemoteException, InterruptedException, ErrnoException {
+        return dumpService(serviceName, false, args);
+    }
+
+    /**
+     * Dumps the specified service and returns a string. Sends a dump IPC to the given service
+     * with the specified args and a pipe, then reads from the pipe in a separate thread.
+     * Adopts the {@code DUMP} permission via {@code adoptShellPermissionIdentity} and then releases
+     * it. This method should not be used if the caller already has the shell permission identity.
+     * TODO: when Q and R are no longer supported, use
+     * {@link android.app.UiAutomation#getAdoptedShellPermissions} to automatically acquire the
+     * shell permission if the caller does not already have it.
+     *
+     * @param serviceName the service to dump.
+     * @param args the arguments to pass to the dump function.
+     * @return The dump text.
+     * @throws RemoteException dumping the service failed.
+     * @throws InterruptedException the dump timed out.
+     * @throws ErrnoException opening or closing the pipe for the dump failed.
+     */
+    public static String dumpServiceWithShellPermission(String serviceName, String... args)
+            throws RemoteException, InterruptedException, ErrnoException {
+        return dumpService(serviceName, true, args);
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/FakeDns.kt b/staticlibs/testutils/devicetests/com/android/testutils/FakeDns.kt
new file mode 100644
index 0000000..1f82a35
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/FakeDns.kt
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import android.net.DnsResolver
+import android.net.InetAddresses
+import android.os.Looper
+import android.os.Handler
+import com.android.internal.annotations.GuardedBy
+import java.net.InetAddress
+import java.util.concurrent.Executor
+import org.mockito.invocation.InvocationOnMock
+import org.mockito.Mockito.any
+import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.doAnswer
+
+const val TYPE_UNSPECIFIED = -1
+// TODO: Integrate with NetworkMonitorTest.
+class FakeDns(val mockResolver: DnsResolver) {
+    class DnsEntry(val hostname: String, val type: Int, val addresses: List<InetAddress>) {
+        fun match(host: String, type: Int) = hostname.equals(host) && type == type
+    }
+
+    @GuardedBy("answers")
+    val answers = ArrayList<DnsEntry>()
+
+    fun getAnswer(hostname: String, type: Int): DnsEntry? = synchronized(answers) {
+        return answers.firstOrNull { it.match(hostname, type) }
+    }
+
+    fun setAnswer(hostname: String, answer: Array<String>, type: Int) = synchronized(answers) {
+        val ans = DnsEntry(hostname, type, generateAnswer(answer))
+        // Replace or remove the existing one.
+        when (val index = answers.indexOfFirst { it.match(hostname, type) }) {
+            -1 -> answers.add(ans)
+            else -> answers[index] = ans
+        }
+    }
+
+    private fun generateAnswer(answer: Array<String>) =
+            answer.filterNotNull().map { InetAddresses.parseNumericAddress(it) }
+
+    fun startMocking() {
+        // Mock DnsResolver.query() w/o type
+        doAnswer {
+            mockAnswer(it, 1, -1, 3, 5)
+        }.`when`(mockResolver).query(any() /* network */, any() /* domain */, anyInt() /* flags */,
+                any() /* executor */, any() /* cancellationSignal */, any() /*callback*/)
+        // Mock DnsResolver.query() w/ type
+        doAnswer {
+            mockAnswer(it, 1, 2, 4, 6)
+        }.`when`(mockResolver).query(any() /* network */, any() /* domain */, anyInt() /* nsType */,
+                anyInt() /* flags */, any() /* executor */, any() /* cancellationSignal */,
+        any() /*callback*/)
+    }
+
+    private fun mockAnswer(
+        it: InvocationOnMock,
+        posHos: Int,
+        posType: Int,
+        posExecutor: Int,
+        posCallback: Int
+    ) {
+        val hostname = it.arguments[posHos] as String
+        val executor = it.arguments[posExecutor] as Executor
+        val callback = it.arguments[posCallback] as DnsResolver.Callback<List<InetAddress>>
+        var type = if (posType != -1) it.arguments[posType] as Int else TYPE_UNSPECIFIED
+        val answer = getAnswer(hostname, type)
+
+        if (answer != null && !answer.addresses.isNullOrEmpty()) {
+            Handler(Looper.getMainLooper()).post({ executor.execute({
+                    callback.onAnswer(answer.addresses, 0); }) })
+        }
+    }
+
+    /** Clears all entries. */
+    fun clearAll() = synchronized(answers) {
+        answers.clear()
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/HandlerUtils.kt b/staticlibs/testutils/devicetests/com/android/testutils/HandlerUtils.kt
new file mode 100644
index 0000000..f00ca11
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/HandlerUtils.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:JvmName("HandlerUtils")
+
+package com.android.testutils
+
+import android.os.ConditionVariable
+import android.os.Handler
+import android.os.HandlerThread
+import android.util.Log
+import com.android.testutils.FunctionalUtils.ThrowingRunnable
+import com.android.testutils.FunctionalUtils.ThrowingSupplier
+import java.lang.Exception
+import java.util.concurrent.Executor
+import kotlin.test.fail
+
+private const val TAG = "HandlerUtils"
+
+/**
+ * Block until the specified Handler or HandlerThread becomes idle, or until timeoutMs has passed.
+ */
+fun HandlerThread.waitForIdle(timeoutMs: Int) = threadHandler.waitForIdle(timeoutMs.toLong())
+fun HandlerThread.waitForIdle(timeoutMs: Long) = threadHandler.waitForIdle(timeoutMs)
+fun Handler.waitForIdle(timeoutMs: Int) = waitForIdle(timeoutMs.toLong())
+fun Handler.waitForIdle(timeoutMs: Long) {
+    val cv = ConditionVariable(false)
+    post(cv::open)
+    if (!cv.block(timeoutMs)) {
+        fail("Handler did not become idle after ${timeoutMs}ms")
+    }
+}
+
+/**
+ * Block until the given Serial Executor becomes idle, or until timeoutMs has passed.
+ */
+fun waitForIdleSerialExecutor(executor: Executor, timeoutMs: Long) {
+    val cv = ConditionVariable()
+    executor.execute(cv::open)
+    if (!cv.block(timeoutMs)) {
+        fail("Executor did not become idle after ${timeoutMs}ms")
+    }
+}
+
+/**
+ * Executes a block of code that returns a value, making its side effects visible on the caller and
+ * the handler thread.
+ *
+ * After this function returns, the side effects of the passed block of code are guaranteed to be
+ * observed both on the thread running the handler and on the thread running this method.
+ * To achieve this, this method runs the passed block on the handler and blocks this thread
+ * until it's executed, so keep in mind this method will block, (including, if the handler isn't
+ * running, blocking forever).
+ */
+fun <T> visibleOnHandlerThread(handler: Handler, supplier: ThrowingSupplier<T>): T {
+    val cv = ConditionVariable()
+    var rv: Result<T> = Result.failure(RuntimeException("Not run"))
+    handler.post {
+        try {
+            rv = Result.success(supplier.get())
+        } catch (exception: Exception) {
+            Log.e(TAG, "visibleOnHandlerThread caught exception", exception)
+            rv = Result.failure(exception)
+        }
+        cv.open()
+    }
+    // After block() returns, the handler thread has seen the change (since it ran it)
+    // and this thread also has seen the change (since cv.open() happens-before cv.block()
+    // returns).
+    cv.block()
+    return rv.getOrThrow()
+}
+
+/** Overload of visibleOnHandlerThread but executes a block of code that does not return a value. */
+inline fun visibleOnHandlerThread(handler: Handler, r: ThrowingRunnable){
+    visibleOnHandlerThread(handler, ThrowingSupplier<Unit> { r.run() })
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/NatExternalPacketForwarder.kt b/staticlibs/testutils/devicetests/com/android/testutils/NatExternalPacketForwarder.kt
new file mode 100644
index 0000000..d7961a0
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/NatExternalPacketForwarder.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import java.io.FileDescriptor
+import java.net.InetAddress
+
+/**
+ * A class that forwards packets from the external {@link TestNetworkInterface} to the internal
+ * {@link TestNetworkInterface} with NAT. See {@link NatPacketForwarderBase} for detail.
+ */
+class NatExternalPacketForwarder(
+    srcFd: FileDescriptor,
+    mtu: Int,
+    dstFd: FileDescriptor,
+    extAddr: InetAddress,
+    natMap: PacketBridge.NatMap
+) : NatPacketForwarderBase(srcFd, mtu, dstFd, extAddr, natMap) {
+
+    /**
+     * Rewrite addresses, ports and fix up checksums for packets received on the external
+     * interface.
+     *
+     * Incoming response from external interface which is being forwarded to the internal
+     * interface with translated address, e.g. 1.2.3.4:80 -> 8.8.8.8:1234
+     * will be translated into 8.8.8.8:80 -> 192.168.1.1:5678.
+     *
+     * For packets that are not an incoming response, do not forward them to the
+     * internal interface.
+     */
+    override fun preparePacketForForwarding(buf: ByteArray, len: Int, version: Int, proto: Int) {
+        val (addrPos, addrLen) = getAddressPositionAndLength(version)
+
+        // TODO: support one external address per ip version.
+        val extAddrBuf = mExtAddr.address
+        if (addrLen != extAddrBuf.size) throw IllegalStateException("Packet IP version mismatch")
+
+        // Get internal address by port.
+        val transportOffset =
+            if (version == 4) PacketReflector.IPV4_HEADER_LENGTH
+            else PacketReflector.IPV6_HEADER_LENGTH
+        val dstPort = getPortAt(buf, transportOffset + DESTINATION_PORT_OFFSET)
+        val intAddrInfo = synchronized(mNatMap) { mNatMap.fromExternalPort(dstPort) }
+        // No mapping, skip. This usually happens if the connection is initiated directly on
+        // the external interface, e.g. DNS64 resolution, network validation, etc.
+        if (intAddrInfo == null) return
+
+        val intAddrBuf = intAddrInfo.address.address
+        val intPort = intAddrInfo.port
+
+        // Copy the original destination to into the source address.
+        for (i in 0 until addrLen) {
+            buf[addrPos + i] = buf[addrPos + addrLen + i]
+        }
+
+        // Copy the internal address into the destination address.
+        for (i in 0 until addrLen) {
+            buf[addrPos + addrLen + i] = intAddrBuf[i]
+        }
+
+        // Copy the internal port into the destination port.
+        setPortAt(intPort, buf, transportOffset + DESTINATION_PORT_OFFSET)
+
+        // Fix IP and Transport layer checksum.
+        fixPacketChecksum(buf, len, version, proto.toByte())
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/NatInternalPacketForwarder.kt b/staticlibs/testutils/devicetests/com/android/testutils/NatInternalPacketForwarder.kt
new file mode 100644
index 0000000..fa39d19
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/NatInternalPacketForwarder.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import java.io.FileDescriptor
+import java.net.InetAddress
+
+/**
+ * A class that forwards packets from the internal {@link TestNetworkInterface} to the external
+ * {@link TestNetworkInterface} with NAT. See {@link NatPacketForwarderBase} for detail.
+ */
+class NatInternalPacketForwarder(
+    srcFd: FileDescriptor,
+    mtu: Int,
+    dstFd: FileDescriptor,
+    extAddr: InetAddress,
+    natMap: PacketBridge.NatMap
+) : NatPacketForwarderBase(srcFd, mtu, dstFd, extAddr, natMap) {
+
+    /**
+     * Rewrite addresses, ports and fix up checksums for packets received on the internal
+     * interface.
+     *
+     * Outgoing packet from the internal interface which is being forwarded to the
+     * external interface with translated address, e.g. 192.168.1.1:5678 -> 8.8.8.8:80
+     * will be translated into 8.8.8.8:1234 -> 1.2.3.4:80.
+     *
+     * The external port, e.g. 1234 in the above example, is the port number assigned by
+     * the forwarder when creating the mapping to identify the source address and port when
+     * the response is coming from the external interface. See {@link PacketBridge.NatMap}
+     * for detail.
+     */
+    override fun preparePacketForForwarding(buf: ByteArray, len: Int, version: Int, proto: Int) {
+        val (addrPos, addrLen) = getAddressPositionAndLength(version)
+
+        // TODO: support one external address per ip version.
+        val extAddrBuf = mExtAddr.address
+        if (addrLen != extAddrBuf.size) throw IllegalStateException("Packet IP version mismatch")
+
+        val srcAddr = getInetAddressAt(buf, addrPos, addrLen)
+
+        // Copy the original destination to into the source address.
+        for (i in 0 until addrLen) {
+            buf[addrPos + i] = buf[addrPos + addrLen + i]
+        }
+
+        // Copy the external address into the destination address.
+        for (i in 0 until addrLen) {
+            buf[addrPos + addrLen + i] = extAddrBuf[i]
+        }
+
+        // Add an entry to NAT mapping table.
+        val transportOffset =
+            if (version == 4) PacketReflector.IPV4_HEADER_LENGTH
+            else PacketReflector.IPV6_HEADER_LENGTH
+        val srcPort = getPortAt(buf, transportOffset)
+        val extPort = synchronized(mNatMap) { mNatMap.toExternalPort(srcAddr, srcPort, proto) }
+        // Copy the external port to into the source port.
+        setPortAt(extPort, buf, transportOffset)
+
+        // Fix IP and Transport layer checksum.
+        fixPacketChecksum(buf, len, version, proto.toByte())
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/NatPacketForwarderBase.java b/staticlibs/testutils/devicetests/com/android/testutils/NatPacketForwarderBase.java
new file mode 100644
index 0000000..0a2b5d4
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/NatPacketForwarderBase.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils;
+
+import static com.android.testutils.PacketReflector.IPPROTO_TCP;
+import static com.android.testutils.PacketReflector.IPPROTO_UDP;
+import static com.android.testutils.PacketReflector.IPV4_HEADER_LENGTH;
+import static com.android.testutils.PacketReflector.IPV6_HEADER_LENGTH;
+import static com.android.testutils.PacketReflector.IPV6_PROTO_OFFSET;
+import static com.android.testutils.PacketReflector.TCP_HEADER_LENGTH;
+import static com.android.testutils.PacketReflector.UDP_HEADER_LENGTH;
+
+import android.annotation.NonNull;
+import android.net.TestNetworkInterface;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.util.Log;
+
+import androidx.annotation.GuardedBy;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.util.Objects;
+
+/**
+ * A class that forwards packets from a {@link TestNetworkInterface} to another
+ * {@link TestNetworkInterface} with NAT.
+ *
+ * For testing purposes, a {@link TestNetworkInterface} provides a {@link FileDescriptor}
+ * which allows content injection on the test network. However, this could be hard to use
+ * because the callers need to compose IP packets in order to inject content to the
+ * test network.
+ *
+ * In order to remove the need of composing the IP packets, this class forwards IP packets to
+ * the {@link FileDescriptor} of another {@link TestNetworkInterface} instance. Thus,
+ * the TCP/IP headers could be parsed/composed automatically by the protocol stack of this
+ * additional {@link TestNetworkInterface}, while the payload is supplied by the
+ * servers run on the interface.
+ *
+ * To make it work, an internal interface and an external interface are defined, where
+ * the client might send packets from the internal interface which are originated from
+ * multiple addresses to a server that listens on the external address.
+ *
+ * When forwarding the outgoing packet on the internal interface, a simple NAT mechanism
+ * is implemented during forwarding, which will swap the source and destination,
+ * but replacing the source address with the external address,
+ * e.g. 192.168.1.1:1234 -> 8.8.8.8:80 will be translated into 8.8.8.8:1234 -> 1.2.3.4:80.
+ *
+ * For the above example, a client who sends http request will have a hallucination that
+ * it is talking to a remote server at 8.8.8.8. Also, the server listens on 1.2.3.4 will
+ * have a different hallucination that the request is sent from a remote client at 8.8.8.8,
+ * to a local address 1.2.3.4.
+ *
+ * And a NAT mapping is created at the time when the outgoing packet is forwarded.
+ * With a different internal source port, the instance learned that when a response with the
+ * destination port 1234, it should forward the packet to the internal address 192.168.1.1.
+ *
+ * For the incoming packet received from external interface, for example a http response sent
+ * from the http server, the same mechanism is applied but in a different direction,
+ * where the source and destination will be swapped, and the source address will be replaced
+ * with the internal address, which is obtained from the NAT mapping described above.
+ */
+public abstract class NatPacketForwarderBase extends Thread {
+    private static final String TAG = "NatPacketForwarder";
+    static final int DESTINATION_PORT_OFFSET = 2;
+
+    // The source fd to read packets from.
+    @NonNull
+    final FileDescriptor mSrcFd;
+    // The buffer to temporarily hold the entire packet after receiving.
+    @NonNull
+    final byte[] mBuf;
+    // The destination fd to write packets to.
+    @NonNull
+    final FileDescriptor mDstFd;
+    // The NAT mapping table shared between two NatPacketForwarder instances to map from
+    // the source port to the associated internal address. The map can be read/write from two
+    // different threads on any given time whenever receiving packets on the
+    // {@link TestNetworkInterface}. Thus, synchronize on the object when reading/writing is needed.
+    @GuardedBy("mNatMap")
+    @NonNull
+    final PacketBridge.NatMap mNatMap;
+    // The address of the external interface. See {@link NatPacketForwarder}.
+    @NonNull
+    final InetAddress mExtAddr;
+
+    /**
+     * Construct a {@link NatPacketForwarderBase}.
+     *
+     * This class reads packets from {@code srcFd} of a {@link TestNetworkInterface}, and
+     * forwards them to the {@code dstFd} of another {@link TestNetworkInterface} with
+     * NAT applied. See {@link NatPacketForwarderBase}.
+     *
+     * To apply NAT, the address of the external interface needs to be supplied through
+     * {@code extAddr} to identify the external interface. And a shared NAT mapping table,
+     * {@code natMap} is needed to be shared between these two instances.
+     *
+     * Note that this class is not useful if the instance is not managed by a
+     * {@link PacketBridge} to set up a two-way communication.
+     *
+     * @param srcFd   {@link FileDescriptor} to read packets from.
+     * @param mtu     MTU of the test network.
+     * @param dstFd   {@link FileDescriptor} to write packets to.
+     * @param extAddr the external address, which is the address of the external interface.
+     *                See {@link NatPacketForwarderBase}.
+     * @param natMap  the NAT mapping table shared between two {@link NatPacketForwarderBase}
+     *                instance.
+     */
+    public NatPacketForwarderBase(@NonNull FileDescriptor srcFd, int mtu,
+            @NonNull FileDescriptor dstFd, @NonNull InetAddress extAddr,
+            @NonNull PacketBridge.NatMap natMap) {
+        super(TAG);
+        mSrcFd = Objects.requireNonNull(srcFd);
+        mBuf = new byte[mtu];
+        mDstFd = Objects.requireNonNull(dstFd);
+        mExtAddr = Objects.requireNonNull(extAddr);
+        mNatMap = Objects.requireNonNull(natMap);
+    }
+
+    /**
+     * A method to prepare forwarding packets between two instances of {@link TestNetworkInterface},
+     * which includes re-write addresses, ports and fix up checksums.
+     * Subclasses should override this method to implement a simple NAT.
+     */
+    abstract void preparePacketForForwarding(@NonNull byte[] buf, int len, int version, int proto);
+
+    private void forwardPacket(@NonNull byte[] buf, int len) {
+        try {
+            Os.write(mDstFd, buf, 0, len);
+        } catch (ErrnoException | IOException e) {
+            Log.e(TAG, "Error writing packet: " + e.getMessage());
+        }
+    }
+
+    // Reads one packet from mSrcFd, and writes the packet to the mDstFd for supported protocols.
+    private void processPacket() {
+        final int len = PacketReflectorUtil.readPacket(mSrcFd, mBuf);
+        if (len < 1) {
+            // Usually happens when socket read is being interrupted, e.g. stopping PacketForwarder.
+            return;
+        }
+
+        final int version = mBuf[0] >>> 4;
+        final int protoPos, ipHdrLen;
+        switch (version) {
+            case 4:
+                ipHdrLen = IPV4_HEADER_LENGTH;
+                protoPos = PacketReflector.IPV4_PROTO_OFFSET;
+                break;
+            case 6:
+                ipHdrLen = IPV6_HEADER_LENGTH;
+                protoPos = IPV6_PROTO_OFFSET;
+                break;
+            default:
+                throw new IllegalStateException("Unexpected version: " + version);
+        }
+        if (len < ipHdrLen) {
+            throw new IllegalStateException("Unexpected buffer length: " + len);
+        }
+
+        final byte proto = mBuf[protoPos];
+        final int transportHdrLen;
+        switch (proto) {
+            case IPPROTO_TCP:
+                transportHdrLen = TCP_HEADER_LENGTH;
+                break;
+            case IPPROTO_UDP:
+                transportHdrLen = UDP_HEADER_LENGTH;
+                break;
+            // TODO: Support ICMP.
+            default:
+                return; // Unknown protocol, ignored.
+        }
+
+        if (len < ipHdrLen + transportHdrLen) {
+            throw new IllegalStateException("Unexpected buffer length: " + len);
+        }
+        // Re-write addresses, ports and fix up checksums.
+        preparePacketForForwarding(mBuf, len, version, proto);
+        // Send the packet to the destination fd.
+        forwardPacket(mBuf, len);
+    }
+
+    @Override
+    public void run() {
+        Log.i(TAG, "starting fd=" + mSrcFd + " valid=" + mSrcFd.valid());
+        while (!interrupted() && mSrcFd.valid()) {
+            processPacket();
+        }
+        Log.i(TAG, "exiting fd=" + mSrcFd + " valid=" + mSrcFd.valid());
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/NetlinkTestUtils.kt b/staticlibs/testutils/devicetests/com/android/testutils/NetlinkTestUtils.kt
new file mode 100644
index 0000000..3f5460b
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/NetlinkTestUtils.kt
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:JvmName("NetlinkTestUtils")
+
+package com.android.testutils
+
+import com.android.net.module.util.netlink.NetlinkConstants.RTM_DELNEIGH
+import com.android.net.module.util.netlink.NetlinkConstants.RTM_NEWNEIGH
+import libcore.util.HexEncoding
+import libcore.util.HexEncoding.encodeToString
+import java.net.Inet6Address
+import java.net.InetAddress
+
+private const val VRRP_MAC_ADDR = "00005e000164"
+
+/**
+ * Make a RTM_NEWNEIGH netlink message.
+ */
+@JvmOverloads
+fun makeNewNeighMessage(
+    neighAddr: InetAddress,
+    nudState: Short,
+    linkLayerAddr: String = VRRP_MAC_ADDR
+) = makeNeighborMessage(
+        neighAddr = neighAddr,
+        type = RTM_NEWNEIGH,
+        nudState = nudState,
+        linkLayerAddr = linkLayerAddr
+)
+
+/**
+ * Make a RTM_DELNEIGH netlink message.
+ */
+fun makeDelNeighMessage(
+    neighAddr: InetAddress,
+    nudState: Short
+) = makeNeighborMessage(
+        neighAddr = neighAddr,
+        type = RTM_DELNEIGH,
+        nudState = nudState
+)
+
+private fun makeNeighborMessage(
+    neighAddr: InetAddress,
+    type: Short,
+    nudState: Short,
+    linkLayerAddr: String = VRRP_MAC_ADDR
+) = HexEncoding.decode(
+    /* ktlint-disable indent */
+    // -- struct nlmsghdr --
+                         // length = 88 or 76:
+    (if (neighAddr is Inet6Address) "58000000" else "4c000000") +
+    type.toLEHex() +     // type
+    "0000" +             // flags
+    "00000000" +         // seqno
+    "00000000" +         // pid (0 == kernel)
+    // struct ndmsg
+                         // family (AF_INET6 or AF_INET)
+    (if (neighAddr is Inet6Address) "0a" else "02") +
+    "00" +               // pad1
+    "0000" +             // pad2
+    "15000000" +         // interface index (21 == wlan0, on test device)
+    nudState.toLEHex() + // NUD state
+    "00" +               // flags
+    "01" +               // type
+    // -- struct nlattr: NDA_DST --
+                         // length = 20 or 8:
+    (if (neighAddr is Inet6Address) "1400" else "0800") +
+    "0100" +             // type (1 == NDA_DST, for neighbor messages)
+                         // IP address:
+    encodeToString(neighAddr.address) +
+    // -- struct nlattr: NDA_LLADDR --
+    "0a00" +             // length = 10
+    "0200" +             // type (2 == NDA_LLADDR, for neighbor messages)
+    linkLayerAddr +      // MAC Address(default == 00:00:5e:00:01:64)
+    "0000" +             // padding, for 4 byte alignment
+    // -- struct nlattr: NDA_PROBES --
+    "0800" +             // length = 8
+    "0400" +             // type (4 == NDA_PROBES, for neighbor messages)
+    "01000000" +         // number of probes
+    // -- struct nlattr: NDA_CACHEINFO --
+    "1400" +             // length = 20
+    "0300" +             // type (3 == NDA_CACHEINFO, for neighbor messages)
+    "05190000" +         // ndm_used, as "clock ticks ago"
+    "05190000" +         // ndm_confirmed, as "clock ticks ago"
+    "190d0000" +         // ndm_updated, as "clock ticks ago"
+    "00000000",          // ndm_refcnt
+    false /* allowSingleChar */)
+    /* ktlint-enable indent */
+
+/**
+ * Convert a [Short] to a little-endian hex string.
+ */
+private fun Short.toLEHex() = String.format("%04x", java.lang.Short.reverseBytes(this))
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/NetworkStatsProviderCbStubCompat.java b/staticlibs/testutils/devicetests/com/android/testutils/NetworkStatsProviderCbStubCompat.java
new file mode 100644
index 0000000..642da7a
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/NetworkStatsProviderCbStubCompat.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils;
+
+import android.net.NetworkStats;
+import android.net.netstats.provider.INetworkStatsProviderCallback;
+import android.os.RemoteException;
+
+/**
+ * A shim class that allows {@link TestableNetworkStatsProviderCbBinder} to be built against
+ * different SDK versions.
+ */
+public class NetworkStatsProviderCbStubCompat extends INetworkStatsProviderCallback.Stub {
+    @Override
+    public void notifyStatsUpdated(int token, NetworkStats ifaceStats, NetworkStats uidStats)
+            throws RemoteException {}
+
+    @Override
+    public void notifyAlertReached() throws RemoteException {}
+
+    /** Added in T. */
+    public void notifyLimitReached() throws RemoteException {}
+
+    /** Added in T. */
+    public void notifyWarningReached() throws RemoteException {}
+
+    /** Added in S, removed in T. */
+    public void notifyWarningOrLimitReached() throws RemoteException {}
+
+    @Override
+    public void unregister() throws RemoteException {}
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/NetworkStatsProviderStubCompat.java b/staticlibs/testutils/devicetests/com/android/testutils/NetworkStatsProviderStubCompat.java
new file mode 100644
index 0000000..a77aa02
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/NetworkStatsProviderStubCompat.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils;
+
+import android.net.netstats.provider.INetworkStatsProvider;
+
+/**
+ * A shim class that allows {@link TestableNetworkStatsProviderBinder} to be built against
+ * different SDK versions.
+ */
+public class NetworkStatsProviderStubCompat extends INetworkStatsProvider.Stub {
+    @Override
+    public void onRequestStatsUpdate(int token) {}
+
+    // Removed and won't be called in S+.
+    public void onSetLimit(String iface, long quotaBytes) {}
+
+    @Override
+    public void onSetAlert(long bytes) {}
+
+    // Added in S.
+    public void onSetWarningAndLimit(String iface, long warningBytes, long limitBytes) {}
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/NetworkStatsUtils.kt b/staticlibs/testutils/devicetests/com/android/testutils/NetworkStatsUtils.kt
new file mode 100644
index 0000000..8324b25
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/NetworkStatsUtils.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import android.net.NetworkStats
+import kotlin.test.assertTrue
+
+@JvmOverloads
+fun orderInsensitiveEquals(
+    leftStats: NetworkStats,
+    rightStats: NetworkStats,
+    compareTime: Boolean = false
+): Boolean {
+    if (leftStats == rightStats) return true
+    if (compareTime && leftStats.getElapsedRealtime() != rightStats.getElapsedRealtime()) {
+        return false
+    }
+
+    // While operations such as add/subtract will preserve empty entries. This will make
+    // the result be hard to verify during test. Remove them before comparing since they
+    // are not really affect correctness.
+    // TODO (b/152827872): Remove empty entries after addition/subtraction.
+    val leftTrimmedEmpty = leftStats.removeEmptyEntries()
+    val rightTrimmedEmpty = rightStats.removeEmptyEntries()
+
+    if (leftTrimmedEmpty.size() != rightTrimmedEmpty.size()) return false
+    val left = NetworkStats.Entry()
+    val right = NetworkStats.Entry()
+    // Order insensitive compare.
+    for (i in 0 until leftTrimmedEmpty.size()) {
+        leftTrimmedEmpty.getValues(i, left)
+        val j: Int = rightTrimmedEmpty.findIndexHinted(left.iface, left.uid, left.set, left.tag,
+                left.metered, left.roaming, left.defaultNetwork, i)
+        if (j == -1) return false
+        rightTrimmedEmpty.getValues(j, right)
+        if (left != right) return false
+    }
+    return true
+}
+
+/**
+ * Assert that two {@link NetworkStats} are equals, assuming the order of the records are not
+ * necessarily the same.
+ *
+ * @note {@code elapsedRealtime} is not compared by default, given that in test cases that is not
+ *       usually used.
+ */
+@JvmOverloads
+fun assertNetworkStatsEquals(
+    expected: NetworkStats,
+    actual: NetworkStats,
+    compareTime: Boolean = false
+) {
+    assertTrue(orderInsensitiveEquals(expected, actual, compareTime),
+            "expected: " + expected + " but was: " + actual)
+}
+
+/**
+ * Assert that after being parceled then unparceled, {@link NetworkStats} is equal to the original
+ * object.
+ */
+fun assertParcelingIsLossless(stats: NetworkStats) {
+    assertParcelingIsLossless(stats, { a, b -> orderInsensitiveEquals(a, b) })
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/NonNullTestUtils.java b/staticlibs/testutils/devicetests/com/android/testutils/NonNullTestUtils.java
new file mode 100644
index 0000000..463c470
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/NonNullTestUtils.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils;
+
+import android.annotation.NonNull;
+
+/**
+ * Utilities to help Kotlin test to verify java @NonNull code
+ */
+public class NonNullTestUtils {
+    /**
+     * This method allows Kotlin to pass nullable to @NonNull java code for testing.
+     * For Foo(@NonNull arg) java method, Kotlin can pass nullable variable by
+     * Foo(NonNullTestUtils.nullUnsafe(nullableVar)).
+     */
+    @NonNull public static <T> T nullUnsafe(T v) {
+        return v;
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/PacketBridge.kt b/staticlibs/testutils/devicetests/com/android/testutils/PacketBridge.kt
new file mode 100644
index 0000000..d50f78a
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/PacketBridge.kt
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import android.content.Context
+import android.net.ConnectivityManager
+import android.net.LinkAddress
+import android.net.LinkProperties
+import android.net.Network
+import android.net.NetworkCapabilities
+import android.net.NetworkRequest
+import android.net.TestNetworkInterface
+import android.net.TestNetworkManager
+import android.net.TestNetworkSpecifier
+import android.os.Binder
+import com.android.testutils.RecorderCallback.CallbackEntry.Available
+import java.net.InetAddress
+import libcore.io.IoUtils
+
+private const val MIN_PORT_NUMBER = 1025
+private const val MAX_PORT_NUMBER = 65535
+
+/**
+ * A class that set up two {@link TestNetworkInterface} with NAT, and forward packets between them.
+ *
+ * See {@link NatPacketForwarder} for more detailed information.
+ */
+class PacketBridge(
+    context: Context,
+    internalAddr: LinkAddress,
+    externalAddr: LinkAddress,
+    dnsAddr: InetAddress
+) {
+    private val natMap = NatMap()
+    private val binder = Binder()
+
+    private val cm = context.getSystemService(ConnectivityManager::class.java)!!
+    private val tnm = context.getSystemService(TestNetworkManager::class.java)!!
+
+    // Create test networks.
+    private val internalIface = tnm.createTunInterface(listOf(internalAddr))
+    private val externalIface = tnm.createTunInterface(listOf(externalAddr))
+
+    // Register test networks to ConnectivityService.
+    private val internalNetworkCallback: TestableNetworkCallback
+    private val externalNetworkCallback: TestableNetworkCallback
+    val internalNetwork: Network
+    val externalNetwork: Network
+    init {
+        val (inCb, inNet) = createTestNetwork(internalIface, internalAddr, dnsAddr)
+        val (exCb, exNet) = createTestNetwork(externalIface, externalAddr, dnsAddr)
+        internalNetworkCallback = inCb
+        externalNetworkCallback = exCb
+        internalNetwork = inNet
+        externalNetwork = exNet
+    }
+
+    // Setup the packet bridge.
+    private val internalFd = internalIface.fileDescriptor.fileDescriptor
+    private val externalFd = externalIface.fileDescriptor.fileDescriptor
+
+    private val pr1 = NatInternalPacketForwarder(
+        internalFd,
+        1500,
+        externalFd,
+        externalAddr.address,
+        natMap
+    )
+    private val pr2 = NatExternalPacketForwarder(
+        externalFd,
+        1500,
+        internalFd,
+        externalAddr.address,
+        natMap
+    )
+
+    fun start() {
+        IoUtils.setBlocking(internalFd, true /* blocking */)
+        IoUtils.setBlocking(externalFd, true /* blocking */)
+        pr1.start()
+        pr2.start()
+    }
+
+    fun stop() {
+        pr1.interrupt()
+        pr2.interrupt()
+        cm.unregisterNetworkCallback(internalNetworkCallback)
+        cm.unregisterNetworkCallback(externalNetworkCallback)
+    }
+
+    /**
+     * Creates a test network with given test TUN interface and addresses.
+     */
+    private fun createTestNetwork(
+        testIface: TestNetworkInterface,
+        addr: LinkAddress,
+        dnsAddr: InetAddress
+    ): Pair<TestableNetworkCallback, Network> {
+        // Make a network request to hold the test network
+        val nr = NetworkRequest.Builder()
+            .clearCapabilities()
+            .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
+            .setNetworkSpecifier(TestNetworkSpecifier(testIface.interfaceName))
+            .build()
+        val testCb = TestableNetworkCallback()
+        cm.requestNetwork(nr, testCb)
+
+        val lp = LinkProperties().apply {
+            addLinkAddress(addr)
+            interfaceName = testIface.interfaceName
+            addDnsServer(dnsAddr)
+        }
+        tnm.setupTestNetwork(lp, true /* isMetered */, binder)
+
+        // Wait for available before return.
+        val network = testCb.expect<Available>().network
+        return testCb to network
+    }
+
+    /**
+     * A helper class to maintain the mappings between internal addresses/ports and external
+     * ports.
+     *
+     * This class assigns an unused external port number if the mapping between
+     * srcaddress:srcport:protocol and the external port does not exist yet.
+     *
+     * Note that this class is not thread-safe. The instance of the class needs to be
+     * synchronized in the callers when being used in multiple threads.
+     */
+    class NatMap {
+        data class AddressInfo(val address: InetAddress, val port: Int, val protocol: Int)
+
+        private val mToExternalPort = HashMap<AddressInfo, Int>()
+        private val mFromExternalPort = HashMap<Int, AddressInfo>()
+
+        // Skip well-known port 0~1024.
+        private var nextExternalPort = MIN_PORT_NUMBER
+
+        fun toExternalPort(addr: InetAddress, port: Int, protocol: Int): Int {
+            val info = AddressInfo(addr, port, protocol)
+            val extPort: Int
+            if (!mToExternalPort.containsKey(info)) {
+                extPort = nextExternalPort++
+                if (nextExternalPort > MAX_PORT_NUMBER) {
+                    throw IllegalStateException("Available ports are exhausted")
+                }
+                mToExternalPort[info] = extPort
+                mFromExternalPort[extPort] = info
+            } else {
+                extPort = mToExternalPort[info]!!
+            }
+            return extPort
+        }
+
+        fun fromExternalPort(port: Int): AddressInfo? {
+            return mFromExternalPort[port]
+        }
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/PacketReflector.java b/staticlibs/testutils/devicetests/com/android/testutils/PacketReflector.java
new file mode 100644
index 0000000..69392d4
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/PacketReflector.java
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils;
+
+import static android.system.OsConstants.ICMP6_ECHO_REPLY;
+import static android.system.OsConstants.ICMP6_ECHO_REQUEST;
+
+import android.annotation.NonNull;
+import android.net.TestNetworkInterface;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.util.Log;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.util.Objects;
+
+/**
+ * A class that echoes packets received on a {@link TestNetworkInterface} back to itself.
+ *
+ * For testing purposes, sometimes a mocked environment to simulate a simple echo from the
+ * server side is needed. This is particularly useful if the test, e.g. VpnTest, is
+ * heavily relying on the outside world.
+ *
+ * This class reads packets from the {@link FileDescriptor} of a {@link TestNetworkInterface}, and:
+ *   1. For TCP and UDP packets, simply swaps the source address and the destination
+ *      address, then send it back to the {@link FileDescriptor}.
+ *   2. For ICMP ping packets, composes a ping reply and sends it back to the sender.
+ *   3. Ignore all other packets.
+ */
+public class PacketReflector extends Thread {
+
+    static final int IPV4_HEADER_LENGTH = 20;
+    static final int IPV6_HEADER_LENGTH = 40;
+
+    static final int IPV4_ADDR_OFFSET = 12;
+    static final int IPV6_ADDR_OFFSET = 8;
+    static final int IPV4_ADDR_LENGTH = 4;
+    static final int IPV6_ADDR_LENGTH = 16;
+
+    static final int IPV4_PROTO_OFFSET = 9;
+    static final int IPV6_PROTO_OFFSET = 6;
+
+    static final byte IPPROTO_ICMP = 1;
+    static final byte IPPROTO_TCP = 6;
+    static final byte IPPROTO_UDP = 17;
+    private static final byte IPPROTO_ICMPV6 = 58;
+
+    private static final int ICMP_HEADER_LENGTH = 8;
+    static final int TCP_HEADER_LENGTH = 20;
+    static final int UDP_HEADER_LENGTH = 8;
+
+    private static final byte ICMP_ECHO = 8;
+    private static final byte ICMP_ECHOREPLY = 0;
+
+    private static String TAG = "PacketReflector";
+
+    @NonNull
+    private final FileDescriptor mFd;
+    @NonNull
+    private final byte[] mBuf;
+
+    /**
+     * Construct a {@link PacketReflector} from the given {@code fd} of
+     * a {@link TestNetworkInterface}.
+     *
+     * @param fd {@link FileDescriptor} to read/write packets.
+     * @param mtu MTU of the test network.
+     */
+    public PacketReflector(@NonNull FileDescriptor fd, int mtu) {
+        super("PacketReflector");
+        mFd = Objects.requireNonNull(fd);
+        mBuf = new byte[mtu];
+    }
+
+    private static void swapBytes(@NonNull byte[] buf, int pos1, int pos2, int len) {
+        for (int i = 0; i < len; i++) {
+            byte b = buf[pos1 + i];
+            buf[pos1 + i] = buf[pos2 + i];
+            buf[pos2 + i] = b;
+        }
+    }
+
+    private static void swapAddresses(@NonNull byte[] buf, int version) {
+        int addrPos, addrLen;
+        switch (version) {
+            case 4:
+                addrPos = IPV4_ADDR_OFFSET;
+                addrLen = IPV4_ADDR_LENGTH;
+                break;
+            case 6:
+                addrPos = IPV6_ADDR_OFFSET;
+                addrLen = IPV6_ADDR_LENGTH;
+                break;
+            default:
+                throw new IllegalArgumentException();
+        }
+        swapBytes(buf, addrPos, addrPos + addrLen, addrLen);
+    }
+
+    // Reflect TCP packets: swap the source and destination addresses, but don't change the ports.
+    // This is used by the test to "connect to itself" through the VPN.
+    private void processTcpPacket(@NonNull byte[] buf, int version, int len, int hdrLen) {
+        if (len < hdrLen + TCP_HEADER_LENGTH) {
+            return;
+        }
+
+        // Swap src and dst IP addresses.
+        swapAddresses(buf, version);
+
+        // Send the packet back.
+        writePacket(buf, len);
+    }
+
+    // Echo UDP packets: swap source and destination addresses, and source and destination ports.
+    // This is used by the test to check that the bytes it sends are echoed back.
+    private void processUdpPacket(@NonNull byte[] buf, int version, int len, int hdrLen) {
+        if (len < hdrLen + UDP_HEADER_LENGTH) {
+            return;
+        }
+
+        // Swap src and dst IP addresses.
+        swapAddresses(buf, version);
+
+        // Swap dst and src ports.
+        int portOffset = hdrLen;
+        swapBytes(buf, portOffset, portOffset + 2, 2);
+
+        // Send the packet back.
+        writePacket(buf, len);
+    }
+
+    private void processIcmpPacket(@NonNull byte[] buf, int version, int len, int hdrLen) {
+        if (len < hdrLen + ICMP_HEADER_LENGTH) {
+            return;
+        }
+
+        byte type = buf[hdrLen];
+        if (!(version == 4 && type == ICMP_ECHO) &&
+                !(version == 6 && type == (byte) ICMP6_ECHO_REQUEST)) {
+            return;
+        }
+
+        // Save the ping packet we received.
+        byte[] request = buf.clone();
+
+        // Swap src and dst IP addresses, and send the packet back.
+        // This effectively pings the device to see if it replies.
+        swapAddresses(buf, version);
+        writePacket(buf, len);
+
+        // The device should have replied, and buf should now contain a ping response.
+        int received = PacketReflectorUtil.readPacket(mFd, buf);
+        if (received != len) {
+            Log.i(TAG, "Reflecting ping did not result in ping response: " +
+                    "read=" + received + " expected=" + len);
+            return;
+        }
+
+        byte replyType = buf[hdrLen];
+        if ((type == ICMP_ECHO && replyType != ICMP_ECHOREPLY)
+                || (type == (byte) ICMP6_ECHO_REQUEST && replyType != (byte) ICMP6_ECHO_REPLY)) {
+            Log.i(TAG, "Received unexpected ICMP reply: original " + type
+                    + ", reply " + replyType);
+            return;
+        }
+
+        // Compare the response we got with the original packet.
+        // The only thing that should have changed are addresses, type and checksum.
+        // Overwrite them with the received bytes and see if the packet is otherwise identical.
+        request[hdrLen] = buf[hdrLen];          // Type
+        request[hdrLen + 2] = buf[hdrLen + 2];  // Checksum byte 1.
+        request[hdrLen + 3] = buf[hdrLen + 3];  // Checksum byte 2.
+
+        // Since Linux kernel 4.2, net.ipv6.auto_flowlabels is set by default, and therefore
+        // the request and reply may have different IPv6 flow label: ignore that as well.
+        if (version == 6) {
+            request[1] = (byte) (request[1] & 0xf0 | buf[1] & 0x0f);
+            request[2] = buf[2];
+            request[3] = buf[3];
+        }
+
+        for (int i = 0; i < len; i++) {
+            if (buf[i] != request[i]) {
+                Log.i(TAG, "Received non-matching packet when expecting ping response.");
+                return;
+            }
+        }
+
+        // Now swap the addresses again and reflect the packet. This sends a ping reply.
+        swapAddresses(buf, version);
+        writePacket(buf, len);
+    }
+
+    private void writePacket(@NonNull byte[] buf, int len) {
+        try {
+            Os.write(mFd, buf, 0, len);
+        } catch (ErrnoException | IOException e) {
+            Log.e(TAG, "Error writing packet: " + e.getMessage());
+        }
+    }
+
+    // Reads one packet from our mFd, and possibly writes the packet back.
+    private void processPacket() {
+        int len = PacketReflectorUtil.readPacket(mFd, mBuf);
+        if (len < 1) {
+            // Usually happens when socket read is being interrupted, e.g. stopping PacketReflector.
+            return;
+        }
+
+        int version = mBuf[0] >> 4;
+        int protoPos, hdrLen;
+        if (version == 4) {
+            hdrLen = IPV4_HEADER_LENGTH;
+            protoPos = IPV4_PROTO_OFFSET;
+        } else if (version == 6) {
+            hdrLen = IPV6_HEADER_LENGTH;
+            protoPos = IPV6_PROTO_OFFSET;
+        } else {
+            throw new IllegalStateException("Unexpected version: " + version);
+        }
+
+        if (len < hdrLen) {
+            throw new IllegalStateException("Unexpected buffer length: " + len);
+        }
+
+        byte proto = mBuf[protoPos];
+        switch (proto) {
+            case IPPROTO_ICMP:
+                // fall through
+            case IPPROTO_ICMPV6:
+                processIcmpPacket(mBuf, version, len, hdrLen);
+                break;
+            case IPPROTO_TCP:
+                processTcpPacket(mBuf, version, len, hdrLen);
+                break;
+            case IPPROTO_UDP:
+                processUdpPacket(mBuf, version, len, hdrLen);
+                break;
+        }
+    }
+
+    public void run() {
+        Log.i(TAG, "starting fd=" + mFd + " valid=" + mFd.valid());
+        while (!interrupted() && mFd.valid()) {
+            processPacket();
+        }
+        Log.i(TAG, "exiting fd=" + mFd + " valid=" + mFd.valid());
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/PacketReflectorUtil.kt b/staticlibs/testutils/devicetests/com/android/testutils/PacketReflectorUtil.kt
new file mode 100644
index 0000000..498b1a3
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/PacketReflectorUtil.kt
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:JvmName("PacketReflectorUtil")
+
+package com.android.testutils
+
+import android.system.ErrnoException
+import android.system.Os
+import android.system.OsConstants
+import com.android.net.module.util.IpUtils
+import com.android.testutils.PacketReflector.IPV4_HEADER_LENGTH
+import com.android.testutils.PacketReflector.IPV6_HEADER_LENGTH
+import java.io.FileDescriptor
+import java.io.InterruptedIOException
+import java.net.InetAddress
+import java.nio.ByteBuffer
+
+fun readPacket(fd: FileDescriptor, buf: ByteArray): Int {
+    return try {
+        Os.read(fd, buf, 0, buf.size)
+    } catch (e: ErrnoException) {
+        // Ignore normal use cases such as the EAGAIN error indicates that the read operation
+        // cannot be completed immediately, or the EINTR error indicates that the read
+        // operation was interrupted by a signal.
+        if (e.errno == OsConstants.EAGAIN || e.errno == OsConstants.EINTR) {
+            -1
+        } else {
+            throw e
+        }
+    } catch (e: InterruptedIOException) {
+        -1
+    }
+}
+
+fun getInetAddressAt(buf: ByteArray, pos: Int, len: Int): InetAddress =
+    InetAddress.getByAddress(buf.copyOfRange(pos, pos + len))
+
+/**
+ * Reads a 16-bit unsigned int at pos in big endian, with no alignment requirements.
+ */
+fun getPortAt(buf: ByteArray, pos: Int): Int {
+    return (buf[pos].toInt() and 0xff shl 8) + (buf[pos + 1].toInt() and 0xff)
+}
+
+fun setPortAt(port: Int, buf: ByteArray, pos: Int) {
+    buf[pos] = (port ushr 8).toByte()
+    buf[pos + 1] = (port and 0xff).toByte()
+}
+
+fun getAddressPositionAndLength(version: Int) = when (version) {
+    4 -> PacketReflector.IPV4_ADDR_OFFSET to PacketReflector.IPV4_ADDR_LENGTH
+    6 -> PacketReflector.IPV6_ADDR_OFFSET to PacketReflector.IPV6_ADDR_LENGTH
+    else -> throw IllegalArgumentException("Unknown IP version $version")
+}
+
+private const val IPV4_CHKSUM_OFFSET = 10
+private const val UDP_CHECKSUM_OFFSET = 6
+private const val TCP_CHECKSUM_OFFSET = 16
+
+fun fixPacketChecksum(buf: ByteArray, len: Int, version: Int, protocol: Byte) {
+    // Fill Ip checksum for IPv4. IPv6 header doesn't have a checksum field.
+    if (version == 4) {
+        val checksum = IpUtils.ipChecksum(ByteBuffer.wrap(buf), 0)
+        // Place checksum in Big-endian order.
+        buf[IPV4_CHKSUM_OFFSET] = (checksum.toInt() ushr 8).toByte()
+        buf[IPV4_CHKSUM_OFFSET + 1] = (checksum.toInt() and 0xff).toByte()
+    }
+
+    // Fill transport layer checksum.
+    val transportOffset = if (version == 4) IPV4_HEADER_LENGTH else IPV6_HEADER_LENGTH
+    when (protocol) {
+        PacketReflector.IPPROTO_UDP -> {
+            val checksumPos = transportOffset + UDP_CHECKSUM_OFFSET
+            // Clear before calculate.
+            buf[checksumPos + 1] = 0x00
+            buf[checksumPos] = buf[checksumPos + 1]
+            val checksum = IpUtils.udpChecksum(
+                ByteBuffer.wrap(buf), 0,
+                transportOffset
+            )
+            buf[checksumPos] = (checksum.toInt() ushr 8).toByte()
+            buf[checksumPos + 1] = (checksum.toInt() and 0xff).toByte()
+        }
+        PacketReflector.IPPROTO_TCP -> {
+            val checksumPos = transportOffset + TCP_CHECKSUM_OFFSET
+            // Clear before calculate.
+            buf[checksumPos + 1] = 0x00
+            buf[checksumPos] = buf[checksumPos + 1]
+            val transportLen: Int = len - transportOffset
+            val checksum = IpUtils.tcpChecksum(
+                ByteBuffer.wrap(buf), 0, transportOffset,
+                transportLen
+            )
+            buf[checksumPos] = (checksum.toInt() ushr 8).toByte()
+            buf[checksumPos + 1] = (checksum.toInt() and 0xff).toByte()
+        }
+        // TODO: Support ICMP.
+        else -> throw IllegalArgumentException("Unsupported protocol: $protocol")
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/PacketResponder.kt b/staticlibs/testutils/devicetests/com/android/testutils/PacketResponder.kt
new file mode 100644
index 0000000..964c6c6
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/PacketResponder.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import java.util.function.Predicate
+
+private const val POLL_FREQUENCY_MS = 1000L
+
+/**
+ * A class that can be used to reply to packets from a [TapPacketReader].
+ *
+ * A reply thread will be created to reply to incoming packets asynchronously.
+ * The receiver creates a new read head on the [TapPacketReader], to read packets, so it does not
+ * affect packets obtained through [TapPacketReader.popPacket].
+ *
+ * @param reader a [TapPacketReader] to obtain incoming packets and reply to them.
+ * @param packetFilter A filter to apply to incoming packets.
+ * @param name Name to use for the internal responder thread.
+ */
+abstract class PacketResponder(
+    private val reader: TapPacketReader,
+    private val packetFilter: Predicate<ByteArray>,
+    name: String
+) {
+    private val replyThread = ReplyThread(name)
+
+    protected abstract fun replyToPacket(packet: ByteArray, reader: TapPacketReader)
+
+    /**
+     * Start the [PacketResponder].
+     */
+    fun start() {
+        replyThread.start()
+    }
+
+    /**
+     * Stop the [PacketResponder].
+     *
+     * The responder cannot be used anymore after being stopped.
+     */
+    fun stop() {
+        replyThread.interrupt()
+        replyThread.join()
+    }
+
+    private inner class ReplyThread(name: String) : Thread(name) {
+        override fun run() {
+            try {
+                // Create a new ReadHead so other packets polled on the reader are not affected
+                val recvPackets = reader.receivedPackets.newReadHead()
+                while (!isInterrupted) {
+                    recvPackets.poll(POLL_FREQUENCY_MS, packetFilter::test)?.let {
+                        replyToPacket(it, reader)
+                    }
+                }
+            } catch (e: InterruptedException) {
+                // Exit gracefully
+            }
+        }
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/ParcelUtils.kt b/staticlibs/testutils/devicetests/com/android/testutils/ParcelUtils.kt
new file mode 100644
index 0000000..14ed8e9
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/ParcelUtils.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:JvmName("ParcelUtils")
+
+package com.android.testutils
+
+import android.os.Parcel
+import android.os.Parcelable
+import kotlin.test.assertTrue
+import kotlin.test.fail
+
+/**
+ * Return a new instance of `T` after being parceled then unparceled.
+ */
+fun <T : Parcelable> parcelingRoundTrip(source: T): T {
+    val creator: Parcelable.Creator<T>
+    try {
+        creator = source.javaClass.getField("CREATOR").get(null) as Parcelable.Creator<T>
+    } catch (e: IllegalAccessException) {
+        fail("Missing CREATOR field: " + e.message)
+    } catch (e: NoSuchFieldException) {
+        fail("Missing CREATOR field: " + e.message)
+    }
+
+    var p = Parcel.obtain()
+    source.writeToParcel(p, /* flags */ 0)
+    p.setDataPosition(0)
+    val marshalled = p.marshall()
+    p = Parcel.obtain()
+    p.unmarshall(marshalled, 0, marshalled.size)
+    p.setDataPosition(0)
+    return creator.createFromParcel(p)
+}
+
+/**
+ * Assert that after being parceled then unparceled, `source` is equal to the original
+ * object. If a customized equals function is provided, uses the provided one.
+ */
+@JvmOverloads
+fun <T : Parcelable> assertParcelingIsLossless(
+    source: T,
+    equals: (T, T) -> Boolean = { a, b -> a == b }
+) {
+    val actual = parcelingRoundTrip(source)
+    assertTrue(equals(source, actual), "Expected $source, but was $actual")
+}
+
+@JvmOverloads
+fun <T : Parcelable> assertParcelSane(
+    obj: T,
+    fieldCount: Int,
+    equals: (T, T) -> Boolean = { a, b -> a == b }
+) {
+    assertFieldCountEquals(fieldCount, obj::class.java)
+    assertParcelingIsLossless(obj, equals)
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/RouterAdvertisementResponder.java b/staticlibs/testutils/devicetests/com/android/testutils/RouterAdvertisementResponder.java
new file mode 100644
index 0000000..51d57bc
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/RouterAdvertisementResponder.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils;
+
+import static android.system.OsConstants.IPPROTO_ICMPV6;
+
+import static com.android.net.module.util.NetworkStackConstants.ETHER_TYPE_IPV6;
+import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ND_OPTION_SLLA;
+import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ND_OPTION_TLLA;
+import static com.android.net.module.util.NetworkStackConstants.ICMPV6_NEIGHBOR_SOLICITATION;
+import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ROUTER_SOLICITATION;
+import static com.android.net.module.util.NetworkStackConstants.IPV6_ADDR_ALL_NODES_MULTICAST;
+import static com.android.net.module.util.NetworkStackConstants.NEIGHBOR_ADVERTISEMENT_FLAG_OVERRIDE;
+import static com.android.net.module.util.NetworkStackConstants.NEIGHBOR_ADVERTISEMENT_FLAG_ROUTER;
+import static com.android.net.module.util.NetworkStackConstants.NEIGHBOR_ADVERTISEMENT_FLAG_SOLICITED;
+import static com.android.net.module.util.NetworkStackConstants.PIO_FLAG_AUTONOMOUS;
+import static com.android.net.module.util.NetworkStackConstants.PIO_FLAG_ON_LINK;
+
+import android.net.InetAddresses;
+import android.net.IpPrefix;
+import android.net.MacAddress;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Pair;
+
+import com.android.net.module.util.Ipv6Utils;
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.structs.EthernetHeader;
+import com.android.net.module.util.structs.Icmpv6Header;
+import com.android.net.module.util.structs.Ipv6Header;
+import com.android.net.module.util.structs.LlaOption;
+import com.android.net.module.util.structs.NsHeader;
+import com.android.net.module.util.structs.PrefixInformationOption;
+import com.android.net.module.util.structs.RdnssOption;
+
+import java.io.IOException;
+import java.net.Inet6Address;
+import java.nio.ByteBuffer;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Random;
+
+/**
+ * ND (RA & NA) responder class useful for tests that require a provisioned IPv6 interface.
+ * TODO: rename to NdResponder
+ */
+public class RouterAdvertisementResponder extends PacketResponder {
+    private static final String TAG = "RouterAdvertisementResponder";
+    private static final Inet6Address DNS_SERVER =
+            (Inet6Address) InetAddresses.parseNumericAddress("2001:4860:4860::64");
+    private final TapPacketReader mPacketReader;
+    // Maps IPv6 address to MacAddress and isRouter boolean.
+    private final Map<Inet6Address, Pair<MacAddress, Boolean>> mNeighborMap = new ArrayMap<>();
+    private final IpPrefix mPrefix;
+
+    public RouterAdvertisementResponder(TapPacketReader packetReader, IpPrefix prefix) {
+        super(packetReader, RouterAdvertisementResponder::isRsOrNs, TAG);
+        mPacketReader = packetReader;
+        mPrefix = Objects.requireNonNull(prefix);
+    }
+
+    public RouterAdvertisementResponder(TapPacketReader packetReader) {
+        this(packetReader, makeRandomPrefix());
+    }
+
+    private static IpPrefix makeRandomPrefix() {
+        final byte[] prefixBytes = new IpPrefix("2001:db8::/64").getAddress().getAddress();
+        final Random r = new Random();
+        for (int i = 4; i < 8; i++) {
+            prefixBytes[i] = (byte) r.nextInt();
+        }
+        return new IpPrefix(prefixBytes, 64);
+    }
+
+    /** Returns true if the packet is a router solicitation or neighbor solicitation message. */
+    private static boolean isRsOrNs(byte[] packet) {
+        final ByteBuffer buffer = ByteBuffer.wrap(packet);
+        final EthernetHeader ethHeader = Struct.parse(EthernetHeader.class, buffer);
+        if (ethHeader.etherType != ETHER_TYPE_IPV6) {
+            return false;
+        }
+        final Ipv6Header ipv6Header = Struct.parse(Ipv6Header.class, buffer);
+        if (ipv6Header.nextHeader != IPPROTO_ICMPV6) {
+            return false;
+        }
+        final Icmpv6Header icmpv6Header = Struct.parse(Icmpv6Header.class, buffer);
+        return icmpv6Header.type == ICMPV6_ROUTER_SOLICITATION
+            || icmpv6Header.type == ICMPV6_NEIGHBOR_SOLICITATION;
+    }
+
+    /**
+     * Adds a new router to be advertised.
+     * @param mac the mac address of the router.
+     * @param ip the link-local address of the router.
+     */
+    public void addRouterEntry(MacAddress mac, Inet6Address ip) {
+        mNeighborMap.put(ip, new Pair<>(mac, true));
+    }
+
+    /**
+     * Adds a new neighbor to be advertised.
+     * @param mac the mac address of the neighbor.
+     * @param ip the link-local address of the neighbor.
+     */
+    public void addNeighborEntry(MacAddress mac, Inet6Address ip) {
+        mNeighborMap.put(ip, new Pair<>(mac, false));
+    }
+
+    /**
+     * @return the prefix that is announced in the Router Advertisements sent by this object.
+     */
+    public IpPrefix getPrefix() {
+        return mPrefix;
+    }
+
+    private ByteBuffer buildPrefixOption() {
+        return PrefixInformationOption.build(
+                mPrefix, (byte) (PIO_FLAG_ON_LINK | PIO_FLAG_AUTONOMOUS),
+                3600 /* valid lifetime */, 3600 /* preferred lifetime */);
+    }
+
+    private ByteBuffer buildRdnssOption() {
+        return RdnssOption.build(3600/*lifetime, must be at least 120*/, DNS_SERVER);
+    }
+
+    private ByteBuffer buildSllaOption(MacAddress srcMac) {
+        return LlaOption.build((byte) ICMPV6_ND_OPTION_SLLA, srcMac);
+    }
+
+    private ByteBuffer buildRaPacket(MacAddress srcMac, MacAddress dstMac, Inet6Address srcIp) {
+        return Ipv6Utils.buildRaPacket(srcMac, dstMac, srcIp, IPV6_ADDR_ALL_NODES_MULTICAST,
+                (byte) 0 /*M=0, O=0*/, 3600 /*lifetime*/, 0 /*reachableTime, unspecified*/,
+                0/*retransTimer, unspecified*/, buildPrefixOption(), buildRdnssOption(),
+                buildSllaOption(srcMac));
+    }
+
+    private static void sendResponse(TapPacketReader reader, ByteBuffer buffer) {
+        try {
+            reader.sendResponse(buffer);
+        } catch (IOException e) {
+            // Throwing an exception here will crash the test process. Let's stick to logging, as
+            // the test will fail either way.
+            Log.e(TAG, "Failed to send buffer", e);
+        }
+    }
+
+    private void replyToRouterSolicitation(TapPacketReader reader, MacAddress dstMac) {
+        for (Map.Entry<Inet6Address, Pair<MacAddress, Boolean>> it : mNeighborMap.entrySet()) {
+            final boolean isRouter = it.getValue().second;
+            if (!isRouter) {
+                continue;
+            }
+            final ByteBuffer raResponse = buildRaPacket(it.getValue().first, dstMac, it.getKey());
+            sendResponse(reader, raResponse);
+        }
+    }
+
+    private void replyToNeighborSolicitation(TapPacketReader reader, MacAddress dstMac,
+            Inet6Address dstIp, Inet6Address targetIp) {
+        final Pair<MacAddress, Boolean> neighbor = mNeighborMap.get(targetIp);
+        if (neighbor == null) {
+            return;
+        }
+
+        final MacAddress srcMac = neighbor.first;
+        final boolean isRouter = neighbor.second;
+        int flags = NEIGHBOR_ADVERTISEMENT_FLAG_SOLICITED | NEIGHBOR_ADVERTISEMENT_FLAG_OVERRIDE;
+        if (isRouter) {
+            flags |= NEIGHBOR_ADVERTISEMENT_FLAG_ROUTER;
+        }
+
+        final ByteBuffer tlla = LlaOption.build((byte) ICMPV6_ND_OPTION_TLLA, srcMac);
+        final ByteBuffer naResponse = Ipv6Utils.buildNaPacket(srcMac, dstMac, targetIp, dstIp,
+                flags, targetIp, tlla);
+        sendResponse(reader, naResponse);
+    }
+
+    @Override
+    protected void replyToPacket(byte[] packet, TapPacketReader reader) {
+        final ByteBuffer buf = ByteBuffer.wrap(packet);
+        // Messages are filtered by parent class, so it is safe to assume that packet is either an
+        // RS or NS.
+        final EthernetHeader ethHdr = Struct.parse(EthernetHeader.class, buf);
+        final Ipv6Header ipv6Hdr = Struct.parse(Ipv6Header.class, buf);
+        final Icmpv6Header icmpv6Header = Struct.parse(Icmpv6Header.class, buf);
+
+        if (icmpv6Header.type == ICMPV6_ROUTER_SOLICITATION) {
+            replyToRouterSolicitation(reader, ethHdr.srcMac);
+        } else if (icmpv6Header.type == ICMPV6_NEIGHBOR_SOLICITATION) {
+            final NsHeader nsHeader = Struct.parse(NsHeader.class, buf);
+            replyToNeighborSolicitation(reader, ethHdr.srcMac, ipv6Hdr.srcIp, nsHeader.target);
+        }
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/TapPacketReader.java b/staticlibs/testutils/devicetests/com/android/testutils/TapPacketReader.java
new file mode 100644
index 0000000..b25b9f2
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/TapPacketReader.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils;
+
+import android.os.Handler;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.net.module.util.ArrayTrackRecord;
+import com.android.net.module.util.PacketReader;
+
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.function.Predicate;
+
+import kotlin.Lazy;
+import kotlin.LazyKt;
+
+/**
+ * A packet reader that runs on a TAP interface.
+ *
+ * It also implements facilities to reply to received packets.
+ */
+public class TapPacketReader extends PacketReader {
+    private final FileDescriptor mTapFd;
+    private final ArrayTrackRecord<byte[]> mReceivedPackets = new ArrayTrackRecord<>();
+    private final Lazy<ArrayTrackRecord<byte[]>.ReadHead> mReadHead =
+            LazyKt.lazy(mReceivedPackets::newReadHead);
+
+    public TapPacketReader(Handler h, FileDescriptor tapFd, int maxPacketSize) {
+        super(h, maxPacketSize);
+        mTapFd = tapFd;
+    }
+
+
+    /**
+     * Attempt to start the FdEventsReader on its handler thread.
+     *
+     * As opposed to {@link android.net.util.FdEventsReader#start()}, this method will not report
+     * failure to start, so it is only appropriate in tests that will fail later if that happens.
+     */
+    public void startAsyncForTest() {
+        getHandler().post(this::start);
+    }
+
+    @Override
+    protected FileDescriptor createFd() {
+        return mTapFd;
+    }
+
+    @Override
+    protected void handlePacket(byte[] recvbuf, int length) {
+        final byte[] newPacket = Arrays.copyOf(recvbuf, length);
+        if (!mReceivedPackets.add(newPacket)) {
+            throw new AssertionError("More than " + Integer.MAX_VALUE + " packets outstanding!");
+        }
+    }
+
+    /**
+     * @deprecated This method does not actually "pop" (which generally means the last packet).
+     * Use {@link #poll(long)}, which has the same behavior, instead.
+     */
+    @Nullable
+    @Deprecated
+    public byte[] popPacket(long timeoutMs) {
+        return poll(timeoutMs);
+    }
+
+    /**
+     * @deprecated This method does not actually "pop" (which generally means the last packet).
+     * Use {@link #poll(long, Predicate)}, which has the same behavior, instead.
+     */
+    @Nullable
+    @Deprecated
+    public byte[] popPacket(long timeoutMs, @NonNull Predicate<byte[]> filter) {
+        return poll(timeoutMs, filter);
+    }
+
+    /**
+     * Get the next packet that was received on the interface.
+     */
+    @Nullable
+    public byte[] poll(long timeoutMs) {
+        return mReadHead.getValue().poll(timeoutMs, packet -> true);
+    }
+
+    /**
+     * Get the next packet that was received on the interface and matches the specified filter.
+     */
+    @Nullable
+    public byte[] poll(long timeoutMs, @NonNull Predicate<byte[]> filter) {
+        return mReadHead.getValue().poll(timeoutMs, filter::test);
+    }
+
+    /**
+     * Get the {@link ArrayTrackRecord} that records all packets received by the reader since its
+     * creation.
+     */
+    public ArrayTrackRecord<byte[]> getReceivedPackets() {
+        return mReceivedPackets;
+    }
+
+    /*
+     * Send a response on the TAP interface.
+     *
+     * The passed ByteBuffer is flipped after use.
+     *
+     * @param packet The packet to send.
+     * @throws IOException if the interface can't be written to.
+     */
+    public void sendResponse(final ByteBuffer packet) throws IOException {
+        try (FileOutputStream out = new FileOutputStream(mTapFd)) {
+            byte[] packetBytes = new byte[packet.limit()];
+            packet.get(packetBytes);
+            packet.flip();  // So we can reuse it in the future.
+            out.write(packetBytes);
+        }
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/TapPacketReaderRule.kt b/staticlibs/testutils/devicetests/com/android/testutils/TapPacketReaderRule.kt
new file mode 100644
index 0000000..701666c
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/TapPacketReaderRule.kt
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import android.Manifest.permission.MANAGE_TEST_NETWORKS
+import android.net.TestNetworkInterface
+import android.net.TestNetworkManager
+import android.os.Handler
+import android.os.HandlerThread
+import androidx.test.platform.app.InstrumentationRegistry
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
+import kotlin.test.assertFalse
+import kotlin.test.fail
+
+private const val HANDLER_TIMEOUT_MS = 10_000L
+
+/**
+ * A [TestRule] that sets up a [TapPacketReader] on a [TestNetworkInterface] for use in the test.
+ *
+ * @param maxPacketSize Maximum size of packets read in the [TapPacketReader] buffer.
+ * @param autoStart Whether to initialize the interface and start the reader automatically for every
+ *                  test. If false, each test must either call start() and stop(), or be annotated
+ *                  with TapPacketReaderTest before using the reader or interface.
+ */
+class TapPacketReaderRule @JvmOverloads constructor(
+    private val maxPacketSize: Int = 1500,
+    private val autoStart: Boolean = true
+) : TestRule {
+    // Use lateinit as the below members can't be initialized in the rule constructor (the
+    // InstrumentationRegistry may not be ready), but from the point of view of test cases using
+    // this rule with autoStart = true, the members are always initialized (in setup/test/teardown):
+    // tests cases should be able use them directly.
+    // lateinit also allows getting good exceptions detailing what went wrong if the members are
+    // referenced before they could be initialized (typically if autoStart is false and the test
+    // does not call start or use @TapPacketReaderTest).
+    lateinit var iface: TestNetworkInterface
+    lateinit var reader: TapPacketReader
+
+    @Volatile
+    private var readerRunning = false
+
+    /**
+     * Indicates that the [TapPacketReaderRule] should initialize its [TestNetworkInterface] and
+     * start the [TapPacketReader] before the test, and tear them down afterwards.
+     *
+     * For use when [TapPacketReaderRule] is created with autoStart = false.
+     */
+    annotation class TapPacketReaderTest
+
+    /**
+     * Initialize the tap interface and start the [TapPacketReader].
+     *
+     * Tests using this method must also call [stop] before exiting.
+     * @param handler Handler to run the reader on. Callers are responsible for safely terminating
+     *                the handler when the test ends. If null, a handler thread managed by the
+     *                rule will be used.
+     */
+    @JvmOverloads
+    fun start(handler: Handler? = null) {
+        if (this::iface.isInitialized) {
+            fail("${TapPacketReaderRule::class.java.simpleName} was already started")
+        }
+
+        val ctx = InstrumentationRegistry.getInstrumentation().context
+        iface = runAsShell(MANAGE_TEST_NETWORKS) {
+            val tnm = ctx.getSystemService(TestNetworkManager::class.java)
+                    ?: fail("Could not obtain the TestNetworkManager")
+            tnm.createTapInterface()
+        }
+        val usedHandler = handler ?: HandlerThread(
+                TapPacketReaderRule::class.java.simpleName).apply { start() }.threadHandler
+        reader = TapPacketReader(usedHandler, iface.fileDescriptor.fileDescriptor, maxPacketSize)
+        reader.startAsyncForTest()
+        readerRunning = true
+    }
+
+    /**
+     * Stop the [TapPacketReader].
+     *
+     * Tests calling [start] must call this method before exiting. If a handler was specified in
+     * [start], all messages on that handler must also be processed after calling this method and
+     * before exiting.
+     *
+     * If [start] was not called, calling this method is a no-op.
+     */
+    fun stop() {
+        // The reader may not be initialized if the test case did not use the rule, even though
+        // other test cases in the same class may be using it (so test classes may call stop in
+        // tearDown even if start is not called for all test cases).
+        if (!this::reader.isInitialized) return
+        reader.handler.post {
+            reader.stop()
+            readerRunning = false
+        }
+    }
+
+    override fun apply(base: Statement, description: Description): Statement {
+        return TapReaderStatement(base, description)
+    }
+
+    private inner class TapReaderStatement(
+        private val base: Statement,
+        private val description: Description
+    ) : Statement() {
+        override fun evaluate() {
+            val shouldStart = autoStart ||
+                    description.getAnnotation(TapPacketReaderTest::class.java) != null
+            if (shouldStart) {
+                start()
+            }
+
+            try {
+                base.evaluate()
+            } finally {
+                if (shouldStart) {
+                    stop()
+                    reader.handler.looper.apply {
+                        quitSafely()
+                        thread.join(HANDLER_TIMEOUT_MS)
+                        assertFalse(thread.isAlive,
+                                "HandlerThread did not exit within $HANDLER_TIMEOUT_MS ms")
+                    }
+                }
+
+                if (this@TapPacketReaderRule::iface.isInitialized) {
+                    iface.fileDescriptor.close()
+                }
+            }
+
+            assertFalse(readerRunning,
+                    "stop() was not called, or the provided handler did not process the stop " +
+                    "message before the test ended. If not using autostart, make sure to call " +
+                    "stop() after the test. If a handler is specified in start(), make sure all " +
+                    "messages are processed after calling stop(), before quitting (for example " +
+                    "by using HandlerThread#quitSafely and HandlerThread#join).")
+        }
+    }
+}
\ No newline at end of file
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/TestBpfMap.java b/staticlibs/testutils/devicetests/com/android/testutils/TestBpfMap.java
new file mode 100644
index 0000000..733bd98
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/TestBpfMap.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils;
+
+import android.system.ErrnoException;
+
+import androidx.annotation.NonNull;
+
+import com.android.net.module.util.IBpfMap;
+import com.android.net.module.util.Struct;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ *
+ * Fake BPF map class for tests that have no privilege to access real BPF maps. TestBpfMap does not
+ * load JNI and all member functions do not access real BPF maps.
+ *
+ * Implements IBpfMap so that any class using IBpfMap can use this class in its tests.
+ *
+ * @param <K> the key type
+ * @param <V> the value type
+ */
+public class TestBpfMap<K extends Struct, V extends Struct> implements IBpfMap<K, V> {
+    private final ConcurrentHashMap<K, V> mMap = new ConcurrentHashMap<>();
+
+    // TODO: Remove this constructor
+    public TestBpfMap(final Class<K> key, final Class<V> value) {
+    }
+
+    @Override
+    public void forEach(ThrowingBiConsumer<K, V> action) throws ErrnoException {
+        // TODO: consider using mocked #getFirstKey and #getNextKey to iterate. It helps to
+        // implement the entry deletion in the iteration if required.
+        for (Map.Entry<K, V> entry : mMap.entrySet()) {
+            action.accept(entry.getKey(), entry.getValue());
+        }
+    }
+
+    @Override
+    public void updateEntry(K key, V value) throws ErrnoException {
+        mMap.put(key, value);
+    }
+
+    @Override
+    public void insertEntry(K key, V value) throws ErrnoException,
+            IllegalArgumentException {
+        // The entry is created if and only if it doesn't exist. See BpfMap#insertEntry.
+        if (mMap.get(key) != null) {
+            throw new IllegalArgumentException(key + " already exist");
+        }
+        mMap.put(key, value);
+    }
+
+    @Override
+    public void replaceEntry(K key, V value) throws ErrnoException, NoSuchElementException {
+        if (!mMap.containsKey(key)) throw new NoSuchElementException();
+        mMap.put(key, value);
+    }
+
+    @Override
+    public boolean insertOrReplaceEntry(K key, V value) throws ErrnoException {
+        // Returns true if inserted, false if replaced.
+        boolean ret = !mMap.containsKey(key);
+        mMap.put(key, value);
+        return ret;
+    }
+
+    @Override
+    public boolean deleteEntry(Struct key) throws ErrnoException {
+        return mMap.remove(key) != null;
+    }
+
+    @Override
+    public boolean isEmpty() throws ErrnoException {
+        return mMap.isEmpty();
+    }
+
+    @Override
+    public K getNextKey(@NonNull K key) {
+        // Expensive, but since this is only for tests...
+        Iterator<K> it = mMap.keySet().iterator();
+        while (it.hasNext()) {
+            if (Objects.equals(it.next(), key)) {
+                return it.hasNext() ? it.next() : null;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public K getFirstKey() {
+        for (K key : mMap.keySet()) {
+            return key;
+        }
+        return null;
+    }
+
+    @Override
+    public boolean containsKey(@NonNull K key) throws ErrnoException {
+        return mMap.containsKey(key);
+    }
+
+    @Override
+    public V getValue(@NonNull K key) throws ErrnoException {
+        // Return value for a given key. Otherwise, return null without an error ENOENT.
+        // BpfMap#getValue treats that the entry is not found as no error.
+        return mMap.get(key);
+    }
+
+    @Override
+    public void clear() throws ErrnoException {
+        // TODO: consider using mocked #getFirstKey and #deleteEntry to implement.
+        mMap.clear();
+    }
+
+    @Override
+    public void close() throws IOException {
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/TestDnsServer.kt b/staticlibs/testutils/devicetests/com/android/testutils/TestDnsServer.kt
new file mode 100644
index 0000000..e1b771b
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/TestDnsServer.kt
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import android.net.Network
+import android.util.Log
+import com.android.internal.annotations.GuardedBy
+import com.android.internal.annotations.VisibleForTesting
+import com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE
+import com.android.net.module.util.DnsPacket
+import java.net.DatagramPacket
+import java.net.DatagramSocket
+import java.net.InetAddress
+import java.net.InetSocketAddress
+import java.net.SocketAddress
+import java.net.SocketException
+import java.util.ArrayList
+
+private const val TAG = "TestDnsServer"
+private const val VDBG = true
+@VisibleForTesting(visibility = PRIVATE)
+const val MAX_BUF_SIZE = 8192
+
+/**
+ * A simple implementation of Dns Server that can be bound on specific address and Network.
+ *
+ * The caller should use start() to make the server start a new thread to receive DNS queries
+ * on the bound address, [isAlive] to check status, and stop() for stopping.
+ * The server allows user to manipulate the records to be answered through
+ * [setAnswer] at runtime.
+ *
+ * This server runs on its own thread. Please make sure writing the query to the socket
+ * happens-after using [setAnswer] to guarantee the correct answer is returned. If possible,
+ * use [setAnswer] before calling [start] for simplicity.
+ */
+class TestDnsServer(network: Network, addr: InetSocketAddress) {
+    enum class Status {
+        NOT_STARTED, STARTED, STOPPED
+    }
+    @GuardedBy("thread")
+    private var status: Status = Status.NOT_STARTED
+    private val thread = ReceivingThread()
+    private val socket = DatagramSocket(addr).also { network.bindSocket(it) }
+    private val ansProvider = DnsAnswerProvider()
+
+    // The buffer to store the received packet. They are being reused for
+    // efficiency and it's fine because they are only ever accessed
+    // on the server thread in a sequential manner.
+    private val buffer = ByteArray(MAX_BUF_SIZE)
+    private val packet = DatagramPacket(buffer, buffer.size)
+
+    fun setAnswer(hostname: String, answer: List<InetAddress>) =
+        ansProvider.setAnswer(hostname, answer)
+
+    private fun processPacket() {
+        // Blocking read and try construct a DnsQueryPacket object.
+        socket.receive(packet)
+        val q = DnsQueryPacket(packet.data)
+        handleDnsQuery(q, packet.socketAddress)
+    }
+
+    // TODO: Add support to reply some error with a DNS reply packet with failure RCODE.
+    private fun handleDnsQuery(q: DnsQueryPacket, src: SocketAddress) {
+        val queryRecords = q.queryRecords
+        if (queryRecords.size != 1) {
+            throw IllegalArgumentException(
+                "Expected one dns query record but got ${queryRecords.size}"
+            )
+        }
+        val answerRecords = queryRecords[0].let { ansProvider.getAnswer(it.dName, it.nsType) }
+
+        if (VDBG) {
+            Log.v(TAG, "handleDnsPacket: " +
+                        queryRecords.map { "${it.dName},${it.nsType}" }.joinToString() +
+                        " ansCount=${answerRecords.size} socketAddress=$src")
+        }
+
+        val bytes = q.getAnswerPacket(answerRecords).bytes
+        val reply = DatagramPacket(bytes, bytes.size, src)
+        socket.send(reply)
+    }
+
+    fun start() {
+        synchronized(thread) {
+            if (status != Status.NOT_STARTED) {
+                throw IllegalStateException("unexpected status: $status")
+            }
+            thread.start()
+            status = Status.STARTED
+        }
+    }
+    fun stop() {
+        synchronized(thread) {
+            if (status != Status.STARTED) {
+                throw IllegalStateException("unexpected status: $status")
+            }
+            // The thread needs to be interrupted before closing the socket to prevent a data
+            // race where the thread tries to read from the socket while it's being closed.
+            // DatagramSocket is not thread-safe and running both concurrently can end up in
+            // getPort() returning -1 after it's been checked not to, resulting in a crash by
+            // IllegalArgumentException inside the DatagramSocket implementation.
+            thread.interrupt()
+            socket.close()
+            thread.join()
+            status = Status.STOPPED
+        }
+    }
+    val isAlive get() = thread.isAlive
+    val port get() = socket.localPort
+
+    inner class ReceivingThread : Thread() {
+        override fun run() {
+            while (!interrupted() && !socket.isClosed) {
+                try {
+                    processPacket()
+                } catch (e: InterruptedException) {
+                    // The caller terminated the server, exit.
+                    break
+                } catch (e: SocketException) {
+                    // The caller terminated the server, exit.
+                    break
+                }
+            }
+            Log.i(TAG, "exiting socket={$socket}")
+        }
+    }
+
+    @VisibleForTesting(visibility = PRIVATE)
+    class DnsQueryPacket : DnsPacket {
+        constructor(data: ByteArray) : super(data)
+        constructor(header: DnsHeader, qd: List<DnsRecord>, an: List<DnsRecord>) :
+                super(header, qd, an)
+
+        init {
+            if (mHeader.isResponse) {
+                throw ParseException("Not a query packet")
+            }
+        }
+
+        val queryRecords: List<DnsRecord>
+            get() = mRecords[QDSECTION]
+
+        fun getAnswerPacket(ar: List<DnsRecord>): DnsAnswerPacket {
+            // Set QR bit of flag to 1 for response packet according to RFC 1035 section 4.1.1.
+            val flags = 1 shl 15
+            val qr = ArrayList(mRecords[QDSECTION])
+            // Copy the query packet header id to the answer packet as RFC 1035 section 4.1.1.
+            val header = DnsHeader(mHeader.id, flags, qr.size, ar.size)
+            return DnsAnswerPacket(header, qr, ar)
+        }
+    }
+
+    class DnsAnswerPacket : DnsPacket {
+        constructor(header: DnsHeader, qr: List<DnsRecord>, ar: List<DnsRecord>) :
+                super(header, qr, ar)
+        @VisibleForTesting(visibility = PRIVATE)
+        constructor(bytes: ByteArray) : super(bytes)
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/TestHttpServer.kt b/staticlibs/testutils/devicetests/com/android/testutils/TestHttpServer.kt
new file mode 100644
index 0000000..740bf63
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/TestHttpServer.kt
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import android.net.Uri
+import com.android.net.module.util.ArrayTrackRecord
+import fi.iki.elonen.NanoHTTPD
+import java.io.IOException
+
+/**
+ * A minimal HTTP server running on a random available port.
+ *
+ * @param host The host to listen to, or null to listen on all hosts
+ */
+class TestHttpServer(host: String? = null) : NanoHTTPD(host, 0 /* auto-select the port */) {
+    // Map of URL path -> HTTP response code
+    private val responses = HashMap<Request, Response>()
+
+    /**
+     * A record of all requests received by the server since it was started.
+     */
+    val requestsRecord = ArrayTrackRecord<Request>()
+
+    /**
+     * A request received by the test server.
+     */
+    data class Request(
+        val path: String,
+        val method: Method = Method.GET,
+        val queryParameters: String = ""
+    ) {
+        /**
+         * Returns whether the specified [Uri] matches parameters of this request.
+         */
+        fun matches(uri: Uri) = (uri.path ?: "") == path && (uri.query ?: "") == queryParameters
+    }
+
+    /**
+     * Add a response for GET requests with the path and query parameters of the specified [Uri].
+     */
+    fun addResponse(
+        uri: Uri,
+        statusCode: Response.IStatus,
+        headers: Map<String, String>? = null,
+        content: String = ""
+    ) {
+        addResponse(Request(uri.path
+                ?: "", Method.GET, uri.query ?: ""),
+                statusCode, headers, content)
+    }
+
+    /**
+     * Add a response for the given request.
+     */
+    fun addResponse(
+        request: Request,
+        statusCode: Response.IStatus,
+        headers: Map<String, String>? = null,
+        content: String = ""
+    ) {
+        val response = newFixedLengthResponse(statusCode, "text/plain", content)
+        headers?.forEach {
+            (key, value) -> response.addHeader(key, value)
+        }
+        responses[request] = response
+    }
+
+    override fun serve(session: IHTTPSession): Response {
+        val request = Request(session.uri
+                ?: "", session.method, session.queryParameterString ?: "")
+        requestsRecord.add(request)
+
+        // For PUT and POST, call parseBody to read InputStream before responding.
+        if (Method.PUT == session.method || Method.POST == session.method) {
+            try {
+                session.parseBody(HashMap())
+            } catch (e: Exception) {
+                when (e) {
+                    is IOException, is ResponseException -> e.toResponse()
+                    else -> throw e
+                }
+            }
+        }
+
+        // Default response is a 404
+        return responses[request] ?: super.serve(session)
+    }
+
+    fun Exception.toResponse() =
+        newFixedLengthResponse(Response.Status.INTERNAL_ERROR, "text/plain", this.toString())
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/TestNetworkTracker.kt b/staticlibs/testutils/devicetests/com/android/testutils/TestNetworkTracker.kt
new file mode 100644
index 0000000..84fb47b
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/TestNetworkTracker.kt
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import android.content.Context
+import android.net.ConnectivityManager
+import android.net.ConnectivityManager.NetworkCallback
+import android.net.LinkAddress
+import android.net.Network
+import android.net.NetworkCapabilities
+import android.net.NetworkRequest
+import android.net.LinkProperties
+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 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].
+ */
+fun initTestNetwork(
+    context: Context,
+    interfaceAddr: LinkAddress,
+    setupTimeoutMs: Long = 10_000L
+): TestNetworkTracker {
+    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)
+}
+
+/**
+ * Create a test network based on a TUN interface
+ *
+ * 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(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)
+}
+
+/**
+ * Utility class to create and track test networks.
+ *
+ * This class is not thread-safe.
+ */
+class TestNetworkTracker internal constructor(
+    val context: Context,
+    val iface: TestNetworkInterface,
+    val tnm: TestNetworkManager,
+    val lp: LinkProperties?,
+    setupTimeoutMs: Long
+) : TestableNetworkCallback.HasNetwork {
+    private val cm = context.getSystemService(ConnectivityManager::class.java)!!
+    private val binder = Binder()
+
+    private val networkCallback: NetworkCallback
+    override val network: Network
+    val testIface: TestNetworkInterface
+
+    init {
+        val networkFuture = CompletableFuture<Network>()
+        val networkRequest = NetworkRequest.Builder()
+                .addTransportType(NetworkCapabilities.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(CompatUtil.makeTestNetworkSpecifier(iface.interfaceName))
+                .build()
+        networkCallback = object : NetworkCallback() {
+            override fun onAvailable(network: Network) {
+                networkFuture.complete(network)
+            }
+        }
+        cm.requestNetwork(networkRequest, networkCallback)
+
+        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) {
+            cm.unregisterNetworkCallback(networkCallback)
+            throw e
+        }
+
+        testIface = iface
+    }
+
+    fun teardown() {
+        cm.unregisterNetworkCallback(networkCallback)
+        tnm.teardownTestNetwork(network)
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/TestPermissionUtil.kt b/staticlibs/testutils/devicetests/com/android/testutils/TestPermissionUtil.kt
new file mode 100644
index 0000000..f571f64
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/TestPermissionUtil.kt
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:JvmName("TestPermissionUtil")
+
+package com.android.testutils
+
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.modules.utils.build.SdkLevel
+import com.android.testutils.FunctionalUtils.ThrowingRunnable
+import com.android.testutils.FunctionalUtils.ThrowingSupplier
+
+/**
+ * Run the specified [task] with the specified [permissions] obtained through shell
+ * permission identity.
+ *
+ * Passing in an empty list of permissions can grant all shell permissions, but this is
+ * discouraged as it also causes the process to temporarily lose non-shell permissions.
+ */
+fun <T> runAsShell(vararg permissions: String, task: () -> T): T {
+    val autom = InstrumentationRegistry.getInstrumentation().uiAutomation
+
+    // Calls to adoptShellPermissionIdentity do not nest, and dropShellPermissionIdentity drops all
+    // permissions. Thus, nesting calls will almost certainly cause test bugs, On S+, where we can
+    // detect this, refuse to do it.
+    //
+    // TODO: when R is deprecated, we could try to make this work instead.
+    // - Get the list of previously-adopted permissions.
+    // - Adopt the union of the previously-adopted and newly-requested permissions.
+    // - Run the task.
+    // - Adopt the previously-adopted permissions, dropping the ones just adopted.
+    //
+    // This would allow tests (and utility classes, such as the TestCarrierConfigReceiver attempted
+    // in aosp/2106007) to call runAsShell even within a test that has already adopted permissions.
+    if (SdkLevel.isAtLeastS() && !autom.getAdoptedShellPermissions().isNullOrEmpty()) {
+        throw IllegalStateException("adoptShellPermissionIdentity calls must not be nested")
+    }
+
+    autom.adoptShellPermissionIdentity(*permissions)
+    try {
+        return task()
+    } finally {
+        autom.dropShellPermissionIdentity()
+    }
+}
+
+/**
+ * Convenience overload of [runAsShell] that uses a [ThrowingSupplier] for Java callers, when
+ * only one/two/three permissions are needed.
+ */
+@JvmOverloads
+fun <T> runAsShell(
+    perm1: String,
+    perm2: String = "",
+    perm3: String = "",
+    supplier: ThrowingSupplier<T>
+): T = runAsShell(*getNonEmptyVarargs(perm1, perm2, perm3)) { supplier.get() }
+
+/**
+ * Convenience overload of [runAsShell] that uses a [ThrowingRunnable] for Java callers, when
+ * only one/two/three permissions are needed.
+ */
+@JvmOverloads
+fun runAsShell(
+    perm1: String,
+    perm2: String = "",
+    perm3: String = "",
+    runnable: ThrowingRunnable
+): Unit = runAsShell(*getNonEmptyVarargs(perm1, perm2, perm3)) { runnable.run() }
+
+/**
+ * Get an array containing the first consecutive non-empty arguments out of three arguments.
+ *
+ * The first argument is assumed to be non-empty.
+ */
+private fun getNonEmptyVarargs(arg1: String, arg2: String, arg3: String): Array<String> {
+    return when {
+        arg2 == "" -> arrayOf(arg1)
+        arg3 == "" -> arrayOf(arg1, arg2)
+        else -> arrayOf(arg1, arg2, arg3)
+    }
+}
\ No newline at end of file
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkAgent.kt b/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkAgent.kt
new file mode 100644
index 0000000..8dc1bc4
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkAgent.kt
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils;
+
+import android.content.Context
+import android.net.KeepalivePacketData
+import android.net.LinkProperties
+import android.net.NetworkAgent
+import android.net.NetworkAgentConfig
+import android.net.NetworkCapabilities
+import android.net.NetworkProvider
+import android.net.QosFilter
+import android.net.Uri
+import android.os.Looper
+import com.android.net.module.util.ArrayTrackRecord
+import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnAddKeepalivePacketFilter
+import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnAutomaticReconnectDisabled
+import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnBandwidthUpdateRequested
+import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnDscpPolicyStatusUpdated
+import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnNetworkCreated
+import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnNetworkDestroyed
+import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnNetworkUnwanted
+import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnRegisterQosCallback
+import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnRemoveKeepalivePacketFilter
+import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnSaveAcceptUnvalidated
+import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnSignalStrengthThresholdsUpdated
+import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnStartSocketKeepalive
+import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnStopSocketKeepalive
+import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnUnregisterQosCallback
+import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnValidationStatus
+import java.time.Duration
+import kotlin.test.assertEquals
+import kotlin.test.assertNotNull
+import kotlin.test.assertNull
+import kotlin.test.assertTrue
+import org.junit.Assert.assertArrayEquals
+
+// Any legal score (0~99) for the test network would do, as it is going to be kept up by the
+// requests filed by the test and should never match normal internet requests. 70 is the default
+// score of Ethernet networks, it's as good a value as any other.
+private const val TEST_NETWORK_SCORE = 70
+
+private class Provider(context: Context, looper: Looper) :
+            NetworkProvider(context, looper, "NetworkAgentTest NetworkProvider")
+
+public open class TestableNetworkAgent(
+    context: Context,
+    looper: Looper,
+    val nc: NetworkCapabilities,
+    val lp: LinkProperties,
+    conf: NetworkAgentConfig
+) : NetworkAgent(context, looper, TestableNetworkAgent::class.java.simpleName /* tag */,
+        nc, lp, TEST_NETWORK_SCORE, conf, Provider(context, looper)) {
+
+    val DEFAULT_TIMEOUT_MS = 5000L
+
+    val history = ArrayTrackRecord<CallbackEntry>().newReadHead()
+
+    sealed class CallbackEntry {
+        object OnBandwidthUpdateRequested : CallbackEntry()
+        object OnNetworkUnwanted : CallbackEntry()
+        data class OnAddKeepalivePacketFilter(
+            val slot: Int,
+            val packet: KeepalivePacketData
+        ) : CallbackEntry()
+        data class OnRemoveKeepalivePacketFilter(val slot: Int) : CallbackEntry()
+        data class OnStartSocketKeepalive(
+            val slot: Int,
+            val interval: Int,
+            val packet: KeepalivePacketData
+        ) : CallbackEntry()
+        data class OnStopSocketKeepalive(val slot: Int) : CallbackEntry()
+        data class OnSaveAcceptUnvalidated(val accept: Boolean) : CallbackEntry()
+        object OnAutomaticReconnectDisabled : CallbackEntry()
+        data class OnValidationStatus(val status: Int, val uri: Uri?) : CallbackEntry()
+        data class OnSignalStrengthThresholdsUpdated(val thresholds: IntArray) : CallbackEntry()
+        object OnNetworkCreated : CallbackEntry()
+        object OnNetworkDestroyed : CallbackEntry()
+        data class OnDscpPolicyStatusUpdated(val policyId: Int, val status: Int) : CallbackEntry()
+        data class OnRegisterQosCallback(
+            val callbackId: Int,
+            val filter: QosFilter
+        ) : CallbackEntry()
+        data class OnUnregisterQosCallback(val callbackId: Int) : CallbackEntry()
+    }
+
+    override fun onBandwidthUpdateRequested() {
+        history.add(OnBandwidthUpdateRequested)
+    }
+
+    override fun onNetworkUnwanted() {
+        history.add(OnNetworkUnwanted)
+    }
+
+    override fun onAddKeepalivePacketFilter(slot: Int, packet: KeepalivePacketData) {
+        history.add(OnAddKeepalivePacketFilter(slot, packet))
+    }
+
+    override fun onRemoveKeepalivePacketFilter(slot: Int) {
+        history.add(OnRemoveKeepalivePacketFilter(slot))
+    }
+
+    override fun onStartSocketKeepalive(
+        slot: Int,
+        interval: Duration,
+        packet: KeepalivePacketData
+    ) {
+        history.add(OnStartSocketKeepalive(slot, interval.seconds.toInt(), packet))
+    }
+
+    override fun onStopSocketKeepalive(slot: Int) {
+        history.add(OnStopSocketKeepalive(slot))
+    }
+
+    override fun onSaveAcceptUnvalidated(accept: Boolean) {
+        history.add(OnSaveAcceptUnvalidated(accept))
+    }
+
+    override fun onAutomaticReconnectDisabled() {
+        history.add(OnAutomaticReconnectDisabled)
+    }
+
+    override fun onSignalStrengthThresholdsUpdated(thresholds: IntArray) {
+        history.add(OnSignalStrengthThresholdsUpdated(thresholds))
+    }
+
+    fun expectSignalStrengths(thresholds: IntArray? = intArrayOf()) {
+        expectCallback<OnSignalStrengthThresholdsUpdated>().let {
+            assertArrayEquals(thresholds, it.thresholds)
+        }
+    }
+
+    override fun onQosCallbackRegistered(qosCallbackId: Int, filter: QosFilter) {
+        history.add(OnRegisterQosCallback(qosCallbackId, filter))
+    }
+
+    override fun onQosCallbackUnregistered(qosCallbackId: Int) {
+        history.add(OnUnregisterQosCallback(qosCallbackId))
+    }
+
+    override fun onValidationStatus(status: Int, uri: Uri?) {
+        history.add(OnValidationStatus(status, uri))
+    }
+
+    override fun onNetworkCreated() {
+        history.add(OnNetworkCreated)
+    }
+
+    override fun onNetworkDestroyed() {
+        history.add(OnNetworkDestroyed)
+    }
+
+    override fun onDscpPolicyStatusUpdated(policyId: Int, status: Int) {
+        history.add(OnDscpPolicyStatusUpdated(policyId, status))
+    }
+
+    // Expects the initial validation event that always occurs immediately after registering
+    // a NetworkAgent whose network does not require validation (which test networks do
+    // not, since they lack the INTERNET capability). It always contains the default argument
+    // for the URI.
+    fun expectValidationBypassedStatus() = expectCallback<OnValidationStatus>().let {
+        assertEquals(it.status, VALID_NETWORK)
+        // The returned Uri is parsed from the empty string, which means it's an
+        // instance of the (private) Uri.StringUri. There are no real good ways
+        // to check this, the least bad is to just convert it to a string and
+        // make sure it's empty.
+        assertEquals("", it.uri.toString())
+    }
+
+    inline fun <reified T : CallbackEntry> expectCallback(): T {
+        val foundCallback = history.poll(DEFAULT_TIMEOUT_MS)
+        assertTrue(foundCallback is T, "Expected ${T::class} but found $foundCallback")
+        return foundCallback
+    }
+
+    inline fun <reified T : CallbackEntry> expectCallback(valid: (T) -> Boolean) {
+        val foundCallback = history.poll(DEFAULT_TIMEOUT_MS)
+        assertTrue(foundCallback is T, "Expected ${T::class} but found $foundCallback")
+        assertTrue(valid(foundCallback), "Unexpected callback : $foundCallback")
+    }
+
+    inline fun <reified T : CallbackEntry> eventuallyExpect() =
+            history.poll(DEFAULT_TIMEOUT_MS) { it is T }.also {
+                assertNotNull(it, "Callback ${T::class} not received")
+    } as T
+
+    fun assertNoCallback() {
+        assertTrue(waitForIdle(DEFAULT_TIMEOUT_MS),
+                "Handler didn't became idle after ${DEFAULT_TIMEOUT_MS}ms")
+        assertNull(history.peek())
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkCallback.kt b/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkCallback.kt
new file mode 100644
index 0000000..df9c61a
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkCallback.kt
@@ -0,0 +1,569 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import android.net.ConnectivityManager.NetworkCallback
+import android.net.LinkProperties
+import android.net.Network
+import android.net.NetworkCapabilities
+import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
+import android.util.Log
+import com.android.net.module.util.ArrayTrackRecord
+import com.android.testutils.RecorderCallback.CallbackEntry.Available
+import com.android.testutils.RecorderCallback.CallbackEntry.BlockedStatus
+import com.android.testutils.RecorderCallback.CallbackEntry.BlockedStatusInt
+import com.android.testutils.RecorderCallback.CallbackEntry.CapabilitiesChanged
+import com.android.testutils.RecorderCallback.CallbackEntry.LinkPropertiesChanged
+import com.android.testutils.RecorderCallback.CallbackEntry.Losing
+import com.android.testutils.RecorderCallback.CallbackEntry.Lost
+import com.android.testutils.RecorderCallback.CallbackEntry.Resumed
+import com.android.testutils.RecorderCallback.CallbackEntry.Suspended
+import com.android.testutils.RecorderCallback.CallbackEntry.Unavailable
+import kotlin.reflect.KClass
+import kotlin.test.assertEquals
+import kotlin.test.assertNotNull
+import kotlin.test.fail
+
+object NULL_NETWORK : Network(-1)
+object ANY_NETWORK : Network(-2)
+fun anyNetwork() = ANY_NETWORK
+
+open class RecorderCallback private constructor(
+    private val backingRecord: ArrayTrackRecord<CallbackEntry>
+) : NetworkCallback() {
+    public constructor() : this(ArrayTrackRecord())
+    protected constructor(src: RecorderCallback?) : this(src?.backingRecord ?: ArrayTrackRecord())
+
+    private val TAG = this::class.simpleName
+
+    sealed class CallbackEntry {
+        // To get equals(), hashcode(), componentN() etc for free, the child classes of
+        // this class are data classes. But while data classes can inherit from other classes,
+        // they may only have visible members in the constructors, so they couldn't declare
+        // a constructor with a non-val arg to pass to CallbackEntry. Instead, force all
+        // subclasses to implement a `network' property, which can be done in a data class
+        // constructor by specifying override.
+        abstract val network: Network
+
+        data class Available(override val network: Network) : CallbackEntry()
+        data class CapabilitiesChanged(
+            override val network: Network,
+            val caps: NetworkCapabilities
+        ) : CallbackEntry()
+        data class LinkPropertiesChanged(
+            override val network: Network,
+            val lp: LinkProperties
+        ) : CallbackEntry()
+        data class Suspended(override val network: Network) : CallbackEntry()
+        data class Resumed(override val network: Network) : CallbackEntry()
+        data class Losing(override val network: Network, val maxMsToLive: Int) : CallbackEntry()
+        data class Lost(override val network: Network) : CallbackEntry()
+        data class Unavailable private constructor(
+            override val network: Network
+        ) : CallbackEntry() {
+            constructor() : this(NULL_NETWORK)
+        }
+        data class BlockedStatus(
+            override val network: Network,
+            val blocked: Boolean
+        ) : CallbackEntry()
+        data class BlockedStatusInt(
+            override val network: Network,
+            val reason: Int
+        ) : CallbackEntry()
+        // Convenience constants for expecting a type
+        companion object {
+            @JvmField
+            val AVAILABLE = Available::class
+            @JvmField
+            val NETWORK_CAPS_UPDATED = CapabilitiesChanged::class
+            @JvmField
+            val LINK_PROPERTIES_CHANGED = LinkPropertiesChanged::class
+            @JvmField
+            val SUSPENDED = Suspended::class
+            @JvmField
+            val RESUMED = Resumed::class
+            @JvmField
+            val LOSING = Losing::class
+            @JvmField
+            val LOST = Lost::class
+            @JvmField
+            val UNAVAILABLE = Unavailable::class
+            @JvmField
+            val BLOCKED_STATUS = BlockedStatus::class
+            @JvmField
+            val BLOCKED_STATUS_INT = BlockedStatusInt::class
+        }
+    }
+
+    val history = backingRecord.newReadHead()
+    val mark get() = history.mark
+
+    override fun onAvailable(network: Network) {
+        Log.d(TAG, "onAvailable $network")
+        history.add(Available(network))
+    }
+
+    // PreCheck is not used in the tests today. For backward compatibility with existing tests that
+    // expect the callbacks not to record this, do not listen to PreCheck here.
+
+    override fun onCapabilitiesChanged(network: Network, caps: NetworkCapabilities) {
+        Log.d(TAG, "onCapabilitiesChanged $network $caps")
+        history.add(CapabilitiesChanged(network, caps))
+    }
+
+    override fun onLinkPropertiesChanged(network: Network, lp: LinkProperties) {
+        Log.d(TAG, "onLinkPropertiesChanged $network $lp")
+        history.add(LinkPropertiesChanged(network, lp))
+    }
+
+    override fun onBlockedStatusChanged(network: Network, blocked: Boolean) {
+        Log.d(TAG, "onBlockedStatusChanged $network $blocked")
+        history.add(BlockedStatus(network, blocked))
+    }
+
+    // Cannot do:
+    // fun onBlockedStatusChanged(network: Network, blocked: Int) {
+    // because on S, that needs to be "override fun", and on R, that cannot be "override fun".
+    override fun onNetworkSuspended(network: Network) {
+        Log.d(TAG, "onNetworkSuspended $network $network")
+        history.add(Suspended(network))
+    }
+
+    override fun onNetworkResumed(network: Network) {
+        Log.d(TAG, "$network onNetworkResumed $network")
+        history.add(Resumed(network))
+    }
+
+    override fun onLosing(network: Network, maxMsToLive: Int) {
+        Log.d(TAG, "onLosing $network $maxMsToLive")
+        history.add(Losing(network, maxMsToLive))
+    }
+
+    override fun onLost(network: Network) {
+        Log.d(TAG, "onLost $network")
+        history.add(Lost(network))
+    }
+
+    override fun onUnavailable() {
+        Log.d(TAG, "onUnavailable")
+        history.add(Unavailable())
+    }
+}
+
+private const val DEFAULT_TIMEOUT = 30_000L // ms
+private const val DEFAULT_NO_CALLBACK_TIMEOUT = 200L // ms
+private val NOOP = Runnable {}
+
+/**
+ * See comments on the public constructor below for a description of the arguments.
+ */
+open class TestableNetworkCallback private constructor(
+    src: TestableNetworkCallback?,
+    val defaultTimeoutMs: Long = DEFAULT_TIMEOUT,
+    val defaultNoCallbackTimeoutMs: Long = DEFAULT_NO_CALLBACK_TIMEOUT,
+    val waiterFunc: Runnable = NOOP // "() -> Unit" would forbid calling with a void func from Java
+) : RecorderCallback(src) {
+    /**
+     * Construct a testable network callback.
+     * @param timeoutMs the default timeout for expecting a callback. Default 30 seconds. This
+     *                  should be long in most cases, because the success case doesn't incur
+     *                  the wait.
+     * @param noCallbackTimeoutMs the timeout for expecting that no callback is received. Default
+     *                            200ms. Because the success case does incur the timeout, this
+     *                            should be short in most cases, but not so short as to frequently
+     *                            time out before an incorrect callback is received.
+     * @param waiterFunc a function to use before asserting no callback. For some specific tests,
+     *                   it is useful to run test-specific code before asserting no callback to
+     *                   increase the likelihood that a spurious callback is correctly detected.
+     *                   As an example, a unit test using mock loopers may want to use this to
+     *                   make sure the loopers are drained before asserting no callback, since
+     *                   one of them may cause a callback to be called. @see ConnectivityServiceTest
+     *                   for such an example.
+     */
+    @JvmOverloads
+    constructor(
+        timeoutMs: Long = DEFAULT_TIMEOUT,
+        noCallbackTimeoutMs: Long = DEFAULT_NO_CALLBACK_TIMEOUT,
+        waiterFunc: Runnable = NOOP
+    ) : this(null, timeoutMs, noCallbackTimeoutMs, waiterFunc)
+
+    fun createLinkedCopy() = TestableNetworkCallback(
+            this, defaultTimeoutMs, defaultNoCallbackTimeoutMs, waiterFunc)
+
+    // The last available network, or null if any network was lost since the last call to
+    // onAvailable. TODO : fix this by fixing the tests that rely on this behavior
+    val lastAvailableNetwork: Network?
+        get() = when (val it = history.lastOrNull { it is Available || it is Lost }) {
+            is Available -> it.network
+            else -> null
+        }
+
+    /**
+     * Get the next callback or null if timeout.
+     *
+     * With no argument, this method waits out the default timeout. To wait forever, pass
+     * Long.MAX_VALUE.
+     */
+    @JvmOverloads
+    fun poll(timeoutMs: Long = defaultTimeoutMs, predicate: (CallbackEntry) -> Boolean = { true }) =
+            history.poll(timeoutMs, predicate)
+
+    /*****
+     * expect family of methods.
+     * These methods fetch the next callback and assert it matches the conditions : type,
+     * passed predicate. If no callback is received within the timeout, these methods fail.
+     */
+    @JvmOverloads
+    fun <T : CallbackEntry> expect(
+        type: KClass<T>,
+        network: Network = ANY_NETWORK,
+        timeoutMs: Long = defaultTimeoutMs,
+        errorMsg: String? = null,
+        test: (T) -> Boolean = { true }
+    ) = expect<CallbackEntry>(network, timeoutMs, errorMsg) {
+        if (type.isInstance(it)) {
+            test(it as T) // Cast can't fail since type.isInstance(it) and type: KClass<T>
+        } else {
+            fail("Expected callback ${type.simpleName}, got $it")
+        }
+    } as T
+
+    @JvmOverloads
+    fun <T : CallbackEntry> expect(
+        type: KClass<T>,
+        network: HasNetwork,
+        timeoutMs: Long = defaultTimeoutMs,
+        errorMsg: String? = null,
+        test: (T) -> Boolean = { true }
+    ) = expect(type, network.network, timeoutMs, errorMsg, test)
+
+    // Java needs an explicit overload to let it omit arguments in the middle, so define these
+    // here. Note that @JvmOverloads give us the versions without the last arguments too, so
+    // there is no need to explicitly define versions without the test predicate.
+    // Without |network|
+    @JvmOverloads
+    fun <T : CallbackEntry> expect(
+        type: KClass<T>,
+        timeoutMs: Long,
+        errorMsg: String?,
+        test: (T) -> Boolean = { true }
+    ) = expect(type, ANY_NETWORK, timeoutMs, errorMsg, test)
+
+    // Without |timeout|, in Network and HasNetwork versions
+    @JvmOverloads
+    fun <T : CallbackEntry> expect(
+        type: KClass<T>,
+        network: Network,
+        errorMsg: String?,
+        test: (T) -> Boolean = { true }
+    ) = expect(type, network, defaultTimeoutMs, errorMsg, test)
+
+    @JvmOverloads
+    fun <T : CallbackEntry> expect(
+        type: KClass<T>,
+        network: HasNetwork,
+        errorMsg: String?,
+        test: (T) -> Boolean = { true }
+    ) = expect(type, network.network, defaultTimeoutMs, errorMsg, test)
+
+    // Without |errorMsg|, in Network and HasNetwork versions
+    @JvmOverloads
+    fun <T : CallbackEntry> expect(
+        type: KClass<T>,
+        network: Network,
+        timeoutMs: Long,
+        test: (T) -> Boolean
+    ) = expect(type, network, timeoutMs, null, test)
+
+    @JvmOverloads
+    fun <T : CallbackEntry> expect(
+        type: KClass<T>,
+        network: HasNetwork,
+        timeoutMs: Long,
+        test: (T) -> Boolean
+    ) = expect(type, network.network, timeoutMs, null, test)
+
+    // Without |network| or |timeout|
+    @JvmOverloads
+    fun <T : CallbackEntry> expect(
+        type: KClass<T>,
+        errorMsg: String?,
+        test: (T) -> Boolean = { true }
+    ) = expect(type, ANY_NETWORK, defaultTimeoutMs, errorMsg, test)
+
+    // Without |network| or |errorMsg|
+    @JvmOverloads
+    fun <T : CallbackEntry> expect(
+        type: KClass<T>,
+        timeoutMs: Long,
+        test: (T) -> Boolean = { true }
+    ) = expect(type, ANY_NETWORK, timeoutMs, null, test)
+
+    // Without |timeout| or |errorMsg|, in Network and HasNetwork versions
+    @JvmOverloads
+    fun <T : CallbackEntry> expect(
+        type: KClass<T>,
+        network: Network,
+        test: (T) -> Boolean
+    ) = expect(type, network, defaultTimeoutMs, null, test)
+
+    @JvmOverloads
+    fun <T : CallbackEntry> expect(
+        type: KClass<T>,
+        network: HasNetwork,
+        test: (T) -> Boolean
+    ) = expect(type, network.network, defaultTimeoutMs, null, test)
+
+    // Without |network| or |timeout| or |errorMsg|
+    @JvmOverloads
+    fun <T : CallbackEntry> expect(
+        type: KClass<T>,
+        test: (T) -> Boolean
+    ) = expect(type, ANY_NETWORK, defaultTimeoutMs, null, test)
+
+    // Kotlin reified versions. Don't call methods above, or the predicate would need to be noinline
+    inline fun <reified T : CallbackEntry> expect(
+        network: Network = ANY_NETWORK,
+        timeoutMs: Long = defaultTimeoutMs,
+        errorMsg: String? = null,
+        test: (T) -> Boolean = { true }
+    ) = (poll(timeoutMs) ?: fail("Did not receive ${T::class.simpleName} after ${timeoutMs}ms"))
+            .also {
+                if (it !is T) fail("Expected callback ${T::class.simpleName}, got $it")
+                if (ANY_NETWORK !== network && it.network != network) {
+                    fail("Expected network $network for callback : $it")
+                }
+                if (!test(it)) {
+                    fail("${errorMsg ?: "Callback doesn't match predicate"} : $it")
+                }
+            } as T
+
+    inline fun <reified T : CallbackEntry> expect(
+        network: HasNetwork,
+        timeoutMs: Long = defaultTimeoutMs,
+        errorMsg: String? = null,
+        test: (T) -> Boolean = { true }
+    ) = expect(network.network, timeoutMs, errorMsg, test)
+
+    /*****
+     * assertNoCallback family of methods.
+     * These methods make sure that no callback that matches the predicate was received.
+     * If no predicate is given, they make sure that no callback at all was received.
+     * These methods run the waiter func given in the constructor if any.
+     */
+    @JvmOverloads
+    fun assertNoCallback(
+        timeoutMs: Long = defaultNoCallbackTimeoutMs,
+        valid: (CallbackEntry) -> Boolean = { true }
+    ) {
+        waiterFunc.run()
+        history.poll(timeoutMs) { valid(it) }?.let { fail("Expected no callback but got $it") }
+    }
+
+    fun assertNoCallback(valid: (CallbackEntry) -> Boolean) =
+            assertNoCallback(defaultNoCallbackTimeoutMs, valid)
+
+    /*****
+     * eventuallyExpect family of methods.
+     * These methods make sure a callback that matches the type/predicate is received eventually.
+     * Any callback of the wrong type, or doesn't match the optional predicate, is ignored.
+     * They fail if no callback matching the predicate is received within the timeout.
+     */
+    inline fun <reified T : CallbackEntry> eventuallyExpect(
+        timeoutMs: Long = defaultTimeoutMs,
+        from: Int = mark,
+        crossinline predicate: (T) -> Boolean = { true }
+    ): T = history.poll(timeoutMs, from) { it is T && predicate(it) }.also {
+        assertNotNull(it, "Callback ${T::class} not received within ${timeoutMs}ms. " +
+                "Got ${history.backtrace()}")
+    } as T
+
+    @JvmOverloads
+    fun <T : CallbackEntry> eventuallyExpect(
+        type: KClass<T>,
+        timeoutMs: Long = defaultTimeoutMs,
+        predicate: (cb: T) -> Boolean = { true }
+    ) = history.poll(timeoutMs) { type.java.isInstance(it) && predicate(it as T) }.also {
+        assertNotNull(it, "Callback ${type.java} not received within ${timeoutMs}ms. " +
+                "Got ${history.backtrace()}")
+    } as T
+
+    fun <T : CallbackEntry> eventuallyExpect(
+        type: KClass<T>,
+        timeoutMs: Long = defaultTimeoutMs,
+        from: Int = mark,
+        predicate: (cb: T) -> Boolean = { true }
+    ) = history.poll(timeoutMs, from) { type.java.isInstance(it) && predicate(it as T) }.also {
+        assertNotNull(it, "Callback ${type.java} not received within ${timeoutMs}ms. " +
+                "Got ${history.backtrace()}")
+    } as T
+
+    // Expects onAvailable and the callbacks that follow it. These are:
+    // - onSuspended, iff the network was suspended when the callbacks fire.
+    // - onCapabilitiesChanged.
+    // - onLinkPropertiesChanged.
+    // - onBlockedStatusChanged.
+    //
+    // @param network the network to expect the callbacks on.
+    // @param suspended whether to expect a SUSPENDED callback.
+    // @param validated the expected value of the VALIDATED capability in the
+    //        onCapabilitiesChanged callback.
+    // @param tmt how long to wait for the callbacks.
+    @JvmOverloads
+    fun expectAvailableCallbacks(
+        net: Network,
+        suspended: Boolean = false,
+        validated: Boolean? = true,
+        blocked: Boolean = false,
+        tmt: Long = defaultTimeoutMs
+    ) {
+        expectAvailableCallbacksCommon(net, suspended, validated, tmt)
+        expect<BlockedStatus>(net, tmt) { it.blocked == blocked }
+    }
+
+    fun expectAvailableCallbacks(
+        net: Network,
+        suspended: Boolean,
+        validated: Boolean,
+        blockedReason: Int,
+        tmt: Long
+    ) {
+        expectAvailableCallbacksCommon(net, suspended, validated, tmt)
+        expect<BlockedStatusInt>(net) { it.reason == blockedReason }
+    }
+
+    private fun expectAvailableCallbacksCommon(
+        net: Network,
+        suspended: Boolean,
+        validated: Boolean?,
+        tmt: Long
+    ) {
+        expect<Available>(net, tmt)
+        if (suspended) {
+            expect<Suspended>(net, tmt)
+        }
+        expect<CapabilitiesChanged>(net, tmt) {
+            validated == null || validated == it.caps.hasCapability(NET_CAPABILITY_VALIDATED)
+        }
+        expect<LinkPropertiesChanged>(net, tmt)
+    }
+
+    // Backward compatibility for existing Java code. Use named arguments instead and remove all
+    // these when there is no user left.
+    fun expectAvailableAndSuspendedCallbacks(
+        net: Network,
+        validated: Boolean,
+        tmt: Long = defaultTimeoutMs
+    ) = expectAvailableCallbacks(net, suspended = true, validated = validated, tmt = tmt)
+
+    // Expects the available callbacks (where the onCapabilitiesChanged must contain the
+    // VALIDATED capability), plus another onCapabilitiesChanged which is identical to the
+    // one we just sent.
+    // TODO: this is likely a bug. Fix it and remove this method.
+    fun expectAvailableDoubleValidatedCallbacks(net: Network, tmt: Long = defaultTimeoutMs) {
+        val mark = history.mark
+        expectAvailableCallbacks(net, tmt = tmt)
+        val firstCaps = history.poll(tmt, mark) { it is CapabilitiesChanged }
+        assertEquals(firstCaps, expect<CapabilitiesChanged>(net, tmt))
+    }
+
+    // Expects the available callbacks where the onCapabilitiesChanged must not have validated,
+    // then expects another onCapabilitiesChanged that has the validated bit set. This is used
+    // when a network connects and satisfies a callback, and then immediately validates.
+    fun expectAvailableThenValidatedCallbacks(net: Network, tmt: Long = defaultTimeoutMs) {
+        expectAvailableCallbacks(net, validated = false, tmt = tmt)
+        expectCaps(net, tmt) { it.hasCapability(NET_CAPABILITY_VALIDATED) }
+    }
+
+    fun expectAvailableThenValidatedCallbacks(
+        net: Network,
+        blockedReason: Int,
+        tmt: Long = defaultTimeoutMs
+    ) {
+        expectAvailableCallbacks(net, validated = false, suspended = false,
+                blockedReason = blockedReason, tmt = tmt)
+        expectCaps(net, tmt) { it.hasCapability(NET_CAPABILITY_VALIDATED) }
+    }
+
+    // Temporary Java compat measure : have MockNetworkAgent implement this so that all existing
+    // calls with networkAgent can be routed through here without moving MockNetworkAgent.
+    // TODO: clean this up, remove this method.
+    interface HasNetwork {
+        val network: Network
+    }
+
+    fun expectAvailableCallbacks(
+        n: HasNetwork,
+        suspended: Boolean,
+        validated: Boolean,
+        blocked: Boolean,
+        timeoutMs: Long
+    ) = expectAvailableCallbacks(n.network, suspended, validated, blocked, timeoutMs)
+
+    fun expectAvailableAndSuspendedCallbacks(n: HasNetwork, expectValidated: Boolean) {
+        expectAvailableAndSuspendedCallbacks(n.network, expectValidated)
+    }
+
+    fun expectAvailableCallbacksValidated(n: HasNetwork) {
+        expectAvailableCallbacks(n.network)
+    }
+
+    fun expectAvailableCallbacksValidatedAndBlocked(n: HasNetwork) {
+        expectAvailableCallbacks(n.network, blocked = true)
+    }
+
+    fun expectAvailableCallbacksUnvalidated(n: HasNetwork) {
+        expectAvailableCallbacks(n.network, validated = false)
+    }
+
+    fun expectAvailableCallbacksUnvalidatedAndBlocked(n: HasNetwork) {
+        expectAvailableCallbacks(n.network, validated = false, blocked = true)
+    }
+
+    fun expectAvailableDoubleValidatedCallbacks(n: HasNetwork) {
+        expectAvailableDoubleValidatedCallbacks(n.network, defaultTimeoutMs)
+    }
+
+    fun expectAvailableThenValidatedCallbacks(n: HasNetwork) {
+        expectAvailableThenValidatedCallbacks(n.network, defaultTimeoutMs)
+    }
+
+    @JvmOverloads
+    fun expectCaps(
+        n: HasNetwork,
+        tmt: Long = defaultTimeoutMs,
+        valid: (NetworkCapabilities) -> Boolean = { true }
+    ) = expect<CapabilitiesChanged>(n.network, tmt) { valid(it.caps) }.caps
+
+    @JvmOverloads
+    fun expectCaps(
+        n: Network,
+        tmt: Long = defaultTimeoutMs,
+        valid: (NetworkCapabilities) -> Boolean
+    ) = expect<CapabilitiesChanged>(n, tmt) { valid(it.caps) }.caps
+
+    fun expectCaps(
+        n: HasNetwork,
+        valid: (NetworkCapabilities) -> Boolean
+    ) = expect<CapabilitiesChanged>(n.network) { valid(it.caps) }.caps
+
+    fun expectCaps(
+        tmt: Long,
+        valid: (NetworkCapabilities) -> Boolean
+    ) = expect<CapabilitiesChanged>(ANY_NETWORK, tmt) { valid(it.caps) }.caps
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkOfferCallback.kt b/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkOfferCallback.kt
new file mode 100644
index 0000000..21bd60c
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkOfferCallback.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import android.net.NetworkCapabilities
+import android.net.NetworkProvider
+import android.net.NetworkRequest
+import android.util.Log
+import com.android.net.module.util.ArrayTrackRecord
+import kotlin.test.fail
+
+class TestableNetworkOfferCallback(val timeoutMs: Long, private val noCallbackTimeoutMs: Long)
+            : NetworkProvider.NetworkOfferCallback {
+    private val TAG = this::class.simpleName
+    val history = ArrayTrackRecord<CallbackEntry>().newReadHead()
+
+    sealed class CallbackEntry {
+        data class OnNetworkNeeded(val request: NetworkRequest) : CallbackEntry()
+        data class OnNetworkUnneeded(val request: NetworkRequest) : CallbackEntry()
+    }
+
+    /**
+     * Called by the system when a network for this offer is needed to satisfy some
+     * networking request.
+     */
+    override fun onNetworkNeeded(request: NetworkRequest) {
+        Log.d(TAG, "onNetworkNeeded $request")
+        history.add(CallbackEntry.OnNetworkNeeded(request))
+    }
+
+    /**
+     * Called by the system when this offer is no longer valuable for this request.
+     */
+    override fun onNetworkUnneeded(request: NetworkRequest) {
+        Log.d(TAG, "onNetworkUnneeded $request")
+        history.add(CallbackEntry.OnNetworkUnneeded(request))
+    }
+
+    inline fun <reified T : CallbackEntry> expectCallbackThat(
+        crossinline predicate: (T) -> Boolean
+    ) {
+        val event = history.poll(timeoutMs)
+                ?: fail("Did not receive callback after ${timeoutMs}ms")
+        if (event !is T || !predicate(event)) fail("Received unexpected callback $event")
+    }
+
+    fun expectOnNetworkNeeded(capabilities: NetworkCapabilities) =
+            expectCallbackThat<CallbackEntry.OnNetworkNeeded> {
+                it.request.canBeSatisfiedBy(capabilities)
+            }
+
+    fun expectOnNetworkUnneeded(capabilities: NetworkCapabilities) =
+            expectCallbackThat<CallbackEntry.OnNetworkUnneeded> {
+                it.request.canBeSatisfiedBy(capabilities)
+            }
+
+    fun assertNoCallback() {
+        val cb = history.poll(noCallbackTimeoutMs)
+        if (null != cb) fail("Expected no callback but got $cb")
+    }
+}
\ No newline at end of file
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkStatsProvider.kt b/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkStatsProvider.kt
new file mode 100644
index 0000000..4a7b351
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkStatsProvider.kt
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import android.net.netstats.provider.NetworkStatsProvider
+import android.util.Log
+import com.android.net.module.util.ArrayTrackRecord
+import kotlin.test.assertEquals
+import kotlin.test.assertTrue
+import kotlin.test.fail
+
+private const val DEFAULT_TIMEOUT_MS = 200L
+const val TOKEN_ANY = -1
+
+open class TestableNetworkStatsProvider(
+    val defaultTimeoutMs: Long = DEFAULT_TIMEOUT_MS
+) : NetworkStatsProvider() {
+    sealed class CallbackType {
+        data class OnRequestStatsUpdate(val token: Int) : CallbackType()
+        data class OnSetWarningAndLimit(
+            val iface: String,
+            val warningBytes: Long,
+            val limitBytes: Long
+        ) : CallbackType()
+        data class OnSetLimit(val iface: String, val limitBytes: Long) : CallbackType() {
+            // Add getter for backward compatibility since old tests do not recognize limitBytes.
+            val quotaBytes: Long
+                get() = limitBytes
+        }
+        data class OnSetAlert(val quotaBytes: Long) : CallbackType()
+    }
+
+    private val TAG = this::class.simpleName
+    val history = ArrayTrackRecord<CallbackType>().newReadHead()
+    // See ReadHead#mark
+    val mark get() = history.mark
+
+    override fun onRequestStatsUpdate(token: Int) {
+        Log.d(TAG, "onRequestStatsUpdate $token")
+        history.add(CallbackType.OnRequestStatsUpdate(token))
+    }
+
+    override fun onSetWarningAndLimit(iface: String, warningBytes: Long, limitBytes: Long) {
+        Log.d(TAG, "onSetWarningAndLimit $iface $warningBytes $limitBytes")
+        history.add(CallbackType.OnSetWarningAndLimit(iface, warningBytes, limitBytes))
+    }
+
+    override fun onSetLimit(iface: String, quotaBytes: Long) {
+        Log.d(TAG, "onSetLimit $iface $quotaBytes")
+        history.add(CallbackType.OnSetLimit(iface, quotaBytes))
+    }
+
+    override fun onSetAlert(quotaBytes: Long) {
+        Log.d(TAG, "onSetAlert $quotaBytes")
+        history.add(CallbackType.OnSetAlert(quotaBytes))
+    }
+
+    fun expectOnRequestStatsUpdate(token: Int, timeout: Long = defaultTimeoutMs): Int {
+        val event = history.poll(timeout)
+        assertTrue(event is CallbackType.OnRequestStatsUpdate)
+        if (token != TOKEN_ANY) {
+            assertEquals(token, event.token)
+        }
+        return event.token
+    }
+
+    fun expectOnSetLimit(iface: String, quotaBytes: Long, timeout: Long = defaultTimeoutMs) {
+        assertEquals(CallbackType.OnSetLimit(iface, quotaBytes), history.poll(timeout))
+    }
+
+    fun expectOnSetAlert(quotaBytes: Long, timeout: Long = defaultTimeoutMs) {
+        assertEquals(CallbackType.OnSetAlert(quotaBytes), history.poll(timeout))
+    }
+
+    fun pollForNextCallback(timeout: Long = defaultTimeoutMs) =
+        history.poll(timeout) ?: fail("Did not receive callback after ${timeout}ms")
+
+    inline fun <reified T : CallbackType> expectCallback(
+        timeout: Long = defaultTimeoutMs,
+        predicate: (T) -> Boolean = { true }
+    ): T {
+        return pollForNextCallback(timeout).also { assertTrue(it is T && predicate(it)) } as T
+    }
+
+    // Expects a callback of the specified type matching the predicate within the timeout.
+    // Any callback that doesn't match the predicate will be skipped. Fails only if
+    // no matching callback is received within the timeout.
+    // TODO : factorize the code for this with the identical call in TestableNetworkCallback.
+    // There should be a common superclass doing this generically.
+    // TODO : have a better error message to have this fail. Right now the failure when no
+    // matching callback arrives comes from the casting to a non-nullable T.
+    // TODO : in fact, completely removing this method and have clients use
+    // history.poll(timeout, index, predicate) directly might be simpler.
+    inline fun <reified T : CallbackType> eventuallyExpect(
+        timeoutMs: Long = defaultTimeoutMs,
+        from: Int = mark,
+        crossinline predicate: (T) -> Boolean = { true }
+    ) = history.poll(timeoutMs, from) { it is T && predicate(it) } as T
+
+    fun drainCallbacks() {
+        history.mark = history.size
+    }
+
+    @JvmOverloads
+    fun assertNoCallback(timeout: Long = defaultTimeoutMs) {
+        val cb = history.poll(timeout)
+        cb?.let { fail("Expected no callback but got $cb") }
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkStatsProviderBinder.kt b/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkStatsProviderBinder.kt
new file mode 100644
index 0000000..643346b
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkStatsProviderBinder.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import com.android.net.module.util.ArrayTrackRecord
+import kotlin.test.assertEquals
+import kotlin.test.fail
+
+private const val DEFAULT_TIMEOUT_MS = 200L
+
+open class TestableNetworkStatsProviderBinder : NetworkStatsProviderStubCompat() {
+    sealed class CallbackType {
+        data class OnRequestStatsUpdate(val token: Int) : CallbackType()
+        data class OnSetAlert(val quotaBytes: Long) : CallbackType()
+        data class OnSetWarningAndLimit(
+            val iface: String,
+            val warningBytes: Long,
+            val limitBytes: Long
+        ) : CallbackType()
+    }
+
+    private val history = ArrayTrackRecord<CallbackType>().ReadHead()
+
+    override fun onRequestStatsUpdate(token: Int) {
+        history.add(CallbackType.OnRequestStatsUpdate(token))
+    }
+
+    override fun onSetAlert(quotaBytes: Long) {
+        history.add(CallbackType.OnSetAlert(quotaBytes))
+    }
+
+    override fun onSetWarningAndLimit(iface: String, warningBytes: Long, limitBytes: Long) {
+        history.add(CallbackType.OnSetWarningAndLimit(iface, warningBytes, limitBytes))
+    }
+
+    fun expectOnRequestStatsUpdate(token: Int) {
+        assertEquals(CallbackType.OnRequestStatsUpdate(token), history.poll(DEFAULT_TIMEOUT_MS))
+    }
+
+    fun expectOnSetWarningAndLimit(iface: String, warningBytes: Long, limitBytes: Long) {
+        assertEquals(CallbackType.OnSetWarningAndLimit(iface, warningBytes, limitBytes),
+                history.poll(DEFAULT_TIMEOUT_MS))
+    }
+
+    fun expectOnSetAlert(quotaBytes: Long) {
+        assertEquals(CallbackType.OnSetAlert(quotaBytes), history.poll(DEFAULT_TIMEOUT_MS))
+    }
+
+    @JvmOverloads
+    fun assertNoCallback(timeout: Long = DEFAULT_TIMEOUT_MS) {
+        val cb = history.poll(timeout)
+        cb?.let { fail("Expected no callback but got $cb") }
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkStatsProviderCbBinder.kt b/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkStatsProviderCbBinder.kt
new file mode 100644
index 0000000..5547c90
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkStatsProviderCbBinder.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import android.net.NetworkStats
+import com.android.net.module.util.ArrayTrackRecord
+import kotlin.test.assertEquals
+import kotlin.test.assertTrue
+import kotlin.test.fail
+
+private const val DEFAULT_TIMEOUT_MS = 3000L
+
+open class TestableNetworkStatsProviderCbBinder : NetworkStatsProviderCbStubCompat() {
+    sealed class CallbackType {
+        data class NotifyStatsUpdated(
+            val token: Int,
+            val ifaceStats: NetworkStats,
+            val uidStats: NetworkStats
+        ) : CallbackType()
+        object NotifyWarningReached : CallbackType()
+        object NotifyLimitReached : CallbackType()
+        object NotifyWarningOrLimitReached : CallbackType()
+        object NotifyAlertReached : CallbackType()
+        object Unregister : CallbackType()
+    }
+
+    private val history = ArrayTrackRecord<CallbackType>().ReadHead()
+
+    override fun notifyStatsUpdated(token: Int, ifaceStats: NetworkStats, uidStats: NetworkStats) {
+        history.add(CallbackType.NotifyStatsUpdated(token, ifaceStats, uidStats))
+    }
+
+    override fun notifyWarningReached() {
+        history.add(CallbackType.NotifyWarningReached)
+    }
+
+    override fun notifyLimitReached() {
+        history.add(CallbackType.NotifyLimitReached)
+    }
+
+    override fun notifyWarningOrLimitReached() {
+        // Older callback is split into notifyLimitReached and notifyWarningReached in T.
+        history.add(CallbackType.NotifyWarningOrLimitReached)
+    }
+
+    override fun notifyAlertReached() {
+        history.add(CallbackType.NotifyAlertReached)
+    }
+
+    override fun unregister() {
+        history.add(CallbackType.Unregister)
+    }
+
+    fun expectNotifyStatsUpdated() {
+        val event = history.poll(DEFAULT_TIMEOUT_MS)
+        assertTrue(event is CallbackType.NotifyStatsUpdated)
+    }
+
+    fun expectNotifyStatsUpdated(ifaceStats: NetworkStats, uidStats: NetworkStats) {
+        val event = history.poll(DEFAULT_TIMEOUT_MS)!!
+        if (event !is CallbackType.NotifyStatsUpdated) {
+            throw Exception("Expected NotifyStatsUpdated callback, but got ${event::class}")
+        }
+        // TODO: verify token.
+        assertNetworkStatsEquals(ifaceStats, event.ifaceStats)
+        assertNetworkStatsEquals(uidStats, event.uidStats)
+    }
+
+    fun expectNotifyWarningReached() =
+            assertEquals(CallbackType.NotifyWarningReached, history.poll(DEFAULT_TIMEOUT_MS))
+
+    fun expectNotifyLimitReached() =
+            assertEquals(CallbackType.NotifyLimitReached, history.poll(DEFAULT_TIMEOUT_MS))
+
+    fun expectNotifyWarningOrLimitReached() =
+            assertEquals(CallbackType.NotifyWarningOrLimitReached, history.poll(DEFAULT_TIMEOUT_MS))
+
+    fun expectNotifyAlertReached() =
+            assertEquals(CallbackType.NotifyAlertReached, history.poll(DEFAULT_TIMEOUT_MS))
+
+    // Assert there is no callback in current queue.
+    fun assertNoCallback() {
+        val cb = history.poll(0)
+        cb?.let { fail("Expected no callback but got $cb") }
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/async/FakeOsAccess.java b/staticlibs/testutils/devicetests/com/android/testutils/async/FakeOsAccess.java
new file mode 100644
index 0000000..48b57d7
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/async/FakeOsAccess.java
@@ -0,0 +1,568 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils.async;
+
+import android.os.ParcelFileDescriptor;
+import android.system.StructPollfd;
+import android.util.Log;
+
+import com.android.net.module.util.async.CircularByteBuffer;
+import com.android.net.module.util.async.OsAccess;
+
+import java.io.FileDescriptor;
+import java.io.InterruptedIOException;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.concurrent.TimeUnit;
+
+public class FakeOsAccess extends OsAccess {
+    public static final boolean ENABLE_FINE_DEBUG = true;
+
+    public static final int DEFAULT_FILE_DATA_QUEUE_SIZE = 8 * 1024;
+
+    private enum FileType { PAIR, PIPE }
+
+    // Common poll() constants:
+    private static final short POLLIN  = 0x0001;
+    private static final short POLLOUT = 0x0004;
+    private static final short POLLERR = 0x0008;
+    private static final short POLLHUP = 0x0010;
+
+    private static final Constructor<FileDescriptor> FD_CONSTRUCTOR;
+    private static final Field FD_FIELD_DESCRIPTOR;
+    private static final Field PFD_FIELD_DESCRIPTOR;
+    private static final Field PFD_FIELD_GUARD;
+    private static final Method CLOSE_GUARD_METHOD_CLOSE;
+
+    private final int mReadQueueSize = DEFAULT_FILE_DATA_QUEUE_SIZE;
+    private final int mWriteQueueSize = DEFAULT_FILE_DATA_QUEUE_SIZE;
+    private final HashMap<Integer, File> mFiles = new HashMap<>();
+    private final byte[] mTmpBuffer = new byte[1024];
+    private final long mStartTime;
+    private final String mLogTag;
+    private int mFileNumberGen = 3;
+    private boolean mHasRateLimitedData;
+
+    public FakeOsAccess(String logTag) {
+        mLogTag = logTag;
+        mStartTime = monotonicTimeMillis();
+    }
+
+    @Override
+    public long monotonicTimeMillis() {
+        return System.nanoTime() / 1000000;
+    }
+
+    @Override
+    public FileDescriptor getInnerFileDescriptor(ParcelFileDescriptor fd) {
+        try {
+            return (FileDescriptor) PFD_FIELD_DESCRIPTOR.get(fd);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public void close(ParcelFileDescriptor fd) {
+        if (fd != null) {
+            close(getInnerFileDescriptor(fd));
+
+            try {
+                // Reduce CloseGuard warnings.
+                Object guard = PFD_FIELD_GUARD.get(fd);
+                CLOSE_GUARD_METHOD_CLOSE.invoke(guard);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    public synchronized void close(FileDescriptor fd) {
+        if (fd != null) {
+            File file = getFileOrNull(fd);
+            if (file != null) {
+                file.decreaseRefCount();
+                mFiles.remove(getFileDescriptorNumber(fd));
+                setFileDescriptorNumber(fd, -1);
+                notifyAll();
+            }
+        }
+    }
+
+    private File getFile(String func, FileDescriptor fd) throws IOException {
+        File file = getFileOrNull(fd);
+        if (file == null) {
+            throw newIOException(func, "Unknown file descriptor: " + getFileDebugName(fd));
+        }
+        return file;
+    }
+
+    private File getFileOrNull(FileDescriptor fd) {
+        return mFiles.get(getFileDescriptorNumber(fd));
+    }
+
+    @Override
+    public String getFileDebugName(ParcelFileDescriptor fd) {
+        return (fd != null ? getFileDebugName(getInnerFileDescriptor(fd)) : "null");
+    }
+
+    public String getFileDebugName(FileDescriptor fd) {
+        if (fd == null) {
+            return "null";
+        }
+
+        final int fdNumber = getFileDescriptorNumber(fd);
+        File file = mFiles.get(fdNumber);
+
+        StringBuilder sb = new StringBuilder();
+        if (file != null) {
+            if (file.name != null) {
+                sb.append(file.name);
+                sb.append("/");
+            }
+            sb.append(file.type);
+            sb.append("/");
+        } else {
+            sb.append("BADFD/");
+        }
+        sb.append(fdNumber);
+        return sb.toString();
+    }
+
+    public synchronized void setFileName(FileDescriptor fd, String name) {
+        File file = getFileOrNull(fd);
+        if (file != null) {
+            file.name = name;
+        }
+    }
+
+    @Override
+    public synchronized void setNonBlocking(FileDescriptor fd) throws IOException {
+        File file = getFile("fcntl", fd);
+        file.isBlocking = false;
+    }
+
+    @Override
+    public synchronized int read(FileDescriptor fd, byte[] buffer, int pos, int len)
+            throws IOException {
+        checkBoundaries("read", buffer, pos, len);
+
+        File file = getFile("read", fd);
+        if (file.readQueue == null) {
+            throw newIOException("read", "File not readable");
+        }
+        file.checkNonBlocking("read");
+
+        if (len == 0) {
+            return 0;
+        }
+
+        final int availSize = file.readQueue.size();
+        if (availSize == 0) {
+            if (file.isEndOfStream) {
+                // Java convention uses -1 to indicate end of stream.
+                return -1;
+            }
+            return 0;  // EAGAIN
+        }
+
+        final int readCount = Math.min(len, availSize);
+        file.readQueue.readBytes(buffer, pos, readCount);
+        maybeTransferData(file);
+        return readCount;
+    }
+
+    @Override
+    public synchronized int write(FileDescriptor fd, byte[] buffer, int pos, int len)
+            throws IOException {
+        checkBoundaries("write", buffer, pos, len);
+
+        File file = getFile("write", fd);
+        if (file.writeQueue == null) {
+            throw newIOException("read", "File not writable");
+        }
+        if (file.type == FileType.PIPE && file.sink.openCount == 0) {
+            throw newIOException("write", "The other end of pipe is closed");
+        }
+        file.checkNonBlocking("write");
+
+        if (len == 0) {
+            return 0;
+        }
+
+        final int originalFreeSize = file.writeQueue.freeSize();
+        if (originalFreeSize == 0) {
+            return 0;  // EAGAIN
+        }
+
+        final int writeCount = Math.min(len, originalFreeSize);
+        file.writeQueue.writeBytes(buffer, pos, writeCount);
+        maybeTransferData(file);
+
+        if (file.writeQueue.freeSize() < originalFreeSize) {
+            final int additionalQueuedCount = originalFreeSize - file.writeQueue.freeSize();
+            Log.i(mLogTag, logStr("Delaying transfer of " + additionalQueuedCount
+                + " bytes, queued=" + file.writeQueue.size() + ", type=" + file.type
+                + ", src_red=" + file.outboundLimiter + ", dst_red=" + file.sink.inboundLimiter));
+        }
+
+        return writeCount;
+    }
+
+    private void maybeTransferData(File file) {
+        boolean hasChanges = copyFileBuffers(file, file.sink);
+        hasChanges = copyFileBuffers(file.source, file) || hasChanges;
+
+        if (hasChanges) {
+            // TODO(b/245971639): Avoid notifying if no-one is polling.
+            notifyAll();
+        }
+    }
+
+    private boolean copyFileBuffers(File src, File dst) {
+        if (src.writeQueue == null || dst.readQueue == null) {
+            return false;
+        }
+
+        final int originalCopyCount = Math.min(mTmpBuffer.length,
+            Math.min(src.writeQueue.size(), dst.readQueue.freeSize()));
+
+        final int allowedCopyCount = RateLimiter.limit(
+            src.outboundLimiter, dst.inboundLimiter, originalCopyCount);
+
+        if (allowedCopyCount < originalCopyCount) {
+            if (ENABLE_FINE_DEBUG) {
+                Log.i(mLogTag, logStr("Delaying transfer of "
+                    + (originalCopyCount - allowedCopyCount) + " bytes, original="
+                    + originalCopyCount + ", allowed=" + allowedCopyCount
+                    + ", type=" + src.type));
+            }
+            if (originalCopyCount > 0) {
+                mHasRateLimitedData = true;
+            }
+            if (allowedCopyCount == 0) {
+                return false;
+            }
+        }
+
+        boolean hasChanges = false;
+        if (allowedCopyCount > 0) {
+            if (dst.readQueue.size() == 0 || src.writeQueue.freeSize() == 0) {
+                hasChanges = true;  // Read queue had no data, or write queue was full.
+            }
+            src.writeQueue.readBytes(mTmpBuffer, 0, allowedCopyCount);
+            dst.readQueue.writeBytes(mTmpBuffer, 0, allowedCopyCount);
+        }
+
+        if (!dst.isEndOfStream && src.openCount == 0
+                && src.writeQueue.size() == 0 && dst.readQueue.size() == 0) {
+            dst.isEndOfStream = true;
+            hasChanges = true;
+        }
+
+        return hasChanges;
+    }
+
+    public void clearInboundRateLimit(FileDescriptor fd) {
+        setInboundRateLimit(fd, Integer.MAX_VALUE);
+    }
+
+    public void clearOutboundRateLimit(FileDescriptor fd) {
+        setOutboundRateLimit(fd, Integer.MAX_VALUE);
+    }
+
+    public synchronized void setInboundRateLimit(FileDescriptor fd, int bytesPerSecond) {
+        File file = getFileOrNull(fd);
+        if (file != null) {
+            file.inboundLimiter.setBytesPerSecond(bytesPerSecond);
+            maybeTransferData(file);
+        }
+    }
+
+    public synchronized void setOutboundRateLimit(FileDescriptor fd, int bytesPerSecond) {
+        File file = getFileOrNull(fd);
+        if (file != null) {
+            file.outboundLimiter.setBytesPerSecond(bytesPerSecond);
+            maybeTransferData(file);
+        }
+    }
+
+    public synchronized ParcelFileDescriptor[] socketpair() throws IOException {
+        int fdNumber1 = getNextFd("socketpair");
+        int fdNumber2 = getNextFd("socketpair");
+
+        File file1 = new File(FileType.PAIR, mReadQueueSize, mWriteQueueSize);
+        File file2 = new File(FileType.PAIR, mReadQueueSize, mWriteQueueSize);
+
+        return registerFilePair(fdNumber1, file1, fdNumber2, file2);
+    }
+
+    @Override
+    public synchronized ParcelFileDescriptor[] pipe() throws IOException {
+        int fdNumber1 = getNextFd("pipe");
+        int fdNumber2 = getNextFd("pipe");
+
+        File file1 = new File(FileType.PIPE, mReadQueueSize, 0);
+        File file2 = new File(FileType.PIPE, 0, mWriteQueueSize);
+
+        return registerFilePair(fdNumber1, file1, fdNumber2, file2);
+    }
+
+    private ParcelFileDescriptor[] registerFilePair(
+            int fdNumber1, File file1, int fdNumber2, File file2) {
+        file1.sink = file2;
+        file1.source = file2;
+        file2.sink = file1;
+        file2.source = file1;
+
+        mFiles.put(fdNumber1, file1);
+        mFiles.put(fdNumber2, file2);
+        return new ParcelFileDescriptor[] {
+            newParcelFileDescriptor(fdNumber1), newParcelFileDescriptor(fdNumber2)};
+    }
+
+    @Override
+    public short getPollInMask() {
+        return POLLIN;
+    }
+
+    @Override
+    public short getPollOutMask() {
+        return POLLOUT;
+    }
+
+    @Override
+    public synchronized int poll(StructPollfd[] fds, int timeoutMs) throws IOException {
+        if (timeoutMs < 0) {
+            timeoutMs = (int) TimeUnit.HOURS.toMillis(1);  // Make "infinite" equal to 1 hour.
+        }
+
+        if (fds == null || fds.length > 1000) {
+            throw newIOException("poll", "Invalid fds param");
+        }
+        for (StructPollfd pollFd : fds) {
+            getFile("poll", pollFd.fd);
+        }
+
+        int waitCallCount = 0;
+        final long deadline = monotonicTimeMillis() + timeoutMs;
+        while (true) {
+            if (mHasRateLimitedData) {
+                mHasRateLimitedData = false;
+                for (File file : mFiles.values()) {
+                    if (file.inboundLimiter.getLastRequestReduction() != 0) {
+                        copyFileBuffers(file.source, file);
+                    }
+                    if (file.outboundLimiter.getLastRequestReduction() != 0) {
+                        copyFileBuffers(file, file.sink);
+                    }
+                }
+            }
+
+            final int readyCount = calculateReadyCount(fds);
+            if (readyCount > 0) {
+                if (ENABLE_FINE_DEBUG) {
+                    Log.v(mLogTag, logStr("Poll returns " + readyCount
+                            + " after " + waitCallCount + " wait calls"));
+                }
+                return readyCount;
+            }
+
+            long remainingTimeoutMs = deadline - monotonicTimeMillis();
+            if (remainingTimeoutMs <= 0) {
+                if (ENABLE_FINE_DEBUG) {
+                    Log.v(mLogTag, logStr("Poll timeout " + timeoutMs
+                            + "ms after " + waitCallCount + " wait calls"));
+                }
+                return 0;
+            }
+
+            if (mHasRateLimitedData) {
+                remainingTimeoutMs = Math.min(RateLimiter.BUCKET_DURATION_MS, remainingTimeoutMs);
+            }
+
+            try {
+                wait(remainingTimeoutMs);
+            } catch (InterruptedException e) {
+                // Ignore and retry
+            }
+            waitCallCount++;
+        }
+    }
+
+    private int calculateReadyCount(StructPollfd[] fds) {
+        int fdCount = 0;
+        for (StructPollfd pollFd : fds) {
+            pollFd.revents = 0;
+
+            File file = getFileOrNull(pollFd.fd);
+            if (file == null) {
+                Log.w(mLogTag, logStr("Ignoring FD concurrently closed by a buggy app: "
+                        + getFileDebugName(pollFd.fd)));
+                continue;
+            }
+
+            if (ENABLE_FINE_DEBUG) {
+                Log.v(mLogTag, logStr("calculateReadyCount fd=" + getFileDebugName(pollFd.fd)
+                        + ", events=" + pollFd.events + ", eof=" + file.isEndOfStream
+                        + ", r=" + (file.readQueue != null ? file.readQueue.size() : -1)
+                        + ", w=" + (file.writeQueue != null ? file.writeQueue.freeSize() : -1)));
+            }
+
+            if ((pollFd.events & POLLIN) != 0) {
+                if (file.readQueue != null && file.readQueue.size() != 0) {
+                    pollFd.revents |= POLLIN;
+                }
+                if (file.isEndOfStream) {
+                    pollFd.revents |= POLLHUP;
+                }
+            }
+
+            if ((pollFd.events & POLLOUT) != 0) {
+                if (file.type == FileType.PIPE && file.sink.openCount == 0) {
+                    pollFd.revents |= POLLERR;
+                }
+                if (file.writeQueue != null && file.writeQueue.freeSize() != 0) {
+                    pollFd.revents |= POLLOUT;
+                }
+            }
+
+            if (pollFd.revents != 0) {
+                fdCount++;
+            }
+        }
+        return fdCount;
+    }
+
+    private int getNextFd(String func) throws IOException {
+        if (mFileNumberGen > 100000) {
+            throw newIOException(func, "Too many files open");
+        }
+
+        return mFileNumberGen++;
+    }
+
+    private static IOException newIOException(String func, String message) {
+        return new IOException(message + ", func=" + func);
+    }
+
+    public static void checkBoundaries(String func, byte[] buffer, int pos, int len)
+            throws IOException {
+        if (((buffer.length | pos | len) < 0 || pos > buffer.length - len)) {
+            throw newIOException(func, "Invalid array bounds");
+        }
+    }
+
+    private ParcelFileDescriptor newParcelFileDescriptor(int fdNumber) {
+        try {
+            return new ParcelFileDescriptor(newFileDescriptor(fdNumber));
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private FileDescriptor newFileDescriptor(int fdNumber) {
+        try {
+            return FD_CONSTRUCTOR.newInstance(Integer.valueOf(fdNumber));
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public int getFileDescriptorNumber(FileDescriptor fd) {
+        try {
+            return (Integer) FD_FIELD_DESCRIPTOR.get(fd);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void setFileDescriptorNumber(FileDescriptor fd, int fdNumber) {
+        try {
+            FD_FIELD_DESCRIPTOR.set(fd, Integer.valueOf(fdNumber));
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private String logStr(String message) {
+        return "[FakeOs " + (monotonicTimeMillis() - mStartTime) + "] " + message;
+    }
+
+    private class File {
+        final FileType type;
+        final CircularByteBuffer readQueue;
+        final CircularByteBuffer writeQueue;
+        final RateLimiter inboundLimiter = new RateLimiter(FakeOsAccess.this, Integer.MAX_VALUE);
+        final RateLimiter outboundLimiter = new RateLimiter(FakeOsAccess.this, Integer.MAX_VALUE);
+        String name;
+        int openCount = 1;
+        boolean isBlocking = true;
+        File sink;
+        File source;
+        boolean isEndOfStream;
+
+        File(FileType type, int readQueueSize, int writeQueueSize) {
+            this.type = type;
+            readQueue = (readQueueSize > 0 ? new CircularByteBuffer(readQueueSize) : null);
+            writeQueue = (writeQueueSize > 0 ? new CircularByteBuffer(writeQueueSize) : null);
+        }
+
+        void decreaseRefCount() {
+            if (openCount <= 0) {
+                throw new IllegalStateException();
+            }
+            openCount--;
+        }
+
+        void checkNonBlocking(String func) throws IOException {
+            if (isBlocking) {
+                throw newIOException(func, "File in blocking mode");
+            }
+        }
+    }
+
+    static {
+        try {
+            FD_CONSTRUCTOR = FileDescriptor.class.getDeclaredConstructor(int.class);
+            FD_CONSTRUCTOR.setAccessible(true);
+
+            Field descriptorIntField;
+            try {
+                descriptorIntField = FileDescriptor.class.getDeclaredField("descriptor");
+            } catch (NoSuchFieldException e) {
+                descriptorIntField = FileDescriptor.class.getDeclaredField("fd");
+            }
+            FD_FIELD_DESCRIPTOR = descriptorIntField;
+            FD_FIELD_DESCRIPTOR.setAccessible(true);
+
+            PFD_FIELD_DESCRIPTOR = ParcelFileDescriptor.class.getDeclaredField("mFd");
+            PFD_FIELD_DESCRIPTOR.setAccessible(true);
+
+            PFD_FIELD_GUARD = ParcelFileDescriptor.class.getDeclaredField("mGuard");
+            PFD_FIELD_GUARD.setAccessible(true);
+
+            CLOSE_GUARD_METHOD_CLOSE = Class.forName("dalvik.system.CloseGuard")
+                .getDeclaredMethod("close");
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/async/RateLimiter.java b/staticlibs/testutils/devicetests/com/android/testutils/async/RateLimiter.java
new file mode 100644
index 0000000..d5cca0a
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/async/RateLimiter.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils.async;
+
+import com.android.net.module.util.async.OsAccess;
+
+import java.util.Arrays;
+
+/**
+ * Limits the number of bytes processed to the given maximum of bytes per second.
+ *
+ * The limiter tracks the total for the past second, along with sums for each 10ms
+ * in the past second, allowing the total to be adjusted as the time passes.
+ */
+public final class RateLimiter {
+    private static final int PERIOD_DURATION_MS = 1000;
+    private static final int BUCKET_COUNT = 100;
+
+    public static final int BUCKET_DURATION_MS = PERIOD_DURATION_MS / BUCKET_COUNT;
+
+    private final OsAccess mOsAccess;
+    private final int[] mStatBuckets = new int[BUCKET_COUNT];
+    private int mMaxPerPeriodBytes;
+    private int mMaxPerBucketBytes;
+    private int mRecordedPeriodBytes;
+    private long mLastLimitTimestamp;
+    private int mLastRequestReduction;
+
+    public RateLimiter(OsAccess osAccess, int bytesPerSecond) {
+        mOsAccess = osAccess;
+        setBytesPerSecond(bytesPerSecond);
+        clear();
+    }
+
+    public int getBytesPerSecond() {
+        return mMaxPerPeriodBytes;
+    }
+
+    public void setBytesPerSecond(int bytesPerSecond) {
+        mMaxPerPeriodBytes = bytesPerSecond;
+        mMaxPerBucketBytes = Math.max(1, (mMaxPerPeriodBytes / BUCKET_COUNT) * 2);
+    }
+
+    public void clear() {
+        mLastLimitTimestamp = mOsAccess.monotonicTimeMillis();
+        mRecordedPeriodBytes = 0;
+        Arrays.fill(mStatBuckets, 0);
+    }
+
+    public static int limit(RateLimiter limiter1, RateLimiter limiter2, int requestedBytes) {
+        final long now = limiter1.mOsAccess.monotonicTimeMillis();
+        final int allowedCount = Math.min(limiter1.calculateLimit(now, requestedBytes),
+            limiter2.calculateLimit(now, requestedBytes));
+        limiter1.recordBytes(now, requestedBytes, allowedCount);
+        limiter2.recordBytes(now, requestedBytes, allowedCount);
+        return allowedCount;
+    }
+
+    public int limit(int requestedBytes) {
+        final long now = mOsAccess.monotonicTimeMillis();
+        final int allowedCount = calculateLimit(now, requestedBytes);
+        recordBytes(now, requestedBytes, allowedCount);
+        return allowedCount;
+    }
+
+    public int getLastRequestReduction() {
+        return mLastRequestReduction;
+    }
+
+    public boolean acceptAllOrNone(int requestedBytes) {
+        final long now = mOsAccess.monotonicTimeMillis();
+        final int allowedCount = calculateLimit(now, requestedBytes);
+        if (allowedCount < requestedBytes) {
+            return false;
+        }
+        recordBytes(now, requestedBytes, allowedCount);
+        return true;
+    }
+
+    private int calculateLimit(long now, int requestedBytes) {
+        // First remove all stale bucket data and adjust the total.
+        final long currentBucketAbsIdx = now / BUCKET_DURATION_MS;
+        final long staleCutoffIdx = currentBucketAbsIdx - BUCKET_COUNT;
+        for (long i = mLastLimitTimestamp / BUCKET_DURATION_MS; i < staleCutoffIdx; i++) {
+            final int idx = (int) (i % BUCKET_COUNT);
+            mRecordedPeriodBytes -= mStatBuckets[idx];
+            mStatBuckets[idx] = 0;
+        }
+
+        final int bucketIdx = (int) (currentBucketAbsIdx % BUCKET_COUNT);
+        final int maxAllowed = Math.min(mMaxPerPeriodBytes - mRecordedPeriodBytes,
+            Math.min(mMaxPerBucketBytes - mStatBuckets[bucketIdx], requestedBytes));
+        return Math.max(0, maxAllowed);
+    }
+
+    private void recordBytes(long now, int requestedBytes, int actualBytes) {
+        mStatBuckets[(int) ((now / BUCKET_DURATION_MS) % BUCKET_COUNT)] += actualBytes;
+        mRecordedPeriodBytes += actualBytes;
+        mLastRequestReduction = requestedBytes - actualBytes;
+        mLastLimitTimestamp = now;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{max=");
+        sb.append(mMaxPerPeriodBytes);
+        sb.append(",max_bucket=");
+        sb.append(mMaxPerBucketBytes);
+        sb.append(",total=");
+        sb.append(mRecordedPeriodBytes);
+        sb.append(",last_red=");
+        sb.append(mLastRequestReduction);
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/async/ReadableDataAnswer.java b/staticlibs/testutils/devicetests/com/android/testutils/async/ReadableDataAnswer.java
new file mode 100644
index 0000000..4bf5527
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/async/ReadableDataAnswer.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils.async;
+
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.util.ArrayList;
+
+public class ReadableDataAnswer implements Answer {
+    private final ArrayList<byte[]> mBuffers = new ArrayList<>();
+    private int mBufferPos;
+
+    public ReadableDataAnswer(byte[] ... buffers) {
+        for (byte[] buffer : buffers) {
+            addBuffer(buffer);
+        }
+    }
+
+    public void addBuffer(byte[] buffer) {
+        if (buffer.length != 0) {
+            mBuffers.add(buffer);
+        }
+    }
+
+    public int getRemainingSize() {
+        int totalSize = 0;
+        for (byte[] buffer : mBuffers) {
+            totalSize += buffer.length;
+        }
+        return totalSize - mBufferPos;
+    }
+
+    private void cleanupBuffers() {
+        if (!mBuffers.isEmpty() && mBufferPos == mBuffers.get(0).length) {
+            mBuffers.remove(0);
+            mBufferPos = 0;
+        }
+    }
+
+    @Override
+    public Object answer(InvocationOnMock invocation) throws Throwable {
+        cleanupBuffers();
+
+        if (mBuffers.isEmpty()) {
+            return Integer.valueOf(0);
+        }
+
+        byte[] src = mBuffers.get(0);
+
+        byte[] dst = invocation.<byte[]>getArgument(0);
+        int dstPos = invocation.<Integer>getArgument(1);
+        int dstLen = invocation.<Integer>getArgument(2);
+
+        int copyLen = Math.min(dstLen, src.length - mBufferPos);
+        System.arraycopy(src, mBufferPos, dst, dstPos, copyLen);
+        mBufferPos += copyLen;
+
+        cleanupBuffers();
+        return Integer.valueOf(copyLen);
+    }
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/filters/CtsNetTestCasesMaxTargetSdk30.kt b/staticlibs/testutils/devicetests/com/android/testutils/filters/CtsNetTestCasesMaxTargetSdk30.kt
new file mode 100644
index 0000000..843c41e
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/filters/CtsNetTestCasesMaxTargetSdk30.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils.filters
+
+/**
+ * Only run this test in the CtsNetTestCasesMaxTargetSdk30 suite.
+ */
+annotation class CtsNetTestCasesMaxTargetSdk30(val reason: String)
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/filters/CtsNetTestCasesMaxTargetSdk31.kt b/staticlibs/testutils/devicetests/com/android/testutils/filters/CtsNetTestCasesMaxTargetSdk31.kt
new file mode 100644
index 0000000..be0103d
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/filters/CtsNetTestCasesMaxTargetSdk31.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils.filters
+
+/**
+ * Only run this test in the CtsNetTestCasesMaxTargetSdk31 suite.
+ */
+annotation class CtsNetTestCasesMaxTargetSdk31(val reason: String)
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/filters/CtsNetTestCasesMaxTargetSdk33.kt b/staticlibs/testutils/devicetests/com/android/testutils/filters/CtsNetTestCasesMaxTargetSdk33.kt
new file mode 100644
index 0000000..5af890f
--- /dev/null
+++ b/staticlibs/testutils/devicetests/com/android/testutils/filters/CtsNetTestCasesMaxTargetSdk33.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils.filters
+
+/**
+ * Only run this test in the CtsNetTestCasesMaxTargetSdk33 suite.
+ */
+annotation class CtsNetTestCasesMaxTargetSdk33(val reason: String)
diff --git a/staticlibs/testutils/host/com/android/testutils/ConnectivityTestTargetPreparer.kt b/staticlibs/testutils/host/com/android/testutils/ConnectivityTestTargetPreparer.kt
new file mode 100644
index 0000000..3fc74aa
--- /dev/null
+++ b/staticlibs/testutils/host/com/android/testutils/ConnectivityTestTargetPreparer.kt
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import com.android.ddmlib.testrunner.TestResult
+import com.android.tradefed.config.Option
+import com.android.tradefed.invoker.TestInformation
+import com.android.tradefed.result.CollectingTestListener
+import com.android.tradefed.result.ddmlib.DefaultRemoteAndroidTestRunner
+import com.android.tradefed.targetprep.BaseTargetPreparer
+import com.android.tradefed.targetprep.TargetSetupError
+import com.android.tradefed.targetprep.suite.SuiteApkInstaller
+
+private const val CONNECTIVITY_CHECKER_APK = "ConnectivityTestPreparer.apk"
+private const val CONNECTIVITY_PKG_NAME = "com.android.testutils.connectivitypreparer"
+private const val CONNECTIVITY_CHECK_CLASS = "$CONNECTIVITY_PKG_NAME.ConnectivityCheckTest"
+// As per the <instrumentation> defined in the checker manifest
+private const val CONNECTIVITY_CHECK_RUNNER_NAME = "androidx.test.runner.AndroidJUnitRunner"
+private const val IGNORE_CONN_CHECK_OPTION = "ignore-connectivity-check"
+
+/**
+ * A target preparer that sets up and verifies a device for connectivity tests.
+ *
+ * For quick and dirty local testing, the connectivity check can be disabled by running tests with
+ * "atest -- \
+ * --test-arg com.android.testutils.ConnectivityTestTargetPreparer:ignore-connectivity-check:true".
+ */
+open class ConnectivityTestTargetPreparer : BaseTargetPreparer() {
+    private val installer = SuiteApkInstaller()
+
+    @Option(name = IGNORE_CONN_CHECK_OPTION,
+            description = "Disables the check for mobile data and wifi")
+    private var ignoreConnectivityCheck = false
+
+    override fun setUp(testInformation: TestInformation) {
+        if (isDisabled) return
+        disableGmsUpdate(testInformation)
+        runPreparerApk(testInformation)
+    }
+
+    private fun runPreparerApk(testInformation: TestInformation) {
+        installer.setCleanApk(true)
+        installer.addTestFileName(CONNECTIVITY_CHECKER_APK)
+        installer.setShouldGrantPermission(true)
+        installer.setUp(testInformation)
+
+        val runner = DefaultRemoteAndroidTestRunner(
+                CONNECTIVITY_PKG_NAME,
+                CONNECTIVITY_CHECK_RUNNER_NAME,
+                testInformation.device.iDevice)
+        runner.runOptions = "--no-hidden-api-checks"
+
+        val receiver = CollectingTestListener()
+        if (!testInformation.device.runInstrumentationTests(runner, receiver)) {
+            throw TargetSetupError("Device state check failed to complete",
+                    testInformation.device.deviceDescriptor)
+        }
+
+        val runResult = receiver.currentRunResults
+        if (runResult.isRunFailure) {
+            throw TargetSetupError("Failed to check device state before the test: " +
+                    runResult.runFailureMessage, testInformation.device.deviceDescriptor)
+        }
+
+        val ignoredTestClasses = mutableSetOf<String>()
+        if (ignoreConnectivityCheck) {
+            ignoredTestClasses.add(CONNECTIVITY_CHECK_CLASS)
+        }
+
+        val errorMsg = runResult.testResults.mapNotNull { (testDescription, testResult) ->
+            if (TestResult.TestStatus.FAILURE != testResult.status ||
+                    ignoredTestClasses.contains(testDescription.className)) {
+                null
+            } else {
+                "$testDescription: ${testResult.stackTrace}"
+            }
+        }.joinToString("\n")
+        if (errorMsg.isBlank()) return
+
+        throw TargetSetupError("Device setup checks failed. Check the test bench: \n$errorMsg",
+                testInformation.device.deviceDescriptor)
+    }
+
+    private fun disableGmsUpdate(testInformation: TestInformation) {
+        // This will be a no-op on devices without root (su) or not using gservices, but that's OK.
+        testInformation.device.executeShellCommand("su 0 am broadcast " +
+                "-a com.google.gservices.intent.action.GSERVICES_OVERRIDE " +
+                "-e finsky.play_services_auto_update_enabled false")
+    }
+
+    private fun clearGmsUpdateOverride(testInformation: TestInformation) {
+        testInformation.device.executeShellCommand("su 0 am broadcast " +
+                "-a com.google.gservices.intent.action.GSERVICES_OVERRIDE " +
+                "--esn finsky.play_services_auto_update_enabled")
+    }
+
+    override fun tearDown(testInformation: TestInformation, e: Throwable?) {
+        if (isTearDownDisabled) return
+        installer.tearDown(testInformation, e)
+        clearGmsUpdateOverride(testInformation)
+    }
+}
diff --git a/staticlibs/testutils/host/com/android/testutils/DisableConfigSyncTargetPreparer.kt b/staticlibs/testutils/host/com/android/testutils/DisableConfigSyncTargetPreparer.kt
new file mode 100644
index 0000000..63f05a6
--- /dev/null
+++ b/staticlibs/testutils/host/com/android/testutils/DisableConfigSyncTargetPreparer.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import com.android.tradefed.invoker.TestInformation
+import com.android.tradefed.targetprep.BaseTargetPreparer
+
+/**
+ * A target preparer that disables DeviceConfig sync while running a test.
+ *
+ * Without this preparer, tests that rely on stable values of DeviceConfig flags, for example to
+ * test behavior when setting the flag and resetting it afterwards, may flake as the flags may
+ * be synced with remote servers during the test.
+ */
+class DisableConfigSyncTargetPreparer : BaseTargetPreparer() {
+    private var syncDisabledOriginalValue = "none"
+
+    override fun setUp(testInfo: TestInformation) {
+        if (isDisabled) return
+        syncDisabledOriginalValue = readSyncDisabledOriginalValue(testInfo)
+
+        // The setter is the same in current and legacy S versions
+        testInfo.exec("cmd device_config set_sync_disabled_for_tests until_reboot")
+    }
+
+    override fun tearDown(testInfo: TestInformation, e: Throwable?) {
+        if (isTearDownDisabled) return
+        // May fail harmlessly if called before S
+        testInfo.exec("cmd device_config set_sync_disabled_for_tests $syncDisabledOriginalValue")
+    }
+
+    private fun readSyncDisabledOriginalValue(testInfo: TestInformation): String {
+        return when (val reply = testInfo.exec("cmd device_config get_sync_disabled_for_tests")) {
+            "until_reboot", "persistent", "none" -> reply
+            // Reply does not match known modes, try legacy commands used on S and some T builds
+            else -> when (testInfo.exec("cmd device_config is_sync_disabled_for_tests")) {
+                // The legacy command just said "true" for "until_reboot" or "persistent". There is
+                // no way to know which one was used, so just reset to "until_reboot" to be
+                // conservative.
+                "true" -> "until_reboot"
+                else -> "none"
+            }
+        }
+    }
+}
+
+private fun TestInformation.exec(cmd: String) = this.device.executeShellCommand(cmd)
\ No newline at end of file
diff --git a/staticlibs/testutils/hostdevice/com/android/net/module/util/TrackRecord.kt b/staticlibs/testutils/hostdevice/com/android/net/module/util/TrackRecord.kt
new file mode 100644
index 0000000..f24e4f1
--- /dev/null
+++ b/staticlibs/testutils/hostdevice/com/android/net/module/util/TrackRecord.kt
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.net.module.util
+
+import java.util.concurrent.TimeUnit
+import java.util.concurrent.locks.Condition
+import java.util.concurrent.locks.ReentrantLock
+import java.util.concurrent.locks.StampedLock
+import kotlin.concurrent.withLock
+
+/**
+ * A List that additionally offers the ability to append via the add() method, and to retrieve
+ * an element by its index optionally waiting for it to become available.
+ */
+interface TrackRecord<E> : List<E> {
+    /**
+     * Adds an element to this queue, waking up threads waiting for one. Returns true, as
+     * per the contract for List.
+     */
+    fun add(e: E): Boolean
+
+    /**
+     * Returns the first element after {@param pos}, possibly blocking until one is available, or
+     * null if no such element can be found within the timeout.
+     * If a predicate is given, only elements matching the predicate are returned.
+     *
+     * @param timeoutMs how long, in milliseconds, to wait at most (best effort approximation).
+     * @param pos the position at which to start polling.
+     * @param predicate an optional predicate to filter elements to be returned.
+     * @return an element matching the predicate, or null if timeout.
+     */
+    fun poll(timeoutMs: Long, pos: Int, predicate: (E) -> Boolean = { true }): E?
+}
+
+/**
+ * A thread-safe implementation of TrackRecord that is backed by an ArrayList.
+ *
+ * This class also supports the creation of a read-head for easier single-thread access.
+ * Refer to the documentation of {@link ArrayTrackRecord.ReadHead}.
+ */
+class ArrayTrackRecord<E> : TrackRecord<E> {
+    private val lock = ReentrantLock()
+    private val condition = lock.newCondition()
+    // Backing store. This stores the elements in this ArrayTrackRecord.
+    private val elements = ArrayList<E>()
+
+    // The list iterator for RecordingQueue iterates over a snapshot of the collection at the
+    // time the operator is created. Because TrackRecord is only ever mutated by appending,
+    // that makes this iterator thread-safe as it sees an effectively immutable List.
+    class ArrayTrackRecordIterator<E>(
+        private val list: ArrayList<E>,
+        start: Int,
+        private val end: Int
+    ) : ListIterator<E> {
+        var index = start
+        override fun hasNext() = index < end
+        override fun next() = list[index++]
+        override fun hasPrevious() = index > 0
+        override fun nextIndex() = index + 1
+        override fun previous() = list[--index]
+        override fun previousIndex() = index - 1
+    }
+
+    // List<E> implementation
+    override val size get() = lock.withLock { elements.size }
+    override fun contains(element: E) = lock.withLock { elements.contains(element) }
+    override fun containsAll(elements: Collection<E>) = lock.withLock {
+        this.elements.containsAll(elements)
+    }
+    override operator fun get(index: Int) = lock.withLock { elements[index] }
+    override fun indexOf(element: E): Int = lock.withLock { elements.indexOf(element) }
+    override fun lastIndexOf(element: E): Int = lock.withLock { elements.lastIndexOf(element) }
+    override fun isEmpty() = lock.withLock { elements.isEmpty() }
+    override fun listIterator(index: Int) = ArrayTrackRecordIterator(elements, index, size)
+    override fun listIterator() = listIterator(0)
+    override fun iterator() = listIterator()
+    override fun subList(fromIndex: Int, toIndex: Int): List<E> = lock.withLock {
+        elements.subList(fromIndex, toIndex)
+    }
+
+    // TrackRecord<E> implementation
+    override fun add(e: E): Boolean {
+        lock.withLock {
+            elements.add(e)
+            condition.signalAll()
+        }
+        return true
+    }
+    override fun poll(timeoutMs: Long, pos: Int, predicate: (E) -> Boolean) = lock.withLock {
+        elements.getOrNull(pollForIndexReadLocked(timeoutMs, pos, predicate))
+    }
+
+    // For convenience
+    fun getOrNull(pos: Int, predicate: (E) -> Boolean) = lock.withLock {
+        if (pos < 0 || pos > size) null else elements.subList(pos, size).find(predicate)
+    }
+
+    // Returns the index of the next element whose position is >= pos matching the predicate, if
+    // necessary waiting until such a time that such an element is available, with a timeout.
+    // If no such element is found within the timeout -1 is returned.
+    private fun pollForIndexReadLocked(timeoutMs: Long, pos: Int, predicate: (E) -> Boolean): Int {
+        val deadline = System.currentTimeMillis() + timeoutMs
+        var index = pos
+        do {
+            while (index < elements.size) {
+                if (predicate(elements[index])) return index
+                ++index
+            }
+        } while (condition.await(deadline - System.currentTimeMillis()))
+        return -1
+    }
+
+    /**
+     * Returns a ReadHead over this ArrayTrackRecord. The returned ReadHead is tied to the
+     * current thread.
+     */
+    fun newReadHead() = ReadHead()
+
+    /**
+     * ReadHead is an object that helps users of ArrayTrackRecord keep track of how far
+     * it has read this far in the ArrayTrackRecord. A ReadHead is always associated with
+     * a single instance of ArrayTrackRecord. Multiple ReadHeads can be created and used
+     * on the same instance of ArrayTrackRecord concurrently, and the ArrayTrackRecord
+     * instance can also be used concurrently. ReadHead maintains the current index that is
+     * the next to be read, and calls this the "mark".
+     *
+     * In a ReadHead, {@link poll(Long, (E) -> Boolean)} works similarly to a LinkedBlockingQueue.
+     * It can be called repeatedly and will return the elements as they arrive.
+     *
+     * Intended usage looks something like this :
+     * val TrackRecord<MyObject> record = ArrayTrackRecord().newReadHead()
+     * Thread().start {
+     *   // do stuff
+     *   record.add(something)
+     *   // do stuff
+     * }
+     *
+     * val obj1 = record.poll(timeout)
+     * // do something with obj1
+     * val obj2 = record.poll(timeout)
+     * // do something with obj2
+     *
+     * The point is that the caller does not have to track the mark like it would have to if
+     * it was using ArrayTrackRecord directly.
+     *
+     * Thread safety :
+     * A ReadHead delegates all TrackRecord methods to its associated ArrayTrackRecord, and
+     * inherits its thread-safe properties for all the TrackRecord methods.
+     *
+     * Poll() operates under its own set of rules that only allow execution on multiple threads
+     * within constrained boundaries, and never concurrently or pseudo-concurrently. This is
+     * because concurrent calls to poll() fundamentally do not make sense. poll() will move
+     * the mark according to what events remained to be read by this read head, and therefore
+     * if multiple threads were calling poll() concurrently on the same ReadHead, what
+     * happens to the mark and the return values could not be useful because there is no way to
+     * provide either a guarantee not to skip objects nor a guarantee about the mark position at
+     * the exit of poll(). This is even more true in the presence of a predicate to filter
+     * returned elements, because one thread might be filtering out the events the other is
+     * interested in. For this reason, this class will fail-fast if any concurrent access is
+     * detected with ConcurrentAccessException.
+     * It is possible to use poll() on different threads as long as the following can be
+     * guaranteed : one thread must call poll() for the last time, then execute a write barrier,
+     * then the other thread must execute a read barrier before calling poll() for the first time.
+     * This allows in particular to call poll in @Before and @After methods in JUnit unit tests,
+     * because JUnit will enforce those barriers by creating the testing thread after executing
+     * @Before and joining the thread after executing @After.
+     *
+     * peek() can be used by multiple threads concurrently, but only if no thread is calling
+     * poll() outside of the boundaries above. For simplicity, it can be considered that peek()
+     * is safe to call only when poll() is safe to call.
+     *
+     * Polling concurrently from the same ArrayTrackRecord is supported by creating multiple
+     * ReadHeads on the same instance of ArrayTrackRecord (or of course by using ArrayTrackRecord
+     * directly). Each ReadHead is then guaranteed to see all events always and
+     * guarantees are made on the value of the mark upon return. {@see poll(Long, (E) -> Boolean)}
+     * for details. Be careful to create each ReadHead on the thread it is meant to be used on, or
+     * to have a clear synchronization point between creation and use.
+     *
+     * Users of a ReadHead can ask for the current position of the mark at any time, on a thread
+     * where it's safe to call peek(). This mark can be used later to replay the history of events
+     * either on this ReadHead, on the associated ArrayTrackRecord or on another ReadHead
+     * associated with the same ArrayTrackRecord. It might look like this in the reader thread :
+     *
+     * val markAtStart = record.mark
+     * // Start processing interesting events
+     * while (val element = record.poll(timeout) { it.isInteresting() }) {
+     *   // Do something with element
+     * }
+     * // Look for stuff that happened while searching for interesting events
+     * val firstElementReceived = record.getOrNull(markAtStart)
+     * val firstSpecialElement = record.getOrNull(markAtStart) { it.isSpecial() }
+     * // Get the first special element since markAtStart, possibly blocking until one is available
+     * val specialElement = record.poll(timeout, markAtStart) { it.isSpecial() }
+     */
+    inner class ReadHead : TrackRecord<E> by this@ArrayTrackRecord {
+        // This lock only controls access to the readHead member below. The ArrayTrackRecord
+        // object has its own synchronization following different (and more usual) semantics.
+        // See the comment on the ReadHead class for details.
+        private val slock = StampedLock()
+        private var readHead = 0
+
+        // A special mark used to track the start of the last poll() operation.
+        private var pollMark = 0
+
+        /**
+         * @return the current value of the mark.
+         */
+        var mark
+            get() = checkThread { readHead }
+            set(v: Int) = rewind(v)
+        fun rewind(v: Int) {
+            val stamp = slock.tryWriteLock()
+            if (0L == stamp) concurrentAccessDetected()
+            readHead = v
+            pollMark = v
+            slock.unlockWrite(stamp)
+        }
+
+        private fun <T> checkThread(r: (Long) -> T): T {
+            // tryOptimisticRead is a read barrier, guarantees writes from other threads are visible
+            // after it
+            val stamp = slock.tryOptimisticRead()
+            val result = r(stamp)
+            // validate also performs a read barrier, guaranteeing that if validate returns true,
+            // then any change either happens-before tryOptimisticRead, or happens-after validate.
+            if (!slock.validate(stamp)) concurrentAccessDetected()
+            return result
+        }
+
+        private fun concurrentAccessDetected(): Nothing {
+            throw ConcurrentModificationException(
+                    "ReadHeads can't be used concurrently. Check your threading model.")
+        }
+
+        /**
+         * Returns the first element after the mark, optionally blocking until one is available, or
+         * null if no such element can be found within the timeout.
+         * If a predicate is given, only elements matching the predicate are returned.
+         *
+         * Upon return the mark will be set to immediately after the returned element, or after
+         * the last element in the queue if null is returned. This means this method will always
+         * skip elements that do not match the predicate, even if it returns null.
+         *
+         * This method can only be used by the thread that created this ManagedRecordingQueue.
+         * If used on another thread, this throws IllegalStateException.
+         *
+         * @param timeoutMs how long, in milliseconds, to wait at most (best effort approximation).
+         * @param predicate an optional predicate to filter elements to be returned.
+         * @return an element matching the predicate, or null if timeout.
+         */
+        fun poll(timeoutMs: Long, predicate: (E) -> Boolean = { true }): E? {
+            val stamp = slock.tryWriteLock()
+            if (0L == stamp) concurrentAccessDetected()
+            pollMark = readHead
+            try {
+                lock.withLock {
+                    val index = pollForIndexReadLocked(timeoutMs, readHead, predicate)
+                    readHead = if (index < 0) size else index + 1
+                    return getOrNull(index)
+                }
+            } finally {
+                slock.unlockWrite(stamp)
+            }
+        }
+
+        /**
+         * Returns a list of events that were observed since the last time poll() was called on this
+         * ReadHead.
+         *
+         * @return list of events since poll() was called.
+         */
+        fun backtrace(): List<E> {
+            val stamp = slock.tryReadLock()
+            if (0L == stamp) concurrentAccessDetected()
+
+            try {
+                lock.withLock {
+                    return ArrayList(subList(pollMark, mark))
+                }
+            } finally {
+                slock.unlockRead(stamp)
+            }
+        }
+
+        /**
+         * Returns the first element after the mark or null. This never blocks.
+         *
+         * This method is subject to threading restrictions. It can be used concurrently on
+         * multiple threads but not if any other thread might be executing poll() at the same
+         * time. See the class comment for details.
+         */
+        fun peek(): E? = checkThread { getOrNull(readHead) }
+    }
+}
+
+// Private helper
+private fun Condition.await(timeoutMs: Long) = this.await(timeoutMs, TimeUnit.MILLISECONDS)
diff --git a/staticlibs/testutils/hostdevice/com/android/testutils/Cleanup.kt b/staticlibs/testutils/hostdevice/com/android/testutils/Cleanup.kt
new file mode 100644
index 0000000..9f28234
--- /dev/null
+++ b/staticlibs/testutils/hostdevice/com/android/testutils/Cleanup.kt
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:JvmName("Cleanup")
+
+package com.android.testutils
+
+import com.android.testutils.FunctionalUtils.ThrowingRunnable
+import com.android.testutils.FunctionalUtils.ThrowingSupplier
+import javax.annotation.CheckReturnValue
+
+/**
+ * Utility to do cleanup in tests without replacing exceptions with those from a finally block.
+ *
+ * This utility is meant for tests that want to do cleanup after they execute their test
+ * logic, whether the test fails (and throws) or not.
+ *
+ * The usual way of doing this is to have a try{}finally{} block and put cleanup in finally{}.
+ * However, if any code in finally{} throws, the exception thrown in finally{} is thrown before
+ * any thrown in try{} ; that means errors reported from tests are from finally{} even if they
+ * have been caused by errors in try{}. This is unhelpful in tests, because it results in a
+ * stacktrace for a symptom rather than a stacktrace for a cause.
+ *
+ * To alleviate this, tests are encouraged to make sure the code in finally{} can't throw, or
+ * that the code in try{} can't cause it to fail. This is not always realistic ; not only does
+ * it require the developer thinks about complex interactions of code, test code often relies
+ * on bricks provided by other teams, not controlled by the team writing the test, which may
+ * start throwing with an update (see b/198998862 for an example).
+ *
+ * This utility allows a different approach : it offers a new construct, tryTest{}cleanup{} similar
+ * to try{}finally{}, but that will always throw the first exception that happens. In other words,
+ * if only tryTest{} throws or only cleanup{} throws, that exception will be thrown, but contrary
+ * to the standard try{}finally{}, if both throws, the construct throws the exception that happened
+ * in tryTest{} rather than the one that happened in cleanup{}.
+ *
+ * Kotlin usage is as try{}finally{}, but with multiple finally{} blocks :
+ * tryTest {
+ *   testing code
+ * } cleanupStep {
+ *   cleanup code 1
+ * } cleanupStep {
+ *   cleanup code 2
+ * } cleanup {
+ *   cleanup code 3
+ * }
+ * Catch blocks can be added with the following syntax :
+ * tryTest {
+ *   testing code
+ * }.catch<ExceptionType> { it ->
+ *   do something to it
+ * }
+ *
+ * Java doesn't allow this kind of syntax, so instead a function taking lambdas is provided.
+ * testAndCleanup(() -> {
+ *   testing code
+ * }, () -> {
+ *   cleanup code 1
+ * }, () -> {
+ *   cleanup code 2
+ * });
+ */
+
+@CheckReturnValue
+fun <T> tryTest(block: () -> T) = TryExpr(
+        try {
+            Result.success(block())
+        } catch (e: Throwable) {
+            Result.failure(e)
+        })
+
+// Some downstream branches have an older kotlin that doesn't know about value classes.
+// TODO : Change this to "value class" when aosp no longer merges into such branches.
+@Suppress("INLINE_CLASS_DEPRECATED")
+inline class TryExpr<T>(val result: Result<T>) {
+    inline infix fun <reified E : Throwable> catch(block: (E) -> T): TryExpr<T> {
+        val originalException = result.exceptionOrNull()
+        if (originalException !is E) return this
+        return TryExpr(try {
+            Result.success(block(originalException))
+        } catch (e: Throwable) {
+            Result.failure(e)
+        })
+    }
+
+    @CheckReturnValue
+    inline infix fun cleanupStep(block: () -> Unit): TryExpr<T> {
+        try {
+            block()
+        } catch (e: Throwable) {
+            val originalException = result.exceptionOrNull()
+            return TryExpr(if (null == originalException) {
+                Result.failure(e)
+            } else {
+                originalException.addSuppressed(e)
+                Result.failure(originalException)
+            })
+        }
+        return this
+    }
+
+    inline infix fun cleanup(block: () -> Unit): T = cleanupStep(block).result.getOrThrow()
+}
+
+// Java support
+fun <T> testAndCleanup(tryBlock: ThrowingSupplier<T>, vararg cleanupBlock: ThrowingRunnable): T {
+    return cleanupBlock.fold(tryTest { tryBlock.get() }) { previousExpr, nextCleanup ->
+        previousExpr.cleanupStep { nextCleanup.run() }
+    }.cleanup {}
+}
+fun testAndCleanup(tryBlock: ThrowingRunnable, vararg cleanupBlock: ThrowingRunnable) {
+    return testAndCleanup(ThrowingSupplier { tryBlock.run() }, *cleanupBlock)
+}
diff --git a/staticlibs/testutils/hostdevice/com/android/testutils/ConcurrentUtils.kt b/staticlibs/testutils/hostdevice/com/android/testutils/ConcurrentUtils.kt
new file mode 100644
index 0000000..af4f96d
--- /dev/null
+++ b/staticlibs/testutils/hostdevice/com/android/testutils/ConcurrentUtils.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:JvmName("ConcurrentUtils")
+
+package com.android.testutils
+
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import kotlin.system.measureTimeMillis
+
+// For Java usage
+fun durationOf(fn: Runnable) = measureTimeMillis { fn.run() }
+
+fun CountDownLatch.await(timeoutMs: Long): Boolean = await(timeoutMs, TimeUnit.MILLISECONDS)
diff --git a/staticlibs/testutils/hostdevice/com/android/testutils/ConnectivityModuleTest.kt b/staticlibs/testutils/hostdevice/com/android/testutils/ConnectivityModuleTest.kt
new file mode 100644
index 0000000..ec485fe
--- /dev/null
+++ b/staticlibs/testutils/hostdevice/com/android/testutils/ConnectivityModuleTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+/**
+ * Indicates that the test covers functionality that was rolled out in a connectivity module update.
+ *
+ * Annotated MTS tests will typically only be run in Connectivity/Tethering module MTS, and not when
+ * only other modules (such as NetworkStack) have been updated.
+ * Annotated CTS tests will always be run, as the Connectivity module should be at least newer than
+ * the CTS suite.
+ */
+annotation class ConnectivityModuleTest
diff --git a/staticlibs/testutils/hostdevice/com/android/testutils/DnsResolverModuleTest.kt b/staticlibs/testutils/hostdevice/com/android/testutils/DnsResolverModuleTest.kt
new file mode 100644
index 0000000..9e97d51
--- /dev/null
+++ b/staticlibs/testutils/hostdevice/com/android/testutils/DnsResolverModuleTest.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+/**
+ * Indicates that the test covers functionality that was rolled out in a resolv module update.
+ */
+annotation class DnsResolverModuleTest
diff --git a/staticlibs/testutils/hostdevice/com/android/testutils/FileUtils.kt b/staticlibs/testutils/hostdevice/com/android/testutils/FileUtils.kt
new file mode 100644
index 0000000..678f977
--- /dev/null
+++ b/staticlibs/testutils/hostdevice/com/android/testutils/FileUtils.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+// This function is private because the 2 is hardcoded here, and is not correct if not called
+// directly from __LINE__ or __FILE__.
+private fun callerStackTrace(): StackTraceElement = try {
+    throw RuntimeException()
+} catch (e: RuntimeException) {
+    e.stackTrace[2] // 0 is here, 1 is get() in __FILE__ or __LINE__
+}
+val __FILE__: String get() = callerStackTrace().fileName
+val __LINE__: Int get() = callerStackTrace().lineNumber
diff --git a/staticlibs/testutils/hostdevice/com/android/testutils/FunctionalUtils.java b/staticlibs/testutils/hostdevice/com/android/testutils/FunctionalUtils.java
new file mode 100644
index 0000000..da36e4d
--- /dev/null
+++ b/staticlibs/testutils/hostdevice/com/android/testutils/FunctionalUtils.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils;
+
+import java.util.function.Supplier;
+
+/**
+ * A class grouping some utilities to deal with exceptions.
+ */
+public class FunctionalUtils {
+    /**
+     * Like a Consumer, but declared to throw an exception.
+     * @param <T>
+     */
+    @FunctionalInterface
+    public interface ThrowingConsumer<T> {
+        /** @see java.util.function.Consumer */
+        void accept(T t) throws Exception;
+    }
+
+    /**
+     * Like a Supplier, but declared to throw an exception.
+     * @param <T>
+     */
+    @FunctionalInterface
+    public interface ThrowingSupplier<T> {
+        /** @see java.util.function.Supplier */
+        T get() throws Exception;
+    }
+
+    /**
+     * Like a Runnable, but declared to throw an exception.
+     */
+    @FunctionalInterface
+    public interface ThrowingRunnable {
+        /** @see java.lang.Runnable */
+        void run() throws Exception;
+    }
+
+    /**
+     * Convert a supplier that throws into one that doesn't.
+     *
+     * The returned supplier returns null in cases where the source throws.
+     */
+    public static <T> Supplier<T> ignoreExceptions(ThrowingSupplier<T> func) {
+        return () -> {
+            try {
+                return func.get();
+            } catch (Exception e) {
+                return null;
+            }
+        };
+    }
+
+    /**
+     * Convert a runnable that throws into one that doesn't.
+     *
+     * All exceptions are ignored by the returned Runnable.
+     */
+    public static Runnable ignoreExceptions(ThrowingRunnable r) {
+        return () -> {
+            try {
+                r.run();
+            } catch (Exception e) {
+            }
+        };
+    }
+
+    // Java has Function<T, R> and BiFunction<T, U, V> but nothing for higher-arity functions.
+    // Function3 is what Kotlin and Scala use (they also have higher-arity variants, with
+    // FunctionN taking N arguments, as the JVM does not have variadic formal parameters)
+    /**
+     * A function with three arguments.
+     * @param <TArg1> Type of the first argument
+     * @param <TArg2> Type of the second argument
+     * @param <TArg3> Type of the third argument
+     * @param <TResult> Type of the return value
+     */
+    public interface Function3<TArg1, TArg2, TArg3, TResult> {
+        /**
+         * Apply the function to the arguments
+         */
+        TResult apply(TArg1 a1, TArg2 a2, TArg3 a3);
+    }
+}
diff --git a/staticlibs/testutils/hostdevice/com/android/testutils/MiscAsserts.kt b/staticlibs/testutils/hostdevice/com/android/testutils/MiscAsserts.kt
new file mode 100644
index 0000000..1883387
--- /dev/null
+++ b/staticlibs/testutils/hostdevice/com/android/testutils/MiscAsserts.kt
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:JvmName("MiscAsserts")
+
+package com.android.testutils
+
+import com.android.testutils.FunctionalUtils.ThrowingRunnable
+import java.lang.reflect.Modifier
+import kotlin.system.measureTimeMillis
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
+
+private const val TAG = "Connectivity unit test"
+
+fun <T> assertEmpty(ts: Array<T>) = ts.size.let { len ->
+    assertEquals(0, len, "Expected empty array, but length was $len")
+}
+
+fun <T> assertEmpty(ts: Collection<T>) = ts.size.let { len ->
+    assertEquals(0, len, "Expected empty collection, but length was $len")
+}
+
+fun <T> assertLength(expected: Int, got: Array<T>) = got.size.let { len ->
+    assertEquals(expected, len, "Expected array of length $expected, but was $len for $got")
+}
+
+fun <T> assertLength(expected: Int, got: List<T>) = got.size.let { len ->
+    assertEquals(expected, len, "Expected list of length $expected, but was $len for $got")
+}
+
+// Bridge method to help write this in Java. If you're writing Kotlin, consider using
+// kotlin.test.assertFailsWith instead, as that method is reified and inlined.
+fun <T : Exception> assertThrows(expected: Class<T>, block: ThrowingRunnable): T {
+    return assertFailsWith(expected.kotlin) { block.run() }
+}
+
+fun <T : Exception> assertThrows(msg: String, expected: Class<T>, block: ThrowingRunnable): T {
+    return assertFailsWith(expected.kotlin, msg) { block.run() }
+}
+
+fun <T> assertEqualBothWays(o1: T, o2: T) {
+    assertTrue(o1 == o2)
+    assertTrue(o2 == o1)
+}
+
+fun <T> assertNotEqualEitherWay(o1: T, o2: T) {
+    assertFalse(o1 == o2)
+    assertFalse(o2 == o1)
+}
+
+fun assertStringContains(got: String, want: String) {
+    assertTrue(got.contains(want), "$got did not contain \"${want}\"")
+}
+
+fun assertContainsExactly(actual: IntArray, vararg expected: Int) {
+    // IntArray#sorted() returns a list, so it's fine to test with equals()
+    assertEquals(actual.sorted(), expected.sorted(),
+            "$actual does not contain exactly $expected")
+}
+
+fun assertContainsStringsExactly(actual: Array<String>, vararg expected: String) {
+    assertEquals(actual.sorted(), expected.sorted(),
+            "$actual does not contain exactly $expected")
+}
+
+fun <T> assertContainsAll(list: Collection<T>, vararg elems: T) {
+    assertContainsAll(list, elems.asList())
+}
+
+fun <T> assertContainsAll(list: Collection<T>, elems: Collection<T>) {
+    elems.forEach { assertTrue(list.contains(it), "$it not in list") }
+}
+
+fun assertRunsInAtMost(descr: String, timeLimit: Long, fn: Runnable) {
+    assertRunsInAtMost(descr, timeLimit) { fn.run() }
+}
+
+fun assertRunsInAtMost(descr: String, timeLimit: Long, fn: () -> Unit) {
+    val timeTaken = measureTimeMillis(fn)
+    val msg = String.format("%s: took %dms, limit was %dms", descr, timeTaken, timeLimit)
+    assertTrue(timeTaken <= timeLimit, msg)
+}
+
+/**
+ * Verifies that the number of nonstatic fields in a java class equals a given count.
+ * Note: this is essentially not useful for Kotlin code where fields are not really a thing.
+ *
+ * This assertion serves as a reminder to update test code around it if fields are added
+ * after the test is written.
+ * @param count Expected number of nonstatic fields in the class.
+ * @param clazz Class to test.
+ */
+fun <T> assertFieldCountEquals(count: Int, clazz: Class<T>) {
+    assertEquals(count, clazz.declaredFields.filter {
+        !Modifier.isStatic(it.modifiers) && !Modifier.isTransient(it.modifiers)
+    }.size)
+}
+
+fun <T> assertSameElements(expected: List<T>, actual: List<T>) {
+    val expectedSet: HashSet<T> = HashSet(expected)
+    assertEquals(expectedSet.size, expected.size, "expected list contains duplicates")
+    val actualSet: HashSet<T> = HashSet(actual)
+    assertEquals(actualSet.size, actual.size, "actual list contains duplicates")
+    assertEquals(expectedSet, actualSet)
+}
\ No newline at end of file
diff --git a/staticlibs/testutils/hostdevice/com/android/testutils/NetworkStackModuleTest.kt b/staticlibs/testutils/hostdevice/com/android/testutils/NetworkStackModuleTest.kt
new file mode 100644
index 0000000..fe312a0
--- /dev/null
+++ b/staticlibs/testutils/hostdevice/com/android/testutils/NetworkStackModuleTest.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+/**
+ * Indicates that the test covers functionality that was rolled out in a NetworkStack module update.
+ */
+annotation class NetworkStackModuleTest
diff --git a/staticlibs/testutils/hostdevice/com/android/testutils/PacketFilter.kt b/staticlibs/testutils/hostdevice/com/android/testutils/PacketFilter.kt
new file mode 100644
index 0000000..1bb6d68
--- /dev/null
+++ b/staticlibs/testutils/hostdevice/com/android/testutils/PacketFilter.kt
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+import java.net.Inet4Address
+import java.util.function.Predicate
+
+// Some of the below constants are duplicated with NetworkStackConstants, but this is a hostdevice
+// library usable for host-side tests, so device-side utils are not usable, and there is no
+// host-side non-test library to host common constants.
+private const val ETHER_TYPE_OFFSET = 12
+private const val ETHER_HEADER_LENGTH = 14
+private const val IPV4_PROTOCOL_OFFSET = ETHER_HEADER_LENGTH + 9
+private const val IPV6_PROTOCOL_OFFSET = ETHER_HEADER_LENGTH + 6
+private const val IPV4_CHECKSUM_OFFSET = ETHER_HEADER_LENGTH + 10
+private const val IPV4_DST_OFFSET = ETHER_HEADER_LENGTH + 16
+private const val IPV4_HEADER_LENGTH = 20
+private const val IPV6_HEADER_LENGTH = 40
+private const val IPV4_PAYLOAD_OFFSET = ETHER_HEADER_LENGTH + IPV4_HEADER_LENGTH
+private const val IPV6_PAYLOAD_OFFSET = ETHER_HEADER_LENGTH + IPV6_HEADER_LENGTH
+private const val UDP_HEADER_LENGTH = 8
+private const val BOOTP_OFFSET = IPV4_PAYLOAD_OFFSET + UDP_HEADER_LENGTH
+private const val BOOTP_TID_OFFSET = BOOTP_OFFSET + 4
+private const val BOOTP_CLIENT_MAC_OFFSET = BOOTP_OFFSET + 28
+private const val DHCP_OPTIONS_OFFSET = BOOTP_OFFSET + 240
+private const val ARP_OPCODE_OFFSET = ETHER_HEADER_LENGTH + 6
+
+/**
+ * A [Predicate] that matches a [ByteArray] if it contains the specified [bytes] at the specified
+ * [offset].
+ */
+class OffsetFilter(val offset: Int, vararg val bytes: Byte) : Predicate<ByteArray> {
+    override fun test(packet: ByteArray) =
+            bytes.withIndex().all { it.value == packet[offset + it.index] }
+}
+
+private class UdpPortFilter(
+    private val udpOffset: Int,
+    private val src: Short?,
+    private val dst: Short?
+) : Predicate<ByteArray> {
+    override fun test(t: ByteArray): Boolean {
+        if (src != null && !OffsetFilter(udpOffset,
+                        src.toInt().ushr(8).toByte(), src.toByte()).test(t)) {
+            return false
+        }
+
+        if (dst != null && !OffsetFilter(udpOffset + 2,
+                        dst.toInt().ushr(8).toByte(), dst.toByte()).test(t)) {
+            return false
+        }
+        return true
+    }
+}
+
+/**
+ * A [Predicate] that matches ethernet-encapped packets that contain an UDP over IPv4 datagram.
+ */
+class IPv4UdpFilter @JvmOverloads constructor(
+    srcPort: Short? = null,
+    dstPort: Short? = null
+) : Predicate<ByteArray> {
+    private val impl = OffsetFilter(ETHER_TYPE_OFFSET, 0x08, 0x00 /* IPv4 */).and(
+            OffsetFilter(IPV4_PROTOCOL_OFFSET, 17 /* UDP */)).and(
+            UdpPortFilter(IPV4_PAYLOAD_OFFSET, srcPort, dstPort))
+    override fun test(t: ByteArray) = impl.test(t)
+}
+
+/**
+ * A [Predicate] that matches ethernet-encapped packets that contain an UDP over IPv6 datagram.
+ */
+class IPv6UdpFilter @JvmOverloads constructor(
+    srcPort: Short? = null,
+    dstPort: Short? = null
+) : Predicate<ByteArray> {
+    private val impl = OffsetFilter(ETHER_TYPE_OFFSET, 0x86.toByte(), 0xdd.toByte() /* IPv6 */).and(
+            OffsetFilter(IPV6_PROTOCOL_OFFSET, 17 /* UDP */)).and(
+            UdpPortFilter(IPV6_PAYLOAD_OFFSET, srcPort, dstPort))
+    override fun test(t: ByteArray) = impl.test(t)
+}
+
+/**
+ * A [Predicate] that matches ethernet-encapped packets sent to the specified IPv4 destination.
+ */
+class IPv4DstFilter(dst: Inet4Address) : Predicate<ByteArray> {
+    private val impl = OffsetFilter(IPV4_DST_OFFSET, *dst.address)
+    override fun test(t: ByteArray) = impl.test(t)
+}
+
+/**
+ * A [Predicate] that matches ethernet-encapped ARP requests.
+ */
+class ArpRequestFilter : Predicate<ByteArray> {
+    private val impl = OffsetFilter(ETHER_TYPE_OFFSET, 0x08, 0x06 /* ARP */)
+            .and(OffsetFilter(ARP_OPCODE_OFFSET, 0x00, 0x01 /* request */))
+    override fun test(t: ByteArray) = impl.test(t)
+}
+
+/**
+ * A [Predicate] that matches ethernet-encapped DHCP packets sent from a DHCP client.
+ */
+class DhcpClientPacketFilter : Predicate<ByteArray> {
+    private val impl = IPv4UdpFilter(srcPort = 68, dstPort = 67)
+    override fun test(t: ByteArray) = impl.test(t)
+}
+
+/**
+ * A [Predicate] that matches a [ByteArray] if it contains a ethernet-encapped DHCP packet that
+ * contains the specified option with the specified [bytes] as value.
+ */
+class DhcpOptionFilter(val option: Byte, vararg val bytes: Byte) : Predicate<ByteArray> {
+    override fun test(packet: ByteArray): Boolean {
+        val option = findDhcpOption(packet, option) ?: return false
+        return option.contentEquals(bytes)
+    }
+}
+
+/**
+ * Find a DHCP option in a packet and return its value, if found.
+ */
+fun findDhcpOption(packet: ByteArray, option: Byte): ByteArray? =
+        findOptionOffset(packet, option, DHCP_OPTIONS_OFFSET)?.let {
+            val optionLen = packet[it + 1]
+            return packet.copyOfRange(it + 2 /* type, length bytes */, it + 2 + optionLen)
+        }
+
+private tailrec fun findOptionOffset(packet: ByteArray, option: Byte, searchOffset: Int): Int? {
+    if (packet.size <= searchOffset + 2 /* type, length bytes */) return null
+
+    return if (packet[searchOffset] == option) searchOffset else {
+        val optionLen = packet[searchOffset + 1]
+        findOptionOffset(packet, option, searchOffset + 2 + optionLen)
+    }
+}
diff --git a/staticlibs/testutils/hostdevice/com/android/testutils/SkipMainlinePresubmit.kt b/staticlibs/testutils/hostdevice/com/android/testutils/SkipMainlinePresubmit.kt
new file mode 100644
index 0000000..5952365
--- /dev/null
+++ b/staticlibs/testutils/hostdevice/com/android/testutils/SkipMainlinePresubmit.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+/**
+ * Skip the test in presubmit runs for the reason specified in [reason].
+ *
+ * This annotation is typically used to document limitations that prevent a test from being
+ * executed in presubmit on older builds.
+ */
+annotation class SkipMainlinePresubmit(val reason: String)
diff --git a/staticlibs/testutils/hostdevice/com/android/testutils/SkipPresubmit.kt b/staticlibs/testutils/hostdevice/com/android/testutils/SkipPresubmit.kt
new file mode 100644
index 0000000..69ed048
--- /dev/null
+++ b/staticlibs/testutils/hostdevice/com/android/testutils/SkipPresubmit.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils
+
+/**
+ * Skip the test in presubmit runs for the reason specified in [reason].
+ *
+ * This annotation is typically used to document hardware or test bench limitations.
+ */
+annotation class SkipPresubmit(val reason: String)
\ No newline at end of file
