diff --git a/tests/cts/hostside/Android.bp b/tests/cts/hostside/Android.bp
index 741c961..47b114b 100644
--- a/tests/cts/hostside/Android.bp
+++ b/tests/cts/hostside/Android.bp
@@ -24,7 +24,6 @@
     // Tag this module as a cts test artifact
     test_suites: [
         "cts",
-        "vts10",
         "general-tests",
     ],
 }
diff --git a/tests/cts/hostside/app/Android.bp b/tests/cts/hostside/app/Android.bp
index e129be7..9903756 100644
--- a/tests/cts/hostside/app/Android.bp
+++ b/tests/cts/hostside/app/Android.bp
@@ -35,7 +35,6 @@
     // Tag this module as a cts test artifact
     test_suites: [
         "cts",
-        "vts10",
         "general-tests",
     ],
 }
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java
index bb492a1..f9e30b6 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java
@@ -78,6 +78,17 @@
         stopForegroundService();
         assertAppIdle(true);
         assertBackgroundNetworkAccess(false);
+
+        // Set Idle after foreground service start.
+        launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_FOREGROUND_SERVICE);
+        setAppIdle(true);
+        addPowerSaveModeWhitelist(TEST_PKG);
+        removePowerSaveModeWhitelist(TEST_PKG);
+        assertForegroundServiceNetworkAccess();
+        stopForegroundService();
+        assertAppIdle(true);
+        assertBackgroundNetworkAccess(false);
+
     }
 
     @Test
diff --git a/tests/cts/hostside/app2/Android.bp b/tests/cts/hostside/app2/Android.bp
index a6e9b11..8e27931 100644
--- a/tests/cts/hostside/app2/Android.bp
+++ b/tests/cts/hostside/app2/Android.bp
@@ -23,7 +23,6 @@
     // Tag this module as a cts test artifact
     test_suites: [
         "cts",
-        "vts10",
         "general-tests",
     ],
     certificate: ":cts-net-app",
diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp
index 4c00428..528171a 100644
--- a/tests/cts/net/Android.bp
+++ b/tests/cts/net/Android.bp
@@ -21,7 +21,6 @@
 
     libs: [
         "voip-common",
-        "org.apache.http.legacy",
         "android.test.base",
     ],
 
@@ -40,14 +39,11 @@
     static_libs: [
         "FrameworksNetCommonTests",
         "TestNetworkStackLib",
-        "compatibility-device-util-axt",
         "core-tests-support",
         "cts-net-utils",
         "ctstestrunner-axt",
-        "ctstestserver",
         "junit",
         "junit-params",
-        "mockwebserver",
         "net-utils-framework-common",
         "truth-prebuilt",
     ],
@@ -66,7 +62,6 @@
     defaults: ["CtsNetTestCasesDefaults"],
     test_suites: [
         "cts",
-        "vts10",
         "general-tests",
     ],
     test_config_template: "AndroidTestTemplate.xml",
diff --git a/tests/cts/net/AndroidTestTemplate.xml b/tests/cts/net/AndroidTestTemplate.xml
index 4e93751..78a01e2 100644
--- a/tests/cts/net/AndroidTestTemplate.xml
+++ b/tests/cts/net/AndroidTestTemplate.xml
@@ -20,7 +20,7 @@
     <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
 
-    <option name="config-descriptor:metadata" key="mainline-param" value="CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk" />
+    <option name="config-descriptor:metadata" key="mainline-param" value="CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex" />
     <option name="not-shardable" value="true" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/tests/cts/net/TEST_MAPPING b/tests/cts/net/TEST_MAPPING
index 9167c98..7545cb0 100644
--- a/tests/cts/net/TEST_MAPPING
+++ b/tests/cts/net/TEST_MAPPING
@@ -12,7 +12,7 @@
   ],
   "mainline-presubmit": [
     {
-      "name": "CtsNetTestCasesLatestSdk[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk]",
+      "name": "CtsNetTestCasesLatestSdk[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]",
       "options": [
         {
           "exclude-annotation": "com.android.testutils.SkipPresubmit"
diff --git a/tests/cts/net/api23Test/Android.bp b/tests/cts/net/api23Test/Android.bp
index 0ce9826..e43a5e8 100644
--- a/tests/cts/net/api23Test/Android.bp
+++ b/tests/cts/net/api23Test/Android.bp
@@ -45,7 +45,6 @@
     // Tag this module as a cts test artifact
     test_suites: [
         "cts",
-        "vts10",
         "general-tests",
     ],
 
diff --git a/tests/cts/net/appForApi23/Android.bp b/tests/cts/net/appForApi23/Android.bp
index 399c199..cec6d7f 100644
--- a/tests/cts/net/appForApi23/Android.bp
+++ b/tests/cts/net/appForApi23/Android.bp
@@ -26,7 +26,6 @@
     // Tag this module as a cts test artifact
     test_suites: [
         "cts",
-        "vts10",
         "general-tests",
     ],
 
diff --git a/tests/cts/net/ipsec/Android.bp b/tests/cts/net/ipsec/Android.bp
deleted file mode 100644
index 948cc05..0000000
--- a/tests/cts/net/ipsec/Android.bp
+++ /dev/null
@@ -1,48 +0,0 @@
-// 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.
-
-android_test {
-    name: "CtsIkeTestCases",
-    defaults: ["cts_defaults"],
-
-    // Include both the 32 and 64 bit versions
-    compile_multilib: "both",
-
-    libs: [
-        "android.net.ipsec.ike.stubs.system",
-        "android.test.base",
-    ],
-
-    srcs: [
-        "src/**/*.java",
-        ":ike-test-utils",
-    ],
-
-    static_libs: [
-        "androidx.test.ext.junit",
-        "compatibility-device-util-axt",
-        "ctstestrunner-axt",
-        "net-tests-utils",
-    ],
-
-    platform_apis: true,
-
-    // Tag this module as a cts test artifact
-    test_suites: [
-        "cts",
-        "mts",
-        "vts",
-        "general-tests",
-    ],
-}
diff --git a/tests/cts/net/ipsec/AndroidManifest.xml b/tests/cts/net/ipsec/AndroidManifest.xml
deleted file mode 100644
index de7d23c..0000000
--- a/tests/cts/net/ipsec/AndroidManifest.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * 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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.net.ipsec.cts"
-    android:targetSandboxVersion="2">
-
-    <!--Allow tests to call ConnectivityManager#getActiveNetwork()-->
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
-    <!--Allow tests to create socket -->
-    <uses-permission android:name="android.permission.INTERNET"/>
-
-    <application android:label="CtsIkeTestCases">
-        <uses-library android:name="android.test.runner" />
-        <uses-library android:name="android.net.ipsec.ike" />
-    </application>
-
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="android.net.ipsec.cts"
-                     android:label="CTS tests of android.net.ipsec">
-        <meta-data android:name="listener"
-            android:value="com.android.cts.runner.CtsTestRunListener" />
-    </instrumentation>
-
-</manifest>
diff --git a/tests/cts/net/ipsec/AndroidTest.xml b/tests/cts/net/ipsec/AndroidTest.xml
deleted file mode 100644
index cd5c118..0000000
--- a/tests/cts/net/ipsec/AndroidTest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<!-- 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.
--->
-<configuration description="Config for CTS IKE test cases">
-    <option name="test-suite-tag" value="cts" />
-    <option name="config-descriptor:metadata" key="component" value="networking" />
-    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
-    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
-    <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
-    <option name="not-shardable" value="true" />
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsIkeTestCases.apk" />
-    </target_preparer>
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.net.ipsec.cts" />
-        <option name="hidden-api-checks" value="false" />
-    </test>
-    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
-        <option name="mainline-module-package-name" value="com.google.android.ipsec" />
-    </object>
-</configuration>
diff --git a/tests/cts/net/ipsec/OWNERS b/tests/cts/net/ipsec/OWNERS
deleted file mode 100644
index 26407ff..0000000
--- a/tests/cts/net/ipsec/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-lorenzo@google.com
-nharold@google.com
-satk@google.com
diff --git a/tests/cts/net/ipsec/assets/key/client-a-private-key.key b/tests/cts/net/ipsec/assets/key/client-a-private-key.key
deleted file mode 100644
index 22736e9..0000000
--- a/tests/cts/net/ipsec/assets/key/client-a-private-key.key
+++ /dev/null
@@ -1,28 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCv3CvrCGokJSWL
-8ufg6u9LCW4EezztbktqpC0T+1m98+Ujb8/eJ0L2UaxZ9QBSBAqXxEoeZFBeoCXu
-7ezUd5qUPfIhKLAkQTAyU/KgfhHh4i+MJK5ghPbGDE8r2gKUXOkM6M5//ZCpmu0K
-Y/9uQL6D5bkxEaoWegEO+wSXm+hTTgKDtQKHvRibgdcZkcY0cA9JsLrC/nIkP+7i
-pbBT+VTuV6gAnKIV0nq8zvI3A/Z3nAb5Gt0g3qaqs59StDT0QtuXzJkuZEo3XSrS
-jon+8NjSNzqVbJj95B7+uiH+91VEbMtJYFz2MipKvJQDK7Zlxke7LxRj2xJfksJK
-a92/ncxfAgMBAAECggEAQztaMvW5lm35J8LKsWs/5qEJRX9T8LWs8W0oqq36Riub
-G2wgvR6ndAIPcSjAYZqX7iOl7m6NZ0+0kN63HxdGqovwKIskpAekBGmhpYftED1n
-zh0r6UyMB3UnQ22KdOv8UOokIDxxdNX8728BdUYdT9Ggdkj5jLRB+VcwD0IUlNvo
-zzTpURV9HEd87uiLqd4AAHXSI0lIHI5U43z24HI/J6/YbYHT3Rlh6CIa/LuwO6vL
-gFkgqg0/oy6yJtjrHtzNVA67F0UaH62hR4YFgbC0d955SJnDidWOv/0j2DMpfdCc
-9kFAcPwUSyykvUSLnGIKWSG4D+6gzIeAeUx4oO7kMQKBgQDVNRkX8AGTHyLg+NXf
-spUWWcodwVioXl30Q7h6+4bt8OI61UbhQ7wX61wvJ1cySpa2KOYa2UdagQVhGhhL
-ADu363R77uXF/jZgzVfmjjyJ2nfDqRgHWRTlSkuq/jCOQCz7VIPHRZg5WL/9D4ms
-TAqMjpzqeMfFZI+w4/+xpcJIuQKBgQDTKBy+ZuerWrVT9icWKvLU58o5EVj/2yFy
-GJvKm+wRAAX2WzjNnR4HVd4DmMREVz1BPYby0j5gqjvtDsxYYu39+NT7JvMioLLK
-QPj+7k5geYgNqVgCxB1vP89RhY2X1RLrN9sTXOodgFPeXOQWNYITkGp3eQpx4nTJ
-+K/al3oB1wKBgAjnc8nVIyuyxDEjE0OJYMKTM2a0uXAmqMPXxC+Wq5bqVXhhidlE
-i+lv0eTCPtkB1nN7F8kNQ/aaps/cWCFhvBy9P5shagUvzbOTP9WIIS0cq53HRRKh
-fMbqqGhWv05hjb9dUzeSR341n6cA7B3++v3Nwu3j52vt/DZF/1q68nc5AoGAS0SU
-ImbKE/GsizZGLoe2sZ/CHN+LKwCwhlwxRGKaHmE0vuE7eUeVSaYZEo0lAPtb8WJ+
-NRYueASWgeTxgFwbW5mUScZTirdfo+rPFwhZVdhcYApKPgosN9i2DOgfVcz1BnWN
-mPRY25U/0BaqkyQVruWeneG+kGPZn5kPDktKiVcCgYEAkzwU9vCGhm7ZVALvx/zR
-wARz2zsL9ImBc0P4DK1ld8g90FEnHrEgeI9JEwz0zFHOCMLwlk7kG0Xev7vfjZ7G
-xSqtQYOH33Qp6rtBOgdt8hSyDFvakvDl6bqhAw52gelO3MTpAB1+ZsfZ5gFx13Jf
-idNFcaIrC52PtZIH7QCzdDY=
------END PRIVATE KEY-----
\ No newline at end of file
diff --git a/tests/cts/net/ipsec/assets/pem/client-a-end-cert.pem b/tests/cts/net/ipsec/assets/pem/client-a-end-cert.pem
deleted file mode 100644
index e82da85..0000000
--- a/tests/cts/net/ipsec/assets/pem/client-a-end-cert.pem
+++ /dev/null
@@ -1,21 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDaDCCAlCgAwIBAgIIcorRI3n29E4wDQYJKoZIhvcNAQELBQAwQTELMAkGA1UE
-BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxIDAeBgNVBAMTF3R3by5jYS50ZXN0LmFu
-ZHJvaWQubmV0MB4XDTIwMDQxNDA1MDM0OVoXDTIzMDQxNDA1MDM0OVowRTELMAkG
-A1UEBhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxJDAiBgNVBAMTG2NsaWVudC50ZXN0
-LmlrZS5hbmRyb2lkLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-AK/cK+sIaiQlJYvy5+Dq70sJbgR7PO1uS2qkLRP7Wb3z5SNvz94nQvZRrFn1AFIE
-CpfESh5kUF6gJe7t7NR3mpQ98iEosCRBMDJT8qB+EeHiL4wkrmCE9sYMTyvaApRc
-6Qzozn/9kKma7Qpj/25AvoPluTERqhZ6AQ77BJeb6FNOAoO1Aoe9GJuB1xmRxjRw
-D0mwusL+ciQ/7uKlsFP5VO5XqACcohXSerzO8jcD9necBvka3SDepqqzn1K0NPRC
-25fMmS5kSjddKtKOif7w2NI3OpVsmP3kHv66If73VURsy0lgXPYyKkq8lAMrtmXG
-R7svFGPbEl+Swkpr3b+dzF8CAwEAAaNgMF4wHwYDVR0jBBgwFoAUcqSu1uRYT/DL
-bLoDNUz38nGvCKQwJgYDVR0RBB8wHYIbY2xpZW50LnRlc3QuaWtlLmFuZHJvaWQu
-bmV0MBMGA1UdJQQMMAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQCa53tK
-I9RM9/MutZ5KNG2Gfs2cqaPyv8ZRhs90HDWZhkFVu7prywJAxOd2hxxHPsvgurio
-4bKAxnT4EXevgz5YoCbj2TPIL9TdFYh59zZ97XXMxk+SRdypgF70M6ETqKPs3hDP
-ZRMMoHvvYaqaPvp4StSBX9A44gSyjHxVYJkrjDZ0uffKg5lFL5IPvqfdmSRSpGab
-SyGTP4OLTy0QiNV3pBsJGdl0h5BzuTPR9OTl4xgeqqBQy2bDjmfJBuiYyCSCkPi7
-T3ohDYCymhuSkuktHPNG1aKllUJaw0tuZuNydlgdAveXPYfM36uvK0sfd9qr9pAy
-rmkYV2MAWguFeckh
------END CERTIFICATE-----
\ No newline at end of file
diff --git a/tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-one.pem b/tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-one.pem
deleted file mode 100644
index 707e575..0000000
--- a/tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-one.pem
+++ /dev/null
@@ -1,21 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDaDCCAlCgAwIBAgIIIbjMyRn2770wDQYJKoZIhvcNAQELBQAwQjELMAkGA1UE
-BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxITAfBgNVBAMTGHJvb3QuY2EudGVzdC5h
-bmRyb2lkLm5ldDAeFw0xOTA5MzAxODQzMThaFw0yNDA5MjgxODQzMThaMEExCzAJ
-BgNVBAYTAlVTMRAwDgYDVQQKEwdBbmRyb2lkMSAwHgYDVQQDExdvbmUuY2EudGVz
-dC5hbmRyb2lkLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNN
-sRr5Z30rAEw2jrAh/BIekbEy/MvOucAr1w0lxH71p+ybRBx5Bj7G07UGXbL659gm
-meMV6nabY4HjQXNMq22POiJBZj+U+rw34br6waljBttxCmmJac1VvgqNsSspXjRy
-NbiVQdFjyKSX0NOPcEkwANk15mZbOgJBaYYc8jQCY2G/p8eARVBTLJCy8LEwEU6j
-XRv/4eYST79qpBFc7gQQj2FLmh9oppDIvcIVBHwtd1tBoVuehRSud1o8vQRkl/HJ
-Mrwp24nO5YYhmVNSFRtBpmWMSu1KknFUwkOebINUNsKXXHebVa7cP4XIQUL8mRT3
-5X9rFJFSQJE01S3NjNMCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B
-Af8EBAMCAQYwHQYDVR0OBBYEFHK3FIm7g8dxEIwK9zMAO8EWhRYxMB8GA1UdIwQY
-MBaAFEmfqEeF14Nj91ekIpR+sVhCEoAaMA0GCSqGSIb3DQEBCwUAA4IBAQAeMlXT
-TnxZo8oz0204gKZ63RzlgDpJ7SqA3qFG+pV+TiqGfSuVkXuIdOskjxJnA9VxUzrr
-LdMTCn5e0FK6wCYjZ2GT/CD7oD3vSMkzGbLGNcNJhhDHUq8BOLPkPzz/rwQFPBSb
-zr6hsiVXphEt/psGoN7Eu9blPeQaIwMfWnaufAwF664S/3dmCRbNMWSam1qzzz8q
-jr0cDOIMa//ZIAcM16cvoBK6pFGnUmuoJYYRtfpY5MmfCWz0sCJxENIX/lxyhd7N
-FdRALA1ZP3E//Tn2vQoeFjbKaAba527RE26HgHJ9zZDo1nn8J8J/YwYRJdBWM/3S
-LYebNiMtcyB5nIkj
------END CERTIFICATE-----
\ No newline at end of file
diff --git a/tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-two.pem b/tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-two.pem
deleted file mode 100644
index 39808f8..0000000
--- a/tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-two.pem
+++ /dev/null
@@ -1,21 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDZzCCAk+gAwIBAgIIKWCREnNCs+wwDQYJKoZIhvcNAQELBQAwQTELMAkGA1UE
-BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxIDAeBgNVBAMTF29uZS5jYS50ZXN0LmFu
-ZHJvaWQubmV0MB4XDTE5MDkzMDE4NDQwMloXDTI0MDkyODE4NDQwMlowQTELMAkG
-A1UEBhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxIDAeBgNVBAMTF3R3by5jYS50ZXN0
-LmFuZHJvaWQubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxLUa
-RqkYl2m7lUmMnkooqO0DNNY1aN9r7mJc3ndYn5gjkpb3yLgOYPDNLcQerV6uWk/u
-qKudNHed2dInGonl3oxwwv7++6oUvvtrSWLDZlRg16GsdIE1Y98DSMQWkSxevYy9
-Nh6FGTdlBFQVMpiMa8qHEkrOyKsy85yCW1sgzlpGTIBwbDAqYtwe3rgbwyHwUtfy
-0EU++DBcR4ll/pDqB0OQtW5E3AOq2GH1iaGeFLKSUQ5KAbdI8y4/b8IkSDffvxcc
-kXig7S54aLrNlL/ZjQ+H4Chgjj2A5wMucd81+Fb60Udej73ICL9PpMPnXQ1+BVYd
-MJ/txjLNmrOJG9yEHQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB
-/wQEAwIBBjAdBgNVHQ4EFgQUcqSu1uRYT/DLbLoDNUz38nGvCKQwHwYDVR0jBBgw
-FoAUcrcUibuDx3EQjAr3MwA7wRaFFjEwDQYJKoZIhvcNAQELBQADggEBADY461GT
-Rw0dGnD07xaGJcI0i0pV+WnGSrl1s1PAIdMYihJAqYnh10fXbFXLm2WMWVmv/pxs
-FI/xDJno+pd4mCa/sIhm63ar/Nv+lFQmcpIlvSlKnhhV4SLNBeqbVhPBGTCHfrG4
-aIyCwm1KJsnkWbf03crhSskR/2CXIjX6lcAy7K3fE2u1ELpAdH0kMJR7VXkLFLUm
-gqe9YCluR0weMpe2sCaOGzdVzQSmMMCzGP5cxeFR5U6K40kMOpiW11JNmQ06xI/m
-YVkMNwoiV/ITT0/C/g9FxJmkO0mVSLEqxaLS/hNiQNDlroVM0rbxhzviXLI3R3AO
-50VvlOQYGxWed/I=
------END CERTIFICATE-----
\ No newline at end of file
diff --git a/tests/cts/net/ipsec/assets/pem/server-a-self-signed-ca.pem b/tests/cts/net/ipsec/assets/pem/server-a-self-signed-ca.pem
deleted file mode 100644
index 972fd55..0000000
--- a/tests/cts/net/ipsec/assets/pem/server-a-self-signed-ca.pem
+++ /dev/null
@@ -1,20 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDSDCCAjCgAwIBAgIITJQJ6HC1rjwwDQYJKoZIhvcNAQELBQAwQjELMAkGA1UE
-BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxITAfBgNVBAMTGHJvb3QuY2EudGVzdC5h
-bmRyb2lkLm5ldDAeFw0xOTA5MzAxNzU1NTJaFw0yOTA5MjcxNzU1NTJaMEIxCzAJ
-BgNVBAYTAlVTMRAwDgYDVQQKEwdBbmRyb2lkMSEwHwYDVQQDExhyb290LmNhLnRl
-c3QuYW5kcm9pZC5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCT
-q3hGF+JvLaB1xW7KGKmaxiQ7BxX2Sn7cbp7ggoVYXsFlBUuPPv3+Vg5PfPCPhsJ8
-/7w4HyKo3uc/vHs5HpQ7rSd9blhAkfmJci2ULLq73FB8Mix4CzPwMx29RrN1X9bU
-z4G0vJMczIBGxbZ0uw7n8bKcXBV7AIeax+J8lseEZ3k8iSuBkUJqGIpPFKTqByFZ
-A1Lvt47xkON5SZh6c/Oe+o6291wXaCOJUSAKv6PAWZkq9HeD2fqKA/ck9dBaz1M3
-YvzQ9V/7so3/dECjAfKia388h1I6XSGNUM+d5hpxMXpAFgG42eUXHpJ10OjDvSwd
-7ZSC91/kRQewUomEKBK1AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
-AQH/BAQDAgEGMB0GA1UdDgQWBBRJn6hHhdeDY/dXpCKUfrFYQhKAGjANBgkqhkiG
-9w0BAQsFAAOCAQEAig/94aGfHBhZuvbbhwAK4rUNpizmR567u0ZJ+QUEKyAlo9lT
-ZWYHSm7qTAZYvPEjzTQIptnAlxCHePXh3Cfwgo+r82lhG2rcdI03iRyvHWjM8gyk
-BXCJTi0Q08JHHpTP6GnAqpz58qEIFkk8P766zNXdhYrGPOydF+p7MFcb1Zv1gum3
-zmRLt0XUAMfjPUv1Bl8kTKFxH5lkMBLR1E0jnoJoTTfgRPrf9CuFSoh48n7YhoBT
-KV75xZY8b8+SuB0v6BvQmkpKZGoxBjuVsShyG7q1+4JTAtwhiP7BlkDvVkaBEi7t
-WIMFp2r2ZDisHgastNaeYFyzHYz9g1FCCrHQ4w==
------END CERTIFICATE-----
\ No newline at end of file
diff --git a/tests/cts/net/ipsec/src/android/net/eap/cts/EapSessionConfigTest.java b/tests/cts/net/ipsec/src/android/net/eap/cts/EapSessionConfigTest.java
deleted file mode 100644
index c24379d..0000000
--- a/tests/cts/net/ipsec/src/android/net/eap/cts/EapSessionConfigTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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 android.net.eap.cts;
-
-import static android.telephony.TelephonyManager.APPTYPE_USIM;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import android.net.eap.EapSessionConfig;
-import android.net.eap.EapSessionConfig.EapAkaConfig;
-import android.net.eap.EapSessionConfig.EapAkaPrimeConfig;
-import android.net.eap.EapSessionConfig.EapMsChapV2Config;
-import android.net.eap.EapSessionConfig.EapSimConfig;
-import android.net.eap.EapSessionConfig.EapUiccConfig;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class EapSessionConfigTest {
-    // These constants are IANA-defined values and are copies of hidden constants in
-    // frameworks/opt/net/ike/src/java/com/android/internal/net/eap/message/EapData.java.
-    private static final int EAP_TYPE_SIM = 18;
-    private static final int EAP_TYPE_AKA = 23;
-    private static final int EAP_TYPE_MSCHAP_V2 = 26;
-    private static final int EAP_TYPE_AKA_PRIME = 50;
-
-    private static final int SUB_ID = 1;
-    private static final byte[] EAP_IDENTITY = "test@android.net".getBytes();
-    private static final String NETWORK_NAME = "android.net";
-    private static final String EAP_MSCHAPV2_USERNAME = "username";
-    private static final String EAP_MSCHAPV2_PASSWORD = "password";
-
-    @Test
-    public void testBuildWithAllEapMethods() {
-        EapSessionConfig result =
-                new EapSessionConfig.Builder()
-                        .setEapIdentity(EAP_IDENTITY)
-                        .setEapSimConfig(SUB_ID, APPTYPE_USIM)
-                        .setEapAkaConfig(SUB_ID, APPTYPE_USIM)
-                        .setEapAkaPrimeConfig(
-                                SUB_ID,
-                                APPTYPE_USIM,
-                                NETWORK_NAME,
-                                true /* allowMismatchedNetworkNames */)
-                        .setEapMsChapV2Config(EAP_MSCHAPV2_USERNAME, EAP_MSCHAPV2_PASSWORD)
-                        .build();
-
-        assertArrayEquals(EAP_IDENTITY, result.getEapIdentity());
-
-        EapSimConfig eapSimConfig = result.getEapSimConfig();
-        assertNotNull(eapSimConfig);
-        assertEquals(EAP_TYPE_SIM, eapSimConfig.getMethodType());
-        verifyEapUiccConfigCommon(eapSimConfig);
-
-        EapAkaConfig eapAkaConfig = result.getEapAkaConfig();
-        assertNotNull(eapAkaConfig);
-        assertEquals(EAP_TYPE_AKA, eapAkaConfig.getMethodType());
-        verifyEapUiccConfigCommon(eapAkaConfig);
-
-        EapAkaPrimeConfig eapAkaPrimeConfig = result.getEapAkaPrimeConfig();
-        assertNotNull(eapAkaPrimeConfig);
-        assertEquals(EAP_TYPE_AKA_PRIME, eapAkaPrimeConfig.getMethodType());
-        assertEquals(NETWORK_NAME, eapAkaPrimeConfig.getNetworkName());
-        assertTrue(NETWORK_NAME, eapAkaPrimeConfig.allowsMismatchedNetworkNames());
-        verifyEapUiccConfigCommon(eapAkaPrimeConfig);
-
-        EapMsChapV2Config eapMsChapV2Config = result.getEapMsChapV2onfig();
-        assertNotNull(eapMsChapV2Config);
-        assertEquals(EAP_TYPE_MSCHAP_V2, eapMsChapV2Config.getMethodType());
-        assertEquals(EAP_MSCHAPV2_USERNAME, eapMsChapV2Config.getUsername());
-        assertEquals(EAP_MSCHAPV2_PASSWORD, eapMsChapV2Config.getPassword());
-    }
-
-    private void verifyEapUiccConfigCommon(EapUiccConfig config) {
-        assertEquals(SUB_ID, config.getSubId());
-        assertEquals(APPTYPE_USIM, config.getAppType());
-    }
-}
diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java
deleted file mode 100644
index 7fb1b6d..0000000
--- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * 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 android.net.ipsec.ike.cts;
-
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.AF_INET6;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.net.LinkAddress;
-import android.net.ipsec.ike.ChildSaProposal;
-import android.net.ipsec.ike.ChildSessionParams;
-import android.net.ipsec.ike.TransportModeChildSessionParams;
-import android.net.ipsec.ike.TunnelModeChildSessionParams;
-import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv4Address;
-import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv4DhcpServer;
-import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv4DnsServer;
-import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv4Netmask;
-import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv6Address;
-import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv6DnsServer;
-import android.net.ipsec.ike.TunnelModeChildSessionParams.TunnelModeChildConfigRequest;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.net.Inet4Address;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-@RunWith(AndroidJUnit4.class)
-public class ChildSessionParamsTest extends IkeTestBase {
-    private static final int HARD_LIFETIME_SECONDS = (int) TimeUnit.HOURS.toSeconds(3L);
-    private static final int SOFT_LIFETIME_SECONDS = (int) TimeUnit.HOURS.toSeconds(1L);
-
-    // Random proposal. Content doesn't matter
-    private final ChildSaProposal mSaProposal =
-            SaProposalTest.buildChildSaProposalWithCombinedModeCipher();
-
-    private void verifyTunnelModeChildParamsWithDefaultValues(ChildSessionParams childParams) {
-        assertTrue(childParams instanceof TunnelModeChildSessionParams);
-        verifyChildParamsWithDefaultValues(childParams);
-    }
-
-    private void verifyTunnelModeChildParamsWithCustomizedValues(ChildSessionParams childParams) {
-        assertTrue(childParams instanceof TunnelModeChildSessionParams);
-        verifyChildParamsWithCustomizedValues(childParams);
-    }
-
-    private void verifyTransportModeChildParamsWithDefaultValues(ChildSessionParams childParams) {
-        assertTrue(childParams instanceof TransportModeChildSessionParams);
-        verifyChildParamsWithDefaultValues(childParams);
-    }
-
-    private void verifyTransportModeChildParamsWithCustomizedValues(
-            ChildSessionParams childParams) {
-        assertTrue(childParams instanceof TransportModeChildSessionParams);
-        verifyChildParamsWithCustomizedValues(childParams);
-    }
-
-    private void verifyChildParamsWithDefaultValues(ChildSessionParams childParams) {
-        assertEquals(Arrays.asList(mSaProposal), childParams.getSaProposals());
-
-        // Do not do assertEquals to the default values to be avoid being a change-detector test
-        assertTrue(childParams.getHardLifetimeSeconds() > childParams.getSoftLifetimeSeconds());
-        assertTrue(childParams.getSoftLifetimeSeconds() > 0);
-
-        assertEquals(
-                Arrays.asList(DEFAULT_V4_TS, DEFAULT_V6_TS),
-                childParams.getInboundTrafficSelectors());
-        assertEquals(
-                Arrays.asList(DEFAULT_V4_TS, DEFAULT_V6_TS),
-                childParams.getOutboundTrafficSelectors());
-    }
-
-    private void verifyChildParamsWithCustomizedValues(ChildSessionParams childParams) {
-        assertEquals(Arrays.asList(mSaProposal), childParams.getSaProposals());
-
-        assertEquals(HARD_LIFETIME_SECONDS, childParams.getHardLifetimeSeconds());
-        assertEquals(SOFT_LIFETIME_SECONDS, childParams.getSoftLifetimeSeconds());
-
-        assertEquals(
-                Arrays.asList(INBOUND_V4_TS, INBOUND_V6_TS),
-                childParams.getInboundTrafficSelectors());
-        assertEquals(
-                Arrays.asList(OUTBOUND_V4_TS, OUTBOUND_V6_TS),
-                childParams.getOutboundTrafficSelectors());
-    }
-
-    @Test
-    public void testBuildTransportModeParamsWithDefaultValues() {
-        TransportModeChildSessionParams childParams =
-                new TransportModeChildSessionParams.Builder().addSaProposal(mSaProposal).build();
-
-        verifyTransportModeChildParamsWithDefaultValues(childParams);
-    }
-
-    @Test
-    public void testBuildTunnelModeParamsWithDefaultValues() {
-        TunnelModeChildSessionParams childParams =
-                new TunnelModeChildSessionParams.Builder().addSaProposal(mSaProposal).build();
-
-        verifyTunnelModeChildParamsWithDefaultValues(childParams);
-        assertTrue(childParams.getConfigurationRequests().isEmpty());
-    }
-
-    @Test
-    public void testBuildTransportModeParamsWithCustomizedValues() {
-        TransportModeChildSessionParams childParams =
-                new TransportModeChildSessionParams.Builder()
-                        .addSaProposal(mSaProposal)
-                        .setLifetimeSeconds(HARD_LIFETIME_SECONDS, SOFT_LIFETIME_SECONDS)
-                        .addInboundTrafficSelectors(INBOUND_V4_TS)
-                        .addInboundTrafficSelectors(INBOUND_V6_TS)
-                        .addOutboundTrafficSelectors(OUTBOUND_V4_TS)
-                        .addOutboundTrafficSelectors(OUTBOUND_V6_TS)
-                        .build();
-
-        verifyTransportModeChildParamsWithCustomizedValues(childParams);
-    }
-
-    @Test
-    public void testBuildTunnelModeParamsWithCustomizedValues() {
-        TunnelModeChildSessionParams childParams =
-                new TunnelModeChildSessionParams.Builder()
-                        .addSaProposal(mSaProposal)
-                        .setLifetimeSeconds(HARD_LIFETIME_SECONDS, SOFT_LIFETIME_SECONDS)
-                        .addInboundTrafficSelectors(INBOUND_V4_TS)
-                        .addInboundTrafficSelectors(INBOUND_V6_TS)
-                        .addOutboundTrafficSelectors(OUTBOUND_V4_TS)
-                        .addOutboundTrafficSelectors(OUTBOUND_V6_TS)
-                        .build();
-
-        verifyTunnelModeChildParamsWithCustomizedValues(childParams);
-    }
-
-    @Test
-    public void testBuildChildSessionParamsWithConfigReq() {
-        TunnelModeChildSessionParams childParams =
-                new TunnelModeChildSessionParams.Builder()
-                        .addSaProposal(mSaProposal)
-                        .addInternalAddressRequest(AF_INET)
-                        .addInternalAddressRequest(AF_INET6)
-                        .addInternalAddressRequest(AF_INET6)
-                        .addInternalAddressRequest(IPV4_ADDRESS_REMOTE)
-                        .addInternalAddressRequest(IPV6_ADDRESS_REMOTE, IP6_PREFIX_LEN)
-                        .addInternalDnsServerRequest(AF_INET)
-                        .addInternalDnsServerRequest(AF_INET6)
-                        .addInternalDhcpServerRequest(AF_INET)
-                        .addInternalDhcpServerRequest(AF_INET)
-                        .build();
-
-        verifyTunnelModeChildParamsWithDefaultValues(childParams);
-
-        // Verify config request types and number of requests for each type
-        Map<Class<? extends TunnelModeChildConfigRequest>, Integer> expectedAttributeCounts =
-                new HashMap<>();
-        expectedAttributeCounts.put(ConfigRequestIpv4Address.class, 2);
-        expectedAttributeCounts.put(ConfigRequestIpv6Address.class, 3);
-        expectedAttributeCounts.put(ConfigRequestIpv4Netmask.class, 1);
-        expectedAttributeCounts.put(ConfigRequestIpv4DnsServer.class, 1);
-        expectedAttributeCounts.put(ConfigRequestIpv6DnsServer.class, 1);
-        expectedAttributeCounts.put(ConfigRequestIpv4DhcpServer.class, 2);
-        verifyConfigRequestTypes(expectedAttributeCounts, childParams.getConfigurationRequests());
-
-        // Verify specific IPv4 address request
-        Set<Inet4Address> expectedV4Addresses = new HashSet<>();
-        expectedV4Addresses.add(IPV4_ADDRESS_REMOTE);
-        verifySpecificV4AddrConfigReq(expectedV4Addresses, childParams);
-
-        // Verify specific IPv6 address request
-        Set<LinkAddress> expectedV6Addresses = new HashSet<>();
-        expectedV6Addresses.add(new LinkAddress(IPV6_ADDRESS_REMOTE, IP6_PREFIX_LEN));
-        verifySpecificV6AddrConfigReq(expectedV6Addresses, childParams);
-    }
-
-    protected void verifySpecificV4AddrConfigReq(
-            Set<Inet4Address> expectedAddresses, TunnelModeChildSessionParams childParams) {
-        for (TunnelModeChildConfigRequest req : childParams.getConfigurationRequests()) {
-            if (req instanceof ConfigRequestIpv4Address
-                    && ((ConfigRequestIpv4Address) req).getAddress() != null) {
-                Inet4Address address = ((ConfigRequestIpv4Address) req).getAddress();
-
-                // Fail if expectedAddresses does not contain this address
-                assertTrue(expectedAddresses.remove(address));
-            }
-        }
-
-        // Fail if any expected address is not found in result
-        assertTrue(expectedAddresses.isEmpty());
-    }
-
-    protected void verifySpecificV6AddrConfigReq(
-            Set<LinkAddress> expectedAddresses, TunnelModeChildSessionParams childParams) {
-        for (TunnelModeChildConfigRequest req : childParams.getConfigurationRequests()) {
-            if (req instanceof ConfigRequestIpv6Address
-                    && ((ConfigRequestIpv6Address) req).getAddress() != null) {
-                ConfigRequestIpv6Address ipv6AddrReq = (ConfigRequestIpv6Address) req;
-
-                // Fail if expectedAddresses does not contain this address
-                LinkAddress address =
-                        new LinkAddress(ipv6AddrReq.getAddress(), ipv6AddrReq.getPrefixLength());
-                assertTrue(expectedAddresses.remove(address));
-            }
-        }
-
-        // Fail if any expected address is not found in result
-        assertTrue(expectedAddresses.isEmpty());
-    }
-}
diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeIdentificationTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeIdentificationTest.java
deleted file mode 100644
index 0317def..0000000
--- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeIdentificationTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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 android.net.ipsec.ike.cts;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-
-import android.net.ipsec.ike.IkeDerAsn1DnIdentification;
-import android.net.ipsec.ike.IkeFqdnIdentification;
-import android.net.ipsec.ike.IkeIpv4AddrIdentification;
-import android.net.ipsec.ike.IkeIpv6AddrIdentification;
-import android.net.ipsec.ike.IkeKeyIdIdentification;
-import android.net.ipsec.ike.IkeRfc822AddrIdentification;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import javax.security.auth.x500.X500Principal;
-
-@RunWith(AndroidJUnit4.class)
-public final class IkeIdentificationTest extends IkeTestBase {
-    @Test
-    public void testIkeDerAsn1DnIdentification() throws Exception {
-        X500Principal asn1Dn = new X500Principal(LOCAL_ASN1_DN_STRING);
-
-        IkeDerAsn1DnIdentification ikeId = new IkeDerAsn1DnIdentification(asn1Dn);
-        assertEquals(asn1Dn, ikeId.derAsn1Dn);
-    }
-
-    @Test
-    public void testIkeFqdnIdentification() throws Exception {
-        IkeFqdnIdentification ikeId = new IkeFqdnIdentification(LOCAL_HOSTNAME);
-        assertEquals(LOCAL_HOSTNAME, ikeId.fqdn);
-    }
-
-    @Test
-    public void testIkeIpv4AddrIdentification() throws Exception {
-        IkeIpv4AddrIdentification ikeId = new IkeIpv4AddrIdentification(IPV4_ADDRESS_LOCAL);
-        assertEquals(IPV4_ADDRESS_LOCAL, ikeId.ipv4Address);
-    }
-
-    @Test
-    public void testIkeIpv6AddrIdentification() throws Exception {
-        IkeIpv6AddrIdentification ikeId = new IkeIpv6AddrIdentification(IPV6_ADDRESS_LOCAL);
-        assertEquals(IPV6_ADDRESS_LOCAL, ikeId.ipv6Address);
-    }
-
-    @Test
-    public void testIkeKeyIdIdentification() throws Exception {
-        IkeKeyIdIdentification ikeId = new IkeKeyIdIdentification(LOCAL_KEY_ID);
-        assertArrayEquals(LOCAL_KEY_ID, ikeId.keyId);
-    }
-
-    @Test
-    public void testIkeRfc822AddrIdentification() throws Exception {
-        IkeRfc822AddrIdentification ikeId = new IkeRfc822AddrIdentification(LOCAL_RFC822_NAME);
-        assertEquals(LOCAL_RFC822_NAME, ikeId.rfc822Name);
-    }
-}
diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionDigitalSignatureTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionDigitalSignatureTest.java
deleted file mode 100644
index 9be1dc7..0000000
--- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionDigitalSignatureTest.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * 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 android.net.ipsec.ike.cts;
-
-import android.net.InetAddresses;
-import android.net.LinkAddress;
-import android.net.ipsec.ike.IkeDerAsn1DnIdentification;
-import android.net.ipsec.ike.IkeSession;
-import android.net.ipsec.ike.IkeSessionParams;
-import android.net.ipsec.ike.IkeTrafficSelector;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import com.android.internal.net.ipsec.ike.testutils.CertUtils;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.net.InetAddress;
-import java.security.cert.X509Certificate;
-import java.security.interfaces.RSAPrivateKey;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-import javax.security.auth.x500.X500Principal;
-
-/**
- * Explicitly test setting up transport mode Child SA so that devices do not have
- * FEATURE_IPSEC_TUNNELS will be test covered. Tunnel mode Child SA setup has been tested in
- * IkeSessionPskTest and authentication method is orthogonal to Child mode.
- */
-@RunWith(AndroidJUnit4.class)
-public class IkeSessionDigitalSignatureTest extends IkeSessionTestBase {
-    private static final int EXPECTED_AUTH_REQ_FRAG_COUNT = 3;
-
-    private static final String IKE_INIT_RESP =
-            "46B8ECA1E0D72A18BF3FA1C2CB1EE86F21202220000000000000015022000030"
-                    + "0000002C010100040300000C0100000C800E0100030000080300000503000008"
-                    + "0200000400000008040000022800008800020000328451C8A976CE69E407966A"
-                    + "50D7320C4197A15A07267CE1B16BAFF9BDBBDEC1FDCDAAF7175ADF9AA8DB55DB"
-                    + "2D70C012D01D914C4EDEF6E8B226868EA1D01B2ED0C4C5C86E6BFE566010EC0C"
-                    + "33BA1C93666430B88BDA0470D82CC4F4416F49E3E361E3017C9F27811A66718B"
-                    + "389E1800915D776D59AA528A7E1D1B7815D35144290000249FE8FABE7F43D917"
-                    + "CE370DE2FD9C22BBC082951AC26C1BA26DE795470F2C25BC2900001C00004004"
-                    + "AE388EC86D6D1A470D44142D01AB2E85A7AC14182900001C0000400544A235A4"
-                    + "171C884286B170F48FFC181DB428D87D290000080000402E290000100000402F"
-                    + "00020003000400050000000800004014";
-    private static final String IKE_AUTH_RESP_FRAG_1 =
-            "46B8ECA1E0D72A18BF3FA1C2CB1EE86F3520232000000001000004E0240004C4"
-                    + "00010002DF6750A2D1D5675006F9F6230BB886FFD20CFB973FD04963CFD7A528"
-                    + "560598C58CC44178B2FCBBBBB271387AC81A664B7E7F1055B912F8C686E287C9"
-                    + "D31684C66339151AB86DA3CF1DA664052FA97687634558A1E9E6B37E16A86BD1"
-                    + "68D76DA5E2E1E0B7E98EB662D80D542307015D2BF134EBBBE425D6954FE8C2C4"
-                    + "D31D16C16AA0521C3C481F873ECF25BB8B05AC6083775C1821CAAB1E35A3955D"
-                    + "85ACC599574142E1DD5B262D6E5365CBF6EBE92FFCC16BC29EC3239456F3B202"
-                    + "492551C0F6D752ADCCA56D506D50CC8809EF6BC56EAD005586F7168F76445FD3"
-                    + "1366CC62D32C0C19B28210B8F813F97CD6A447C3857EFD6EC483DDA8ACD9870E"
-                    + "5A21B9C66F0FA44496C0C3D05E8859A1A4CFC88155D0C411BABC13033DD41FA4"
-                    + "AF08CE7734A146687F374F95634D1F26843203CA1FFD05CA3EB150CEA02FBF14"
-                    + "712B7A1C9BC7616A086E7FCA059E7D64EFF98DB895B32F8F7002762AF7D12F23"
-                    + "31E9DD25174C4CE273E5392BBB48F50B7A3E0187181216265F6A4FC7B91BE0AB"
-                    + "C601A580149D4B07411AE99DDB1944B977E86ADC9746605C60A92B569EEFAFFC"
-                    + "3A888D187B75D8F13249689FC28EBCD62B5E03AF171F3A561F0DEA3B1A75F531"
-                    + "971157DCE1E7BC6E7789FF3E8156015BC9C521EFE48996B41471D33BF09864E4"
-                    + "2436E8D7EB6218CDE7716DA754A924B123A63E25585BF27F4AC043A0C4AECE38"
-                    + "BB59DD62F5C0EC657206A76CED1BD26262237DA1CA6815435992A825758DEBEC"
-                    + "DDF598A22B8242AC4E34E70704DBA7B7B73DC3E067C1C98764F8791F84C99156"
-                    + "947D1FFC875F36FCE24B89369C1B5BF1D4C999DCA28E72A528D0E0163C66C067"
-                    + "E71B5E0025C13DA93313942F9EDA230B3ADC254821A4CB1A5DC9D0C5F4DC4E8E"
-                    + "CE46B7B8C72D3C5923C9B30DF1EF7B4EDEDA8BD05C86CA0162AE1BF8F277878E"
-                    + "607401BAA8F06E3EA873FA4C137324C4E0699277CDF649FE7F0F01945EE25FA7"
-                    + "0E4A89737E58185B11B4CB52FD5B0497D3E3CD1CEE7B1FBB3E969DB6F4C324A1"
-                    + "32DC6A0EA21F41332435FD99140C286F8ABBBA926953ADBEED17D30AAD953909"
-                    + "1347EF6D87163D6B1FF32D8B11FFB2E69FAEE7FE913D3826FBA7F9D11E0E3C57"
-                    + "27625B37D213710B5DD8965DAEFD3F491E8C029E2BF361039949BADEC31D60AC"
-                    + "355F26EE41339C03CC9D9B01C3C7F288F0E9D6DFEE78231BDA9AC10FED135913"
-                    + "2836B1A17CE060742B7E5B738A7177CCD59F70337BA251409C377A0FA5333204"
-                    + "D8622BA8C06DE0BEF4F32B6D4D77BE9DE977445D8A2A08C5C38341CB7974FBFB"
-                    + "22C8F983A7D6CEF068DDB2281E6673453521C831C1826861005AE5F37649BC64"
-                    + "0A6360B23284861441A440F1C5AADE1AB53CA63DB17F4C314D493C4C44DE5F20"
-                    + "75E084D080F92791F30BDD88373D50AB5A07BC72B0E7FFFA593103964E55603E"
-                    + "F7FEB7CA0762A1A7B86B6CCAD88CD6CBC7C6935D21F5F06B2700588A2530E619"
-                    + "DA1648AC809F3DDF56ACE5951737568FFEC7E2AB1AA0AE01B03A7F5A29CE73C0"
-                    + "5D2801B17CAAD0121082E9952FAB16BA1C386336C62D4CF3A5019CF61609433E"
-                    + "1C083237D47C4CF575097F7BF9000EF6B6C497A44E6480154A35669AD276BF05"
-                    + "6CC730B4E5962B6AF96CC6D236AE85CEFDA6877173F72D2F614F6696D1F9DF07"
-                    + "E107758B0978F69BC9DBE0CCBF252C40A3FDF7CE9104D3344F7B73593CCD73E0";
-    private static final String IKE_AUTH_RESP_FRAG_2 =
-            "46B8ECA1E0D72A18BF3FA1C2CB1EE86F3520232000000001000000F0000000D4"
-                    + "00020002155211EA41B37BC5F20568A6AE57038EEE208F94F9B444004F1EF391"
-                    + "2CABFCF857B9CD95FAAA9489ED10A3F5C93510820E22E23FC55ED8049E067D72"
-                    + "3645C00E1E08611916CE72D7F0A84123B63A8F3B9E78DBBE39967B7BB074AF4D"
-                    + "BF2178D991EDBDD01908A14A266D09236DB963B14AC33D894F0F83A580209EFD"
-                    + "61875BB56273AA336C22D6A4D890B93E0D42435667830CC32E4F608500E18569"
-                    + "3E6C1D88C0B5AE427333C86468E3474DAA4D1506AAB2A4021309A33DD759D0D0"
-                    + "A8C98BF7FBEA8109361A9F194D0FD756";
-    private static final String DELETE_IKE_RESP =
-            "46B8ECA1E0D72A18BF3FA1C2CB1EE86F2E202520000000020000004C00000030"
-                    + "342842D8DA37C8EFB92ED37C4FBB23CBDC90445137D6A0AF489F9F03641DBA9D"
-                    + "02F6F59FD8A7A78C7261CEB8";
-
-    // Using IPv4 for transport mode Child SA. IPv6 is currently infeasible because the IKE server
-    // that generates the test vectors is running in an IPv4 only network.
-    private static final IkeTrafficSelector TRANSPORT_MODE_INBOUND_TS =
-            new IkeTrafficSelector(
-                    MIN_PORT,
-                    MAX_PORT,
-                    InetAddresses.parseNumericAddress("172.58.35.103"),
-                    InetAddresses.parseNumericAddress("172.58.35.103"));
-
-    // TODO(b/157510502): Add test for IKE Session setup with transport mode Child in IPv6 network
-
-    private static final String LOCAL_ID_ASN1_DN =
-            "CN=client.test.ike.android.net, O=Android, C=US";
-    private static final String REMOTE_ID_ASN1_DN =
-            "CN=server.test.ike.android.net, O=Android, C=US";
-
-    private static X509Certificate sServerCaCert;
-    private static X509Certificate sClientEndCert;
-    private static X509Certificate sClientIntermediateCaCertOne;
-    private static X509Certificate sClientIntermediateCaCertTwo;
-    private static RSAPrivateKey sClientPrivateKey;
-
-    @BeforeClass
-    public static void setUpCertsBeforeClass() throws Exception {
-        sServerCaCert = CertUtils.createCertFromPemFile("server-a-self-signed-ca.pem");
-        sClientEndCert = CertUtils.createCertFromPemFile("client-a-end-cert.pem");
-        sClientIntermediateCaCertOne =
-                CertUtils.createCertFromPemFile("client-a-intermediate-ca-one.pem");
-        sClientIntermediateCaCertTwo =
-                CertUtils.createCertFromPemFile("client-a-intermediate-ca-two.pem");
-        sClientPrivateKey = CertUtils.createRsaPrivateKeyFromKeyFile("client-a-private-key.key");
-    }
-
-    private IkeSession openIkeSessionWithRemoteAddress(InetAddress remoteAddress) {
-        IkeSessionParams ikeParams =
-                new IkeSessionParams.Builder(sContext)
-                        .setNetwork(mTunNetwork)
-                        .setServerHostname(remoteAddress.getHostAddress())
-                        .addSaProposal(SaProposalTest.buildIkeSaProposalWithNormalModeCipher())
-                        .addSaProposal(SaProposalTest.buildIkeSaProposalWithCombinedModeCipher())
-                        .setLocalIdentification(
-                                new IkeDerAsn1DnIdentification(new X500Principal(LOCAL_ID_ASN1_DN)))
-                        .setRemoteIdentification(
-                                new IkeDerAsn1DnIdentification(
-                                        new X500Principal(REMOTE_ID_ASN1_DN)))
-                        .setAuthDigitalSignature(
-                                sServerCaCert,
-                                sClientEndCert,
-                                Arrays.asList(
-                                        sClientIntermediateCaCertOne, sClientIntermediateCaCertTwo),
-                                sClientPrivateKey)
-                        .build();
-
-        return new IkeSession(
-                sContext,
-                ikeParams,
-                buildTransportModeChildParamsWithTs(
-                        TRANSPORT_MODE_INBOUND_TS, TRANSPORT_MODE_OUTBOUND_TS),
-                mUserCbExecutor,
-                mIkeSessionCallback,
-                mFirstChildSessionCallback);
-    }
-
-    @Test
-    public void testIkeSessionSetupAndChildSessionSetupWithTransportMode() throws Exception {
-        // Open IKE Session
-        IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
-        performSetupIkeAndFirstChildBlocking(
-                IKE_INIT_RESP,
-                EXPECTED_AUTH_REQ_FRAG_COUNT /* expectedReqPktCnt */,
-                true /* expectedAuthUseEncap */,
-                IKE_AUTH_RESP_FRAG_1,
-                IKE_AUTH_RESP_FRAG_2);
-
-        // IKE INIT and IKE AUTH takes two exchanges. Message ID starts from 2
-        int expectedMsgId = 2;
-
-        verifyIkeSessionSetupBlocking();
-        verifyChildSessionSetupBlocking(
-                mFirstChildSessionCallback,
-                Arrays.asList(TRANSPORT_MODE_INBOUND_TS),
-                Arrays.asList(TRANSPORT_MODE_OUTBOUND_TS),
-                new ArrayList<LinkAddress>());
-        IpSecTransformCallRecord firstTransformRecordA =
-                mFirstChildSessionCallback.awaitNextCreatedIpSecTransform();
-        IpSecTransformCallRecord firstTransformRecordB =
-                mFirstChildSessionCallback.awaitNextCreatedIpSecTransform();
-        verifyCreateIpSecTransformPair(firstTransformRecordA, firstTransformRecordB);
-
-        // Close IKE Session
-        ikeSession.close();
-        performCloseIkeBlocking(expectedMsgId++, DELETE_IKE_RESP);
-        verifyCloseIkeAndChildBlocking(firstTransformRecordA, firstTransformRecordB);
-    }
-}
diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionMschapV2Test.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionMschapV2Test.java
deleted file mode 100644
index cb77127..0000000
--- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionMschapV2Test.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * 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 android.net.ipsec.ike.cts;
-
-import android.net.InetAddresses;
-import android.net.LinkAddress;
-import android.net.eap.EapSessionConfig;
-import android.net.ipsec.ike.IkeFqdnIdentification;
-import android.net.ipsec.ike.IkeSession;
-import android.net.ipsec.ike.IkeSessionParams;
-import android.net.ipsec.ike.IkeTrafficSelector;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import com.android.internal.net.ipsec.ike.testutils.CertUtils;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.net.InetAddress;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-/**
- * Explicitly test setting up transport mode Child SA so that devices do not have
- * FEATURE_IPSEC_TUNNELS will be test covered. Tunnel mode Child SA setup has been tested in
- * IkeSessionPskTest and authentication method is orthogonal to Child mode.
- */
-@RunWith(AndroidJUnit4.class)
-public class IkeSessionMschapV2Test extends IkeSessionTestBase {
-    private static final String IKE_INIT_RESP =
-            "46B8ECA1E0D72A1873F643FF94D249A921202220000000000000015022000030"
-                    + "0000002C010100040300000C0100000C800E0080030000080300000203000008"
-                    + "0200000200000008040000022800008800020000CC6E71E67E32CED6BCE33FBD"
-                    + "A74113867E3FA3AE21C7C9AB44A7F8835DF602BFD6F6528B67FEE39821232380"
-                    + "C99E8FFC0A5D767F8F38906DA41946C2299DF18C15FA69BAC08D3EDB32E8C8CA"
-                    + "28431831561C04CB0CDE393F817151CD8DAF7A311838411F1C39BFDB5EBCF6A6"
-                    + "1DF66DEB067362649D64607D599B56C4227819D0290000241197004CF31AD00F"
-                    + "5E0C92E198488D8A2B6F6A25C82762AA49F565BCE9D857D72900001C00004004"
-                    + "A0D98FEABBFB92A6C0976EE83D2AACFCCF969A6B2900001C0000400575EBF73F"
-                    + "8EE5CC73917DE9D3F91FCD4A16A0444D290000080000402E290000100000402F"
-                    + "00020003000400050000000800004014";
-    private static final String IKE_AUTH_RESP_1_FRAG_1 =
-            "46B8ECA1E0D72A1873F643FF94D249A93520232000000001000004E0240004C4"
-                    + "00010002C4159CB756773B3F1911F4595107BC505D7A28C72F05182966076679"
-                    + "CA68ED92E4BC5CD441C9CB315F2F449A8A521CAFED3C5F285E295FC3791D3415"
-                    + "E3BACF66A08410DF4E35F7D88FE40DA28851C91C77A6549E186AC1B7846DF3FA"
-                    + "0A347A5ABBCAEE19E70F0EE5966DC6242A115F29523709302EDAD2E36C8F0395"
-                    + "CF5C42EC2D2898ECDD8A6AEDD686A70B589A981558667647F32F41E0D8913E94"
-                    + "A6693F53E59EA8938037F562CF1DC5E6E2CDC630B5FFB08949E3172249422F7D"
-                    + "EA069F9BAD5F96E48BADC7164A9269669AD0DF295A80C54D1D23CEA3F28AC485"
-                    + "86D2A9850DA23823037AB7D1577B7B2364C92C36B84238357129EB4A64D33310"
-                    + "B95DCD50CD53E78C32EFE7DC1627D9432E9BFDEE130045DE967B19F92A9D1270"
-                    + "F1E2C6BFBAA56802F3E63510578EF1ECB6872852F286EEC790AA1FE0CAF391CB"
-                    + "E276554922713BA4770CFE71E23F043DC620E22CC02A74F60725D18331B7F2C9"
-                    + "276EB6FBB7CBDAA040046D7ECBE1A5D7064E04E542807C5101B941D1C81B9D5E"
-                    + "90347B22BD4E638E2EDC98E369B51AA29BDB2CF8AA610D4B893EB83A4650717C"
-                    + "38B4D145EE939C18DCEDF6C79933CEB3D7C116B1F188DF9DDD560951B54E4A7D"
-                    + "80C999A32AB02BF39D7B498DAD36F1A5CBE2F64557D6401AE9DD6E0CEADA3F90"
-                    + "540FE9114BB6B8719C9064796354F4A180A6600CAD092F8302564E409B71ACB7"
-                    + "590F19B3AC88E7A606C718D0B97F7E4B4830F11D851C59F2255846DA22E2C805"
-                    + "0CA2AF2ACF3B6C769D11B75B5AC9AB82ED3D90014994B1BF6FED58FBEF2D72EF"
-                    + "8BDFE51F9A101393A7CA1ACF78FAEBF3E3CC25E09407D1E14AF351A159A13EE3"
-                    + "9B919BA8B49942792E7527C2FB6D418C4DF427669A4BF5A1AFBBB973BAF17918"
-                    + "9C9D520CAC2283B89A539ECE785EBE48FBB77D880A17D55C84A51F46068A4B87"
-                    + "FF48FEEE50E1E034CC8AFF5DA92105F55EC4823E67BDFE942CA8BE0DAECBBD52"
-                    + "E8AAF306049DC6C4CF87D987B0AC54FCE92E6AE8507965AAAC6AB8BD3405712F"
-                    + "EE170B70BC64BDCBD86D80C7AAAF341131F9A1210D7430B17218413AE1363183"
-                    + "5C98FA2428B1E9E987ADC9070E232310A28F4C3163E18366FFB112BADD7C5E0F"
-                    + "D13093A7C1428F87856BA0A7E46955589ACA267CE7A04320C4BCDBB60C672404"
-                    + "778F8D511AAB09349DAB482445D7F606F28E7FBBB18FC0F4EC0AF04F44C282F9"
-                    + "39C6E3B955C84DADEA350667236583069B74F492D600127636FA31F63E560851"
-                    + "2FC28B8EA5B4D01D110990B6EA46B9C2E7C7C856C240EF7A8147BA2C4344B85A"
-                    + "453C862024B5B6814D13CDEAEF7683D539BB50CAFFC0416F269F2F9EDEC5FA30"
-                    + "022FD7B4B186CD2020E7ED8D81ED90822EDD8B76F840DD68F09694CFF9B4F33E"
-                    + "11DF4E601A4212881A6D4E9259001705C41E9E23D18A7F3D4A3463649A38211A"
-                    + "5A90D0F17739A677C74E23F31C01D60B5A0F1E6A4D44FED9D25BF1E63418E1FC"
-                    + "0B19F6F4B71DE53C62B14B82279538A82DD4BE19AB6E00AFC20F124AAB7DF21A"
-                    + "42259BE4F40EC69B16917256F23E2C37376311D62E0A3A0EF8C2AD0C090221D5"
-                    + "C5ECA08F08178A4D31FFDB150C609827D18AD83C7B0A43AEE0406BD3FB494B53"
-                    + "A279FDD6447E234C926AD8CE47FFF779BB45B1FC8457C6E7D257D1359959D977"
-                    + "CEF6906A3367DC4D454993EFDC6F1EA94E17EB3DCB00A289346B4CFD7F19B16E";
-    private static final String IKE_AUTH_RESP_1_FRAG_2 =
-            "46B8ECA1E0D72A1873F643FF94D249A935202320000000010000008000000064"
-                    + "00020002C61F66025E821A5E69A4DE1F591A2C32C983C3154A5003660137D685"
-                    + "A5262B9FDF5EDC699DE4D8BD38F549E3CBD12024B45B4C86561C36C3EED839DA"
-                    + "9860C6AA0B764C662D08F1B6A98F68CF6E3038F737C0B415AD8A8B7D702BD92A";
-    private static final String IKE_AUTH_RESP_2 =
-            "46B8ECA1E0D72A1873F643FF94D249A92E202320000000020000008C30000070"
-                    + "62B90C2229FD23025BC2FD7FE6341E9EE04B17264CD619BCE18975A5F88BE438"
-                    + "D4AD4A5310057255AF568C293A29B10107E3EE3675C10AA2B26404D90C0528CC"
-                    + "F7605A86C96A1F2635CCC6CFC90EE65E5C2A2262EB33FE520EB708423A83CB63"
-                    + "274ECCBB102AF5DF35742657";
-    private static final String IKE_AUTH_RESP_3 =
-            "46B8ECA1E0D72A1873F643FF94D249A92E202320000000030000004C30000030"
-                    + "AB52C3C80123D3432C05AF457CE93C352395F73E861CD49561BA528CFE68D17D"
-                    + "78BBF6FC41E81C2B9EA051A2";
-    private static final String IKE_AUTH_RESP_4 =
-            "46B8ECA1E0D72A1873F643FF94D249A92E20232000000004000000CC270000B0"
-                    + "8D3342A7AB2666AC754F4B55C5C6B1A61255E62FBCA53D5CDEEDE60DADB7915C"
-                    + "7F962076A58BF7D39A05ED1B60FF349B6DE311AF7CEBC72B4BB9723A728A5D3E"
-                    + "9E508B2D7A11843D279B56ADA07E608D61F5CA7638F10372A440AD1DCE44E190"
-                    + "7B7B7A68B126EBBB86638D667D5B528D233BA8D32D7E0FAC4E1448E87396EEE6"
-                    + "0985B79841E1229D7962AACFD8F872722EC8D5B19D4C82D6C4ADCB276127A1A7"
-                    + "3FC84CDF85B2299BC96B64AC";
-    private static final String DELETE_IKE_RESP =
-            "46B8ECA1E0D72A1873F643FF94D249A92E202520000000050000004C00000030"
-                    + "622CE06C8CB132AA00567E9BC83F58B32BD7DB5130C76E385B306434DA227361"
-                    + "D50CC19D408A8D4F36F9697F";
-
-    // This value is align with the test vectors hex that are generated in an IPv4 environment
-    private static final IkeTrafficSelector TRANSPORT_MODE_INBOUND_TS =
-            new IkeTrafficSelector(
-                    MIN_PORT,
-                    MAX_PORT,
-                    InetAddresses.parseNumericAddress("172.58.35.67"),
-                    InetAddresses.parseNumericAddress("172.58.35.67"));
-
-    private static final EapSessionConfig EAP_CONFIG =
-            new EapSessionConfig.Builder()
-                    .setEapIdentity(EAP_IDENTITY)
-                    .setEapMsChapV2Config(EAP_MSCHAPV2_USERNAME, EAP_MSCHAPV2_PASSWORD)
-                    .build();
-
-    private static X509Certificate sServerCaCert;
-
-    @BeforeClass
-    public static void setUpCertBeforeClass() throws Exception {
-        sServerCaCert = CertUtils.createCertFromPemFile("server-a-self-signed-ca.pem");
-    }
-
-    private IkeSession openIkeSessionWithRemoteAddress(InetAddress remoteAddress) {
-        IkeSessionParams ikeParams =
-                new IkeSessionParams.Builder(sContext)
-                        .setNetwork(mTunNetwork)
-                        .setServerHostname(remoteAddress.getHostAddress())
-                        .addSaProposal(SaProposalTest.buildIkeSaProposalWithNormalModeCipher())
-                        .addSaProposal(SaProposalTest.buildIkeSaProposalWithCombinedModeCipher())
-                        .setLocalIdentification(new IkeFqdnIdentification(LOCAL_HOSTNAME))
-                        .setRemoteIdentification(new IkeFqdnIdentification(REMOTE_HOSTNAME))
-                        .setAuthEap(sServerCaCert, EAP_CONFIG)
-                        .build();
-        return new IkeSession(
-                sContext,
-                ikeParams,
-                buildTransportModeChildParamsWithTs(
-                        TRANSPORT_MODE_INBOUND_TS, TRANSPORT_MODE_OUTBOUND_TS),
-                mUserCbExecutor,
-                mIkeSessionCallback,
-                mFirstChildSessionCallback);
-    }
-
-    @Test
-    public void testIkeSessionSetupAndChildSessionSetupWithTransportMode() throws Exception {
-        // Open IKE Session
-        IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
-        int expectedMsgId = 0;
-        mTunUtils.awaitReqAndInjectResp(
-                IKE_DETERMINISTIC_INITIATOR_SPI,
-                expectedMsgId++,
-                false /* expectedUseEncap */,
-                IKE_INIT_RESP);
-
-        mTunUtils.awaitReqAndInjectResp(
-                IKE_DETERMINISTIC_INITIATOR_SPI,
-                expectedMsgId++,
-                true /* expectedUseEncap */,
-                IKE_AUTH_RESP_1_FRAG_1,
-                IKE_AUTH_RESP_1_FRAG_2);
-
-        mTunUtils.awaitReqAndInjectResp(
-                IKE_DETERMINISTIC_INITIATOR_SPI,
-                expectedMsgId++,
-                true /* expectedUseEncap */,
-                IKE_AUTH_RESP_2);
-        mTunUtils.awaitReqAndInjectResp(
-                IKE_DETERMINISTIC_INITIATOR_SPI,
-                expectedMsgId++,
-                true /* expectedUseEncap */,
-                IKE_AUTH_RESP_3);
-        mTunUtils.awaitReqAndInjectResp(
-                IKE_DETERMINISTIC_INITIATOR_SPI,
-                expectedMsgId++,
-                true /* expectedUseEncap */,
-                IKE_AUTH_RESP_4);
-
-        verifyIkeSessionSetupBlocking();
-        verifyChildSessionSetupBlocking(
-                mFirstChildSessionCallback,
-                Arrays.asList(TRANSPORT_MODE_INBOUND_TS),
-                Arrays.asList(TRANSPORT_MODE_OUTBOUND_TS),
-                new ArrayList<LinkAddress>());
-        IpSecTransformCallRecord firstTransformRecordA =
-                mFirstChildSessionCallback.awaitNextCreatedIpSecTransform();
-        IpSecTransformCallRecord firstTransformRecordB =
-                mFirstChildSessionCallback.awaitNextCreatedIpSecTransform();
-        verifyCreateIpSecTransformPair(firstTransformRecordA, firstTransformRecordB);
-
-        // Close IKE Session
-        ikeSession.close();
-        performCloseIkeBlocking(expectedMsgId++, DELETE_IKE_RESP);
-        verifyCloseIkeAndChildBlocking(firstTransformRecordA, firstTransformRecordB);
-    }
-}
diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java
deleted file mode 100644
index c767b78..0000000
--- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * 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 android.net.ipsec.ike.cts;
-
-import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID;
-import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_EAP_ONLY_AUTH;
-import static android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig;
-import static android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignLocalConfig;
-import static android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignRemoteConfig;
-import static android.net.ipsec.ike.IkeSessionParams.IkeAuthEapConfig;
-import static android.net.ipsec.ike.IkeSessionParams.IkeAuthPskConfig;
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.AF_INET6;
-import static android.telephony.TelephonyManager.APPTYPE_USIM;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.net.eap.EapSessionConfig;
-import android.net.ipsec.ike.IkeFqdnIdentification;
-import android.net.ipsec.ike.IkeIdentification;
-import android.net.ipsec.ike.IkeSaProposal;
-import android.net.ipsec.ike.IkeSessionParams;
-import android.net.ipsec.ike.IkeSessionParams.ConfigRequestIpv4PcscfServer;
-import android.net.ipsec.ike.IkeSessionParams.ConfigRequestIpv6PcscfServer;
-import android.net.ipsec.ike.IkeSessionParams.IkeConfigRequest;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import com.android.internal.net.ipsec.ike.testutils.CertUtils;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.net.InetAddress;
-import java.security.cert.X509Certificate;
-import java.security.interfaces.RSAPrivateKey;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-@RunWith(AndroidJUnit4.class)
-public final class IkeSessionParamsTest extends IkeSessionTestBase {
-    private static final int HARD_LIFETIME_SECONDS = (int) TimeUnit.HOURS.toSeconds(20L);
-    private static final int SOFT_LIFETIME_SECONDS = (int) TimeUnit.HOURS.toSeconds(10L);
-    private static final int DPD_DELAY_SECONDS = (int) TimeUnit.MINUTES.toSeconds(10L);
-    private static final int[] RETRANS_TIMEOUT_MS_LIST = new int[] {500, 500, 500, 500, 500, 500};
-
-    private static final Map<Class<? extends IkeConfigRequest>, Integer> EXPECTED_REQ_COUNT =
-            new HashMap<>();
-    private static final HashSet<InetAddress> EXPECTED_PCSCF_SERVERS = new HashSet<>();
-
-    static {
-        EXPECTED_REQ_COUNT.put(ConfigRequestIpv4PcscfServer.class, 3);
-        EXPECTED_REQ_COUNT.put(ConfigRequestIpv6PcscfServer.class, 3);
-
-        EXPECTED_PCSCF_SERVERS.add(PCSCF_IPV4_ADDRESS_1);
-        EXPECTED_PCSCF_SERVERS.add(PCSCF_IPV4_ADDRESS_2);
-        EXPECTED_PCSCF_SERVERS.add(PCSCF_IPV6_ADDRESS_1);
-        EXPECTED_PCSCF_SERVERS.add(PCSCF_IPV6_ADDRESS_2);
-    }
-
-    // Arbitrary proposal and remote ID. Local ID is chosen to match the client end cert in the
-    // following CL
-    private static final IkeSaProposal SA_PROPOSAL =
-            SaProposalTest.buildIkeSaProposalWithNormalModeCipher();
-    private static final IkeIdentification LOCAL_ID = new IkeFqdnIdentification(LOCAL_HOSTNAME);
-    private static final IkeIdentification REMOTE_ID = new IkeFqdnIdentification(REMOTE_HOSTNAME);
-
-    private static final EapSessionConfig EAP_ALL_METHODS_CONFIG =
-            createEapOnlySafeMethodsBuilder()
-                    .setEapMsChapV2Config(EAP_MSCHAPV2_USERNAME, EAP_MSCHAPV2_PASSWORD)
-                    .build();
-    private static final EapSessionConfig EAP_ONLY_SAFE_METHODS_CONFIG =
-            createEapOnlySafeMethodsBuilder().build();
-
-    private X509Certificate mServerCaCert;
-    private X509Certificate mClientEndCert;
-    private X509Certificate mClientIntermediateCaCertOne;
-    private X509Certificate mClientIntermediateCaCertTwo;
-    private RSAPrivateKey mClientPrivateKey;
-
-    @Before
-    public void setUp() throws Exception {
-        // This address is never used except for setting up the test network
-        setUpTestNetwork(IPV4_ADDRESS_LOCAL);
-
-        mServerCaCert = CertUtils.createCertFromPemFile("server-a-self-signed-ca.pem");
-        mClientEndCert = CertUtils.createCertFromPemFile("client-a-end-cert.pem");
-        mClientIntermediateCaCertOne =
-                CertUtils.createCertFromPemFile("client-a-intermediate-ca-one.pem");
-        mClientIntermediateCaCertTwo =
-                CertUtils.createCertFromPemFile("client-a-intermediate-ca-two.pem");
-        mClientPrivateKey = CertUtils.createRsaPrivateKeyFromKeyFile("client-a-private-key.key");
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        tearDownTestNetwork();
-    }
-
-    private static EapSessionConfig.Builder createEapOnlySafeMethodsBuilder() {
-        return new EapSessionConfig.Builder()
-                .setEapIdentity(EAP_IDENTITY)
-                .setEapSimConfig(SUB_ID, APPTYPE_USIM)
-                .setEapAkaConfig(SUB_ID, APPTYPE_USIM)
-                .setEapAkaPrimeConfig(
-                        SUB_ID, APPTYPE_USIM, NETWORK_NAME, true /* allowMismatchedNetworkNames */);
-    }
-
-    /**
-     * Create a Builder that has minimum configurations to build an IkeSessionParams.
-     *
-     * <p>Authentication method is arbitrarily selected. Using other method (e.g. setAuthEap) also
-     * works.
-     */
-    private IkeSessionParams.Builder createIkeParamsBuilderMinimum() {
-        return new IkeSessionParams.Builder(sContext)
-                .setNetwork(mTunNetwork)
-                .setServerHostname(IPV4_ADDRESS_REMOTE.getHostAddress())
-                .addSaProposal(SA_PROPOSAL)
-                .setLocalIdentification(LOCAL_ID)
-                .setRemoteIdentification(REMOTE_ID)
-                .setAuthPsk(IKE_PSK);
-    }
-
-    /**
-     * Verify the minimum configurations to build an IkeSessionParams.
-     *
-     * @see #createIkeParamsBuilderMinimum
-     */
-    private void verifyIkeParamsMinimum(IkeSessionParams sessionParams) {
-        assertEquals(mTunNetwork, sessionParams.getNetwork());
-        assertEquals(IPV4_ADDRESS_REMOTE.getHostAddress(), sessionParams.getServerHostname());
-        assertEquals(Arrays.asList(SA_PROPOSAL), sessionParams.getSaProposals());
-        assertEquals(LOCAL_ID, sessionParams.getLocalIdentification());
-        assertEquals(REMOTE_ID, sessionParams.getRemoteIdentification());
-
-        IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig();
-        assertTrue(localConfig instanceof IkeAuthPskConfig);
-        assertArrayEquals(IKE_PSK, ((IkeAuthPskConfig) localConfig).getPsk());
-        IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig();
-        assertTrue(remoteConfig instanceof IkeAuthPskConfig);
-        assertArrayEquals(IKE_PSK, ((IkeAuthPskConfig) remoteConfig).getPsk());
-    }
-
-    @Test
-    public void testBuildWithMinimumSet() throws Exception {
-        IkeSessionParams sessionParams = createIkeParamsBuilderMinimum().build();
-
-        verifyIkeParamsMinimum(sessionParams);
-
-        // Verify default values that do not need explicit configuration. Do not do assertEquals
-        // to be avoid being a change-detector test
-        assertTrue(sessionParams.getHardLifetimeSeconds() > sessionParams.getSoftLifetimeSeconds());
-        assertTrue(sessionParams.getSoftLifetimeSeconds() > 0);
-        assertTrue(sessionParams.getDpdDelaySeconds() > 0);
-        assertTrue(sessionParams.getRetransmissionTimeoutsMillis().length > 0);
-        for (int timeout : sessionParams.getRetransmissionTimeoutsMillis()) {
-            assertTrue(timeout > 0);
-        }
-        assertTrue(sessionParams.getConfigurationRequests().isEmpty());
-        assertFalse(sessionParams.hasIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID));
-    }
-
-    @Test
-    public void testSetLifetimes() throws Exception {
-        IkeSessionParams sessionParams =
-                createIkeParamsBuilderMinimum()
-                        .setLifetimeSeconds(HARD_LIFETIME_SECONDS, SOFT_LIFETIME_SECONDS)
-                        .build();
-
-        verifyIkeParamsMinimum(sessionParams);
-        assertEquals(HARD_LIFETIME_SECONDS, sessionParams.getHardLifetimeSeconds());
-        assertEquals(SOFT_LIFETIME_SECONDS, sessionParams.getSoftLifetimeSeconds());
-    }
-
-    @Test
-    public void testSetDpdDelay() throws Exception {
-        IkeSessionParams sessionParams =
-                createIkeParamsBuilderMinimum().setDpdDelaySeconds(DPD_DELAY_SECONDS).build();
-
-        verifyIkeParamsMinimum(sessionParams);
-        assertEquals(DPD_DELAY_SECONDS, sessionParams.getDpdDelaySeconds());
-    }
-
-    @Test
-    public void testSetRetransmissionTimeouts() throws Exception {
-        IkeSessionParams sessionParams =
-                createIkeParamsBuilderMinimum()
-                        .setRetransmissionTimeoutsMillis(RETRANS_TIMEOUT_MS_LIST)
-                        .build();
-
-        verifyIkeParamsMinimum(sessionParams);
-        assertArrayEquals(RETRANS_TIMEOUT_MS_LIST, sessionParams.getRetransmissionTimeoutsMillis());
-    }
-
-    @Test
-    public void testSetPcscfConfigRequests() throws Exception {
-        IkeSessionParams sessionParams =
-                createIkeParamsBuilderMinimum()
-                        .setRetransmissionTimeoutsMillis(RETRANS_TIMEOUT_MS_LIST)
-                        .addPcscfServerRequest(AF_INET)
-                        .addPcscfServerRequest(PCSCF_IPV4_ADDRESS_1)
-                        .addPcscfServerRequest(PCSCF_IPV6_ADDRESS_1)
-                        .addPcscfServerRequest(AF_INET6)
-                        .addPcscfServerRequest(PCSCF_IPV4_ADDRESS_2)
-                        .addPcscfServerRequest(PCSCF_IPV6_ADDRESS_2)
-                        .build();
-
-        verifyIkeParamsMinimum(sessionParams);
-        verifyConfigRequestTypes(EXPECTED_REQ_COUNT, sessionParams.getConfigurationRequests());
-
-        Set<InetAddress> resultAddresses = new HashSet<>();
-        for (IkeConfigRequest req : sessionParams.getConfigurationRequests()) {
-            if (req instanceof ConfigRequestIpv4PcscfServer
-                    && ((ConfigRequestIpv4PcscfServer) req).getAddress() != null) {
-                resultAddresses.add(((ConfigRequestIpv4PcscfServer) req).getAddress());
-            } else if (req instanceof ConfigRequestIpv6PcscfServer
-                    && ((ConfigRequestIpv6PcscfServer) req).getAddress() != null) {
-                resultAddresses.add(((ConfigRequestIpv6PcscfServer) req).getAddress());
-            }
-        }
-        assertEquals(EXPECTED_PCSCF_SERVERS, resultAddresses);
-    }
-
-    @Test
-    public void testAddIkeOption() throws Exception {
-        IkeSessionParams sessionParams =
-                createIkeParamsBuilderMinimum()
-                        .addIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID)
-                        .build();
-
-        verifyIkeParamsMinimum(sessionParams);
-        assertTrue(sessionParams.hasIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID));
-    }
-
-    @Test
-    public void testRemoveIkeOption() throws Exception {
-        IkeSessionParams sessionParams =
-                createIkeParamsBuilderMinimum()
-                        .addIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID)
-                        .removeIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID)
-                        .build();
-
-        verifyIkeParamsMinimum(sessionParams);
-        assertFalse(sessionParams.hasIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID));
-    }
-
-    /**
-     * Create a Builder that has minimum configurations to build an IkeSessionParams, except for
-     * authentication method.
-     */
-    private IkeSessionParams.Builder createIkeParamsBuilderMinimumWithoutAuth() {
-        return new IkeSessionParams.Builder(sContext)
-                .setNetwork(mTunNetwork)
-                .setServerHostname(IPV4_ADDRESS_REMOTE.getHostAddress())
-                .addSaProposal(SA_PROPOSAL)
-                .setLocalIdentification(LOCAL_ID)
-                .setRemoteIdentification(REMOTE_ID);
-    }
-
-    /**
-     * Verify the minimum configurations to build an IkeSessionParams, except for authentication
-     * method.
-     *
-     * @see #createIkeParamsBuilderMinimumWithoutAuth
-     */
-    private void verifyIkeParamsMinimumWithoutAuth(IkeSessionParams sessionParams) {
-        assertEquals(mTunNetwork, sessionParams.getNetwork());
-        assertEquals(IPV4_ADDRESS_REMOTE.getHostAddress(), sessionParams.getServerHostname());
-        assertEquals(Arrays.asList(SA_PROPOSAL), sessionParams.getSaProposals());
-        assertEquals(LOCAL_ID, sessionParams.getLocalIdentification());
-        assertEquals(REMOTE_ID, sessionParams.getRemoteIdentification());
-    }
-
-    @Test
-    public void testBuildWithPsk() throws Exception {
-        IkeSessionParams sessionParams =
-                createIkeParamsBuilderMinimumWithoutAuth().setAuthPsk(IKE_PSK).build();
-
-        verifyIkeParamsMinimumWithoutAuth(sessionParams);
-
-        IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig();
-        assertTrue(localConfig instanceof IkeAuthPskConfig);
-        assertArrayEquals(IKE_PSK, ((IkeAuthPskConfig) localConfig).getPsk());
-        IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig();
-        assertTrue(remoteConfig instanceof IkeAuthPskConfig);
-        assertArrayEquals(IKE_PSK, ((IkeAuthPskConfig) remoteConfig).getPsk());
-    }
-
-    @Test
-    public void testBuildWithEap() throws Exception {
-        IkeSessionParams sessionParams =
-                createIkeParamsBuilderMinimumWithoutAuth()
-                        .setAuthEap(mServerCaCert, EAP_ALL_METHODS_CONFIG)
-                        .build();
-
-        verifyIkeParamsMinimumWithoutAuth(sessionParams);
-
-        IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig();
-        assertTrue(localConfig instanceof IkeAuthEapConfig);
-        assertEquals(EAP_ALL_METHODS_CONFIG, ((IkeAuthEapConfig) localConfig).getEapConfig());
-        IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig();
-        assertTrue(remoteConfig instanceof IkeAuthDigitalSignRemoteConfig);
-        assertEquals(
-                mServerCaCert, ((IkeAuthDigitalSignRemoteConfig) remoteConfig).getRemoteCaCert());
-    }
-
-    @Test
-    public void testBuildWithEapOnlyAuth() throws Exception {
-        IkeSessionParams sessionParams =
-                createIkeParamsBuilderMinimumWithoutAuth()
-                        .setAuthEap(mServerCaCert, EAP_ONLY_SAFE_METHODS_CONFIG)
-                        .addIkeOption(IKE_OPTION_EAP_ONLY_AUTH)
-                        .build();
-
-        assertTrue(sessionParams.hasIkeOption(IKE_OPTION_EAP_ONLY_AUTH));
-        verifyIkeParamsMinimumWithoutAuth(sessionParams);
-
-        IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig();
-        assertTrue(localConfig instanceof IkeAuthEapConfig);
-        assertEquals(EAP_ONLY_SAFE_METHODS_CONFIG, ((IkeAuthEapConfig) localConfig).getEapConfig());
-        IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig();
-        assertTrue(remoteConfig instanceof IkeAuthDigitalSignRemoteConfig);
-        assertEquals(
-                mServerCaCert, ((IkeAuthDigitalSignRemoteConfig) remoteConfig).getRemoteCaCert());
-    }
-
-    @Test
-    public void testThrowBuildEapOnlyAuthWithUnsafeMethod() throws Exception {
-        try {
-            IkeSessionParams sessionParams =
-                    createIkeParamsBuilderMinimumWithoutAuth()
-                            .setAuthEap(mServerCaCert, EAP_ALL_METHODS_CONFIG)
-                            .addIkeOption(IKE_OPTION_EAP_ONLY_AUTH)
-                            .build();
-            fail("Expected to fail because EAP only unsafe method is proposed");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    @Test
-    public void testBuildWithDigitalSignature() throws Exception {
-        IkeSessionParams sessionParams =
-                createIkeParamsBuilderMinimumWithoutAuth()
-                        .setAuthDigitalSignature(mServerCaCert, mClientEndCert, mClientPrivateKey)
-                        .build();
-
-        verifyIkeParamsMinimumWithoutAuth(sessionParams);
-
-        IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig();
-        assertTrue(localConfig instanceof IkeAuthDigitalSignLocalConfig);
-        IkeAuthDigitalSignLocalConfig localSignConfig = (IkeAuthDigitalSignLocalConfig) localConfig;
-        assertEquals(mClientEndCert, localSignConfig.getClientEndCertificate());
-        assertEquals(Collections.EMPTY_LIST, localSignConfig.getIntermediateCertificates());
-        assertEquals(mClientPrivateKey, localSignConfig.getPrivateKey());
-
-        IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig();
-        assertTrue(remoteConfig instanceof IkeAuthDigitalSignRemoteConfig);
-        assertEquals(
-                mServerCaCert, ((IkeAuthDigitalSignRemoteConfig) remoteConfig).getRemoteCaCert());
-    }
-
-    @Test
-    public void testBuildWithDigitalSignatureAndIntermediateCerts() throws Exception {
-        List<X509Certificate> intermediateCerts =
-                Arrays.asList(mClientIntermediateCaCertOne, mClientIntermediateCaCertTwo);
-
-        IkeSessionParams sessionParams =
-                createIkeParamsBuilderMinimumWithoutAuth()
-                        .setAuthDigitalSignature(
-                                mServerCaCert, mClientEndCert, intermediateCerts, mClientPrivateKey)
-                        .build();
-
-        verifyIkeParamsMinimumWithoutAuth(sessionParams);
-
-        IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig();
-        assertTrue(localConfig instanceof IkeAuthDigitalSignLocalConfig);
-        IkeAuthDigitalSignLocalConfig localSignConfig = (IkeAuthDigitalSignLocalConfig) localConfig;
-        assertEquals(mClientEndCert, localSignConfig.getClientEndCertificate());
-        assertEquals(intermediateCerts, localSignConfig.getIntermediateCertificates());
-        assertEquals(mClientPrivateKey, localSignConfig.getPrivateKey());
-
-        IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig();
-        assertTrue(remoteConfig instanceof IkeAuthDigitalSignRemoteConfig);
-        assertEquals(
-                mServerCaCert, ((IkeAuthDigitalSignRemoteConfig) remoteConfig).getRemoteCaCert());
-    }
-}
diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java
deleted file mode 100644
index 13f953a..0000000
--- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * 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 android.net.ipsec.ike.cts;
-
-import static android.app.AppOpsManager.OP_MANAGE_IPSEC_TUNNELS;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_TS_UNACCEPTABLE;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-
-import android.net.LinkAddress;
-import android.net.ipsec.ike.ChildSessionParams;
-import android.net.ipsec.ike.IkeFqdnIdentification;
-import android.net.ipsec.ike.IkeSession;
-import android.net.ipsec.ike.IkeSessionParams;
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-import android.platform.test.annotations.AppModeFull;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-@RunWith(AndroidJUnit4.class)
-@AppModeFull(reason = "MANAGE_IPSEC_TUNNELS permission can't be granted to instant apps")
-public class IkeSessionPskTest extends IkeSessionTestBase {
-    // Test vectors for success workflow
-    private static final String SUCCESS_IKE_INIT_RESP =
-            "46B8ECA1E0D72A18B45427679F9245D421202220000000000000015022000030"
-                    + "0000002C010100040300000C0100000C800E0080030000080300000203000008"
-                    + "0200000200000008040000022800008800020000A7AA3435D088EC1A2B7C2A47"
-                    + "1FA1B85F1066C9B2006E7C353FB5B5FDBC2A88347ED2C6F5B7A265D03AE34039"
-                    + "6AAC0145CFCC93F8BDB219DDFF22A603B8856A5DC59B6FAB7F17C5660CF38670"
-                    + "8794FC72F273ADEB7A4F316519794AED6F8AB61F95DFB360FAF18C6C8CABE471"
-                    + "6E18FE215348C2E582171A57FC41146B16C4AFE429000024A634B61C0E5C90C6"
-                    + "8D8818B0955B125A9B1DF47BBD18775710792E651083105C2900001C00004004"
-                    + "406FA3C5685A16B9B72C7F2EEE9993462C619ABE2900001C00004005AF905A87"
-                    + "0A32222AA284A7070585601208A282F0290000080000402E290000100000402F"
-                    + "00020003000400050000000800004014";
-    private static final String SUCCESS_IKE_AUTH_RESP =
-            "46B8ECA1E0D72A18B45427679F9245D42E20232000000001000000EC240000D0"
-                    + "0D06D37198F3F0962DE8170D66F1A9008267F98CDD956D984BDCED2FC7FAF84A"
-                    + "A6664EF25049B46B93C9ED420488E0C172AA6635BF4011C49792EF2B88FE7190"
-                    + "E8859FEEF51724FD20C46E7B9A9C3DC4708EF7005707A18AB747C903ABCEAC5C"
-                    + "6ECF5A5FC13633DCE3844A920ED10EF202F115DBFBB5D6D2D7AB1F34EB08DE7C"
-                    + "A54DCE0A3A582753345CA2D05A0EFDB9DC61E81B2483B7D13EEE0A815D37252C"
-                    + "23D2F29E9C30658227D2BB0C9E1A481EAA80BC6BE9006BEDC13E925A755A0290"
-                    + "AEC4164D29997F52ED7DCC2E";
-    private static final String SUCCESS_CREATE_CHILD_RESP =
-            "46B8ECA1E0D72A18B45427679F9245D42E20242000000002000000CC210000B0"
-                    + "484565D4AF6546274674A8DE339E9C9584EE2326AB9260F41C4D0B6C5B02D1D"
-                    + "2E8394E3CDE3094895F2ACCABCDCA8E82960E5196E9622BD13745FC8D6A2BED"
-                    + "E561FF5D9975421BC463C959A3CBA3478256B6D278159D99B512DDF56AC1658"
-                    + "63C65A986F395FE8B1476124B91F83FD7865304EB95B22CA4DD9601DA7A2533"
-                    + "ABF4B36EB1B8CD09522F6A600032316C74E562E6756D9D49D945854E2ABDC4C"
-                    + "3AF36305353D60D40B58BE44ABF82";
-    private static final String SUCCESS_DELETE_CHILD_RESP =
-            "46B8ECA1E0D72A18B45427679F9245D42E202520000000030000004C2A000030"
-                    + "0C5CEB882DBCA65CE32F4C53909335F1365C91C555316C5E9D9FB553F7AA916"
-                    + "EF3A1D93460B7FABAF0B4B854";
-    private static final String SUCCESS_DELETE_IKE_RESP =
-            "46B8ECA1E0D72A18B45427679F9245D42E202520000000040000004C00000030"
-                    + "9352D71100777B00ABCC6BD7DBEA697827FFAAA48DF9A54D1D68161939F5DC8"
-                    + "6743A7CEB2BE34AC00095A5B8";
-
-    private IkeSession openIkeSessionWithTunnelModeChild(InetAddress remoteAddress) {
-        return openIkeSession(remoteAddress, buildTunnelModeChildSessionParams());
-    }
-
-    private IkeSession openIkeSessionWithTransportModeChild(InetAddress remoteAddress) {
-        return openIkeSession(remoteAddress, buildTransportModeChildParamsWithDefaultTs());
-    }
-
-    private IkeSession openIkeSession(InetAddress remoteAddress, ChildSessionParams childParams) {
-        IkeSessionParams ikeParams =
-                new IkeSessionParams.Builder(sContext)
-                        .setNetwork(mTunNetwork)
-                        .setServerHostname(remoteAddress.getHostAddress())
-                        .addSaProposal(SaProposalTest.buildIkeSaProposalWithNormalModeCipher())
-                        .addSaProposal(SaProposalTest.buildIkeSaProposalWithCombinedModeCipher())
-                        .setLocalIdentification(new IkeFqdnIdentification(LOCAL_HOSTNAME))
-                        .setRemoteIdentification(new IkeFqdnIdentification(REMOTE_HOSTNAME))
-                        .setAuthPsk(IKE_PSK)
-                        .build();
-        return new IkeSession(
-                sContext,
-                ikeParams,
-                childParams,
-                mUserCbExecutor,
-                mIkeSessionCallback,
-                mFirstChildSessionCallback);
-    }
-
-    @BeforeClass
-    public static void setUpTunnelPermissionBeforeClass() throws Exception {
-        // Under normal circumstances, the MANAGE_IPSEC_TUNNELS appop would be auto-granted, and
-        // a standard permission is insufficient. So we shell out the appop, to give us the
-        // right appop permissions.
-        setAppOp(OP_MANAGE_IPSEC_TUNNELS, true);
-    }
-
-    // This method is guaranteed to run in subclasses and will run after subclasses' @AfterClass
-    // methods.
-    @AfterClass
-    public static void tearDownTunnelPermissionAfterClass() throws Exception {
-        setAppOp(OP_MANAGE_IPSEC_TUNNELS, false);
-    }
-
-    @Test
-    public void testIkeSessionSetupAndChildSessionSetupWithTunnelMode() throws Exception {
-        if (!hasTunnelsFeature()) return;
-
-        // Open IKE Session
-        IkeSession ikeSession = openIkeSessionWithTunnelModeChild(mRemoteAddress);
-        performSetupIkeAndFirstChildBlocking(SUCCESS_IKE_INIT_RESP, SUCCESS_IKE_AUTH_RESP);
-
-        // IKE INIT and IKE AUTH takes two exchanges. Message ID starts from 2
-        int expectedMsgId = 2;
-
-        verifyIkeSessionSetupBlocking();
-        verifyChildSessionSetupBlocking(
-                mFirstChildSessionCallback,
-                Arrays.asList(TUNNEL_MODE_INBOUND_TS),
-                Arrays.asList(TUNNEL_MODE_OUTBOUND_TS),
-                Arrays.asList(EXPECTED_INTERNAL_LINK_ADDR));
-
-        IpSecTransformCallRecord firstTransformRecordA =
-                mFirstChildSessionCallback.awaitNextCreatedIpSecTransform();
-        IpSecTransformCallRecord firstTransformRecordB =
-                mFirstChildSessionCallback.awaitNextCreatedIpSecTransform();
-        verifyCreateIpSecTransformPair(firstTransformRecordA, firstTransformRecordB);
-
-        // Open additional Child Session
-        TestChildSessionCallback additionalChildCb = new TestChildSessionCallback();
-        ikeSession.openChildSession(buildTunnelModeChildSessionParams(), additionalChildCb);
-        mTunUtils.awaitReqAndInjectResp(
-                IKE_DETERMINISTIC_INITIATOR_SPI,
-                expectedMsgId++,
-                true /* expectedUseEncap */,
-                SUCCESS_CREATE_CHILD_RESP);
-
-        // Verify opening additional Child Session
-        verifyChildSessionSetupBlocking(
-                additionalChildCb,
-                Arrays.asList(TUNNEL_MODE_INBOUND_TS),
-                Arrays.asList(TUNNEL_MODE_OUTBOUND_TS),
-                new ArrayList<LinkAddress>());
-        IpSecTransformCallRecord additionalTransformRecordA =
-                additionalChildCb.awaitNextCreatedIpSecTransform();
-        IpSecTransformCallRecord additionalTransformRecordB =
-                additionalChildCb.awaitNextCreatedIpSecTransform();
-        verifyCreateIpSecTransformPair(additionalTransformRecordA, additionalTransformRecordB);
-
-        // Close additional Child Session
-        ikeSession.closeChildSession(additionalChildCb);
-        mTunUtils.awaitReqAndInjectResp(
-                IKE_DETERMINISTIC_INITIATOR_SPI,
-                expectedMsgId++,
-                true /* expectedUseEncap */,
-                SUCCESS_DELETE_CHILD_RESP);
-
-        verifyDeleteIpSecTransformPair(
-                additionalChildCb, additionalTransformRecordA, additionalTransformRecordB);
-        additionalChildCb.awaitOnClosed();
-
-        // Close IKE Session
-        ikeSession.close();
-        performCloseIkeBlocking(expectedMsgId++, SUCCESS_DELETE_IKE_RESP);
-        verifyCloseIkeAndChildBlocking(firstTransformRecordA, firstTransformRecordB);
-    }
-
-    @Test
-    public void testIkeSessionSetupAndChildSessionSetupWithTunnelModeV6() throws Exception {
-        if (!hasTunnelsFeature()) return;
-
-        final String ikeInitResp =
-                "46B8ECA1E0D72A186F7B6C2CEB77EB9021202220000000000000011822000030"
-                        + "0000002C010100040300000C0100000C800E0100030000080300000C03000008"
-                        + "0200000500000008040000022800008800020000DABAA04B38B491E2403F2125"
-                        + "96ECF1C8EF7B1DC19A422FDD46E1756C826BB3A16404361B775D9950577B5CDF"
-                        + "6AAA1642BD1427BDA8BC55354A97C1025E19C1E2EE2DF8A0C9406E545D829F52"
-                        + "75695008E3B742984B8DD1770F3514213B0DF3EE8B199416DF200D248115C057"
-                        + "1C193E4F96802E5EF48DD99CAC251882A8F7CCC329000024BC6F0F1D3653C2C7"
-                        + "679E02CDB6A3B32B2FEE9AF52F0326D4D9AE073D56CE8922290000080000402E"
-                        + "290000100000402F00020003000400050000000800004014";
-        final String ikeAuthResp =
-                "46B8ECA1E0D72A186F7B6C2CEB77EB902E202320000000010000015024000134"
-                        + "4D115AFDCDAD0310760BB664EB7D405A340869AD6EDF0AAEAD0663A9253DADCB"
-                        + "73EBE5CD29D4FA1CDEADE0B94391B5C4CF77BCC1596ACE3CE6A7891E44888FA5"
-                        + "46632C0EF4E6193C023C9DC59142C37D1C49D6EF5CD324EC6FC35C89E1721C78"
-                        + "91FDCDB723D8062709950F4AA9273D26A54C9C7E86862DBC15F7B6641D2B9BAD"
-                        + "E55069008201D12968D97B537B1518FE87B0FFA03C3EE6012C06721B1E2A3F68"
-                        + "92108BC4A4F7063F7F94562D8B60F291A1377A836CF12BCDA7E15C1A8F3C77BB"
-                        + "6DB7F2C833CCE4CDDED7506536621A3356CE2BC1874E7B1A1A9B447D7DF6AB09"
-                        + "638B8AD94A781B28BB91B514B611B24DF8E8A047A10AE27BBF15C754D3D2F792"
-                        + "D3E1CCADDAE934C98AE53A8FC3419C88AFF0355564F82A629C998012DA7BB704"
-                        + "5307270DF326377E3E1994476902035B";
-        final String deleteIkeResp =
-                "46B8ECA1E0D72A186F7B6C2CEB77EB902E202520000000020000005000000034"
-                        + "CF15C299F35688E5140A48B61C95F004121BF8236201415E5CD45BA41AAB16D4"
-                        + "90B44B9E6D5D92B5B97D24196A58C73F";
-
-        mLocalAddress = IPV6_ADDRESS_LOCAL;
-        mRemoteAddress = IPV6_ADDRESS_REMOTE;
-
-        // Teardown current test network that uses IPv4 address and set up new network with IPv6
-        // address.
-        tearDownTestNetwork();
-        setUpTestNetwork(mLocalAddress);
-
-        // Open IKE Session
-        IkeSession ikeSession = openIkeSessionWithTunnelModeChild(mRemoteAddress);
-        performSetupIkeAndFirstChildBlocking(
-                ikeInitResp,
-                1 /* expectedAuthReqPktCnt */,
-                false /* expectedAuthUseEncap */,
-                ikeAuthResp);
-
-        // Local request message ID starts from 2 because there is one IKE_INIT message and a single
-        // IKE_AUTH message.
-        int expectedMsgId = 2;
-
-        verifyIkeSessionSetupBlocking();
-        verifyChildSessionSetupBlocking(
-                mFirstChildSessionCallback,
-                Arrays.asList(TUNNEL_MODE_INBOUND_TS_V6),
-                Arrays.asList(TUNNEL_MODE_OUTBOUND_TS_V6),
-                Arrays.asList(EXPECTED_INTERNAL_LINK_ADDR_V6),
-                Arrays.asList(EXPECTED_DNS_SERVERS_ONE, EXPECTED_DNS_SERVERS_TWO));
-
-        IpSecTransformCallRecord firstTransformRecordA =
-                mFirstChildSessionCallback.awaitNextCreatedIpSecTransform();
-        IpSecTransformCallRecord firstTransformRecordB =
-                mFirstChildSessionCallback.awaitNextCreatedIpSecTransform();
-        verifyCreateIpSecTransformPair(firstTransformRecordA, firstTransformRecordB);
-
-        // Close IKE Session
-        ikeSession.close();
-        performCloseIkeBlocking(expectedMsgId++, false /* expectedUseEncap */, deleteIkeResp);
-        verifyCloseIkeAndChildBlocking(firstTransformRecordA, firstTransformRecordB);
-    }
-
-    @Test
-    public void testIkeSessionKillWithTunnelMode() throws Exception {
-        if (!hasTunnelsFeature()) return;
-
-        // Open IKE Session
-        IkeSession ikeSession = openIkeSessionWithTunnelModeChild(mRemoteAddress);
-        performSetupIkeAndFirstChildBlocking(SUCCESS_IKE_INIT_RESP, SUCCESS_IKE_AUTH_RESP);
-
-        ikeSession.kill();
-        mFirstChildSessionCallback.awaitOnClosed();
-        mIkeSessionCallback.awaitOnClosed();
-    }
-
-    @Test
-    public void testIkeInitFail() throws Exception {
-        final String ikeInitFailRespHex =
-                "46B8ECA1E0D72A180000000000000000292022200000000000000024000000080000000E";
-
-        // Open IKE Session
-        IkeSession ikeSession = openIkeSessionWithTransportModeChild(mRemoteAddress);
-        int expectedMsgId = 0;
-        mTunUtils.awaitReqAndInjectResp(
-                IKE_DETERMINISTIC_INITIATOR_SPI,
-                expectedMsgId++,
-                false /* expectedUseEncap */,
-                ikeInitFailRespHex);
-
-        mFirstChildSessionCallback.awaitOnClosed();
-
-        IkeProtocolException protocolException =
-                (IkeProtocolException) mIkeSessionCallback.awaitOnClosedException();
-        assertEquals(ERROR_TYPE_NO_PROPOSAL_CHOSEN, protocolException.getErrorType());
-        assertArrayEquals(EXPECTED_PROTOCOL_ERROR_DATA_NONE, protocolException.getErrorData());
-    }
-
-    @Test
-    public void testIkeAuthHandlesAuthFailNotification() throws Exception {
-        final String ikeInitRespHex =
-                "46B8ECA1E0D72A18CF94CE3159486F002120222000000000000001502200"
-                        + "00300000002C010100040300000C0100000C800E01000300000803000005"
-                        + "0300000802000004000000080400000228000088000200001821AA854691"
-                        + "FA3292DF710F0AC149ACBD0CB421608B8796C1912AF04C5B4B23936FDEC4"
-                        + "7CB640E3EAFB56BBB562825E87AF68B40E4BAB80A49BAD44407450A4195A"
-                        + "1DD54BD99F48D28C9F0FBA315A3401C1C3C4AD55911F514A8DF2D2467C46"
-                        + "A73DDC1452AE81336E0F0D5EC896D2E7A77628AF2F9089F48943399DF216"
-                        + "EFCD2900002418D2B7E4E6AF0FEFF5962CF8D68F7793B1293FEDE13331D4"
-                        + "AB0CE9436C2EE1EC2900001C0000400457BD9AEF5B362A83DD7F3DDAA4A9"
-                        + "9B6B4041DAF32900001C000040055A81893582701E44D4B6729A22FE06DE"
-                        + "82A03A36290000080000402E290000100000402F00020003000400050000"
-                        + "000800004014";
-        final String ikeAuthFailRespHex =
-                "46B8ECA1E0D72A18CF94CE3159486F002E202320000000010000004C2900"
-                        + "00301B9E4C8242D3BE62E7F0A537FE8B92C6EAB7153105DA421DCE43A06D"
-                        + "AB6E4808BAC0CA1DAD6ADD0A126A41BD";
-
-        // Open IKE Session
-        IkeSession ikeSession = openIkeSessionWithTransportModeChild(mRemoteAddress);
-        performSetupIkeAndFirstChildBlocking(ikeInitRespHex, ikeAuthFailRespHex);
-
-        mFirstChildSessionCallback.awaitOnClosed();
-        IkeProtocolException protocolException =
-                (IkeProtocolException) mIkeSessionCallback.awaitOnClosedException();
-        assertEquals(ERROR_TYPE_AUTHENTICATION_FAILED, protocolException.getErrorType());
-        assertArrayEquals(EXPECTED_PROTOCOL_ERROR_DATA_NONE, protocolException.getErrorData());
-    }
-
-    @Test
-    public void testIkeAuthHandlesFirstChildCreationFail() throws Exception {
-        final String ikeInitRespHex =
-                "46B8ECA1E0D72A18F5ABBF896A1240BE2120222000000000000001502200"
-                        + "00300000002C010100040300000C0100000C800E0100030000080300000C"
-                        + "03000008020000050000000804000002280000880002000074950F016B85"
-                        + "605E57E24651843AB70E41B552EDEE227DFE51E6CBEC00E75FFEFC7D5453"
-                        + "109B15F721FCD811FC9F113BE06050882F2FC5F5FF25857E555CCFB5AB64"
-                        + "8B0D1D7A819A3B05DE1FE89A4A627C60D5AA06CD0F66ACD3748722F9CD4F"
-                        + "F30AE7477CBC12049821F07AD6C9F0ED732321A6A36FA817722E025AC34B"
-                        + "ABE62900002432E3807F595070E95EDA341A787599B24B1151B535B0222B"
-                        + "65C003401B9B38F82900001C000040043BB760DB3037B51768DFFAB4B21D"
-                        + "B1716EA1C1382900001C0000400531098EB04DF1BE3F304606BD59B454A8"
-                        + "CC7E7311290000080000402E290000100000402F00020003000400050000"
-                        + "000800004014";
-        final String ikeAuthCreateChildFailHex =
-                "46B8ECA1E0D72A18F5ABBF896A1240BE2E20232000000001000000B02400"
-                        + "009400B0861242E0C88ECB3848D772B560CAD65B6AC9DFFDC8622A394B8E"
-                        + "64E550BDD69FCD7E768129787ED9062992C1D6DB0F0631C2E05765B403CF"
-                        + "EF1D0A055B32F6698FF7DB5B8FB1B6A83A81634D00E22C86E35B3BFBEC73"
-                        + "EAC6806678926945BC7A57003DC1A3528A1EC423EE56C1075B36C0B57A6B"
-                        + "C6DD990182F6FABFFA167D199C7D629E5B830AAD2AFBD31CEBA6";
-
-        // Open IKE Session
-        IkeSession ikeSession = openIkeSessionWithTransportModeChild(mRemoteAddress);
-        performSetupIkeAndFirstChildBlocking(ikeInitRespHex, ikeAuthCreateChildFailHex);
-
-        // Even though the child creation failed, the authentication succeeded, so the IKE Session's
-        // onOpened() callback is still expected
-        verifyIkeSessionSetupBlocking();
-
-        // Verify Child Creation failed
-        IkeProtocolException protocolException =
-                (IkeProtocolException) mFirstChildSessionCallback.awaitOnClosedException();
-        assertEquals(ERROR_TYPE_TS_UNACCEPTABLE, protocolException.getErrorType());
-        assertArrayEquals(EXPECTED_PROTOCOL_ERROR_DATA_NONE, protocolException.getErrorData());
-
-        ikeSession.kill();
-        mIkeSessionCallback.awaitOnClosed();
-    }
-}
diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionRekeyTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionRekeyTest.java
deleted file mode 100644
index f954fcd..0000000
--- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionRekeyTest.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * 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 android.net.ipsec.ike.cts;
-
-import static com.android.internal.util.HexDump.hexStringToByteArray;
-
-import android.net.InetAddresses;
-import android.net.LinkAddress;
-import android.net.ipsec.ike.IkeFqdnIdentification;
-import android.net.ipsec.ike.IkeSession;
-import android.net.ipsec.ike.IkeSessionParams;
-import android.net.ipsec.ike.IkeTrafficSelector;
-import android.net.ipsec.ike.cts.IkeTunUtils.PortPair;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-/**
- * Explicitly test transport mode Child SA so that devices without FEATURE_IPSEC_TUNNELS can be test
- * covered. Tunnel mode Child SA setup has been tested in IkeSessionPskTest. Rekeying process is
- * independent from Child SA mode.
- */
-@RunWith(AndroidJUnit4.class)
-public class IkeSessionRekeyTest extends IkeSessionTestBase {
-    // This value is align with the test vectors hex that are generated in an IPv4 environment
-    private static final IkeTrafficSelector TRANSPORT_MODE_INBOUND_TS =
-            new IkeTrafficSelector(
-                    MIN_PORT,
-                    MAX_PORT,
-                    InetAddresses.parseNumericAddress("172.58.35.40"),
-                    InetAddresses.parseNumericAddress("172.58.35.40"));
-
-    private IkeSession openIkeSessionWithRemoteAddress(InetAddress remoteAddress) {
-        IkeSessionParams ikeParams =
-                new IkeSessionParams.Builder(sContext)
-                        .setNetwork(mTunNetwork)
-                        .setServerHostname(remoteAddress.getHostAddress())
-                        .addSaProposal(SaProposalTest.buildIkeSaProposalWithNormalModeCipher())
-                        .addSaProposal(SaProposalTest.buildIkeSaProposalWithCombinedModeCipher())
-                        .setLocalIdentification(new IkeFqdnIdentification(LOCAL_HOSTNAME))
-                        .setRemoteIdentification(new IkeFqdnIdentification(REMOTE_HOSTNAME))
-                        .setAuthPsk(IKE_PSK)
-                        .build();
-        return new IkeSession(
-                sContext,
-                ikeParams,
-                buildTransportModeChildParamsWithTs(
-                        TRANSPORT_MODE_INBOUND_TS, TRANSPORT_MODE_OUTBOUND_TS),
-                mUserCbExecutor,
-                mIkeSessionCallback,
-                mFirstChildSessionCallback);
-    }
-
-    private byte[] buildInboundPkt(PortPair outPktSrcDestPortPair, String inboundDataHex)
-            throws Exception {
-        // Build inbound packet by flipping the outbound packet addresses and ports
-        return IkeTunUtils.buildIkePacket(
-                mRemoteAddress,
-                mLocalAddress,
-                outPktSrcDestPortPair.dstPort,
-                outPktSrcDestPortPair.srcPort,
-                true /* useEncap */,
-                hexStringToByteArray(inboundDataHex));
-    }
-
-    @Test
-    public void testRekeyIke() throws Exception {
-        final String ikeInitResp =
-                "46B8ECA1E0D72A1866B5248CF6C7472D21202220000000000000015022000030"
-                        + "0000002C010100040300000C0100000C800E0100030000080300000C03000008"
-                        + "0200000500000008040000022800008800020000920D3E830E7276908209212D"
-                        + "E5A7F2A48706CFEF1BE8CB6E3B173B8B4E0D8C2DC626271FF1B13A88619E569E"
-                        + "7B03C3ED2C127390749CDC7CDC711D0A8611E4457FFCBC4F0981B3288FBF58EA"
-                        + "3E8B70E27E76AE70117FBBCB753660ADDA37EB5EB3A81BED6A374CCB7E132C2A"
-                        + "94BFCE402DC76B19C158B533F6B1F2ABF01ACCC329000024B302CA2FB85B6CF4"
-                        + "02313381246E3C53828D787F6DFEA6BD62D6405254AEE6242900001C00004004"
-                        + "7A1682B06B58596533D00324886EF1F20EF276032900001C00004005BF633E31"
-                        + "F9984B29A62E370BB2770FC09BAEA665290000080000402E290000100000402F"
-                        + "00020003000400050000000800004014";
-        final String ikeAuthResp =
-                "46B8ECA1E0D72A1866B5248CF6C7472D2E20232000000001000000F0240000D4"
-                        + "10166CA8647F56123DE74C17FA5E256043ABF73216C812EE32EE1BB01EAF4A82"
-                        + "DC107AB3ADBFEE0DEA5EEE10BDD5D43178F4C975C7C775D252273BB037283C7F"
-                        + "236FE34A6BCE4833816897075DB2055B9FFD66DFA45A0A89A8F70AFB59431EED"
-                        + "A20602FB614369D12906D3355CF7298A5D25364ABBCC75A9D88E0E6581449FCD"
-                        + "4E361A39E00EFD1FD0A69651F63DB46C12470226AA21BA5EFF48FAF0B6DDF61C"
-                        + "B0A69392CE559495EEDB4D1C1D80688434D225D57210A424C213F7C993D8A456"
-                        + "38153FBD194C5E247B592D1D048DB4C8";
-        final String rekeyIkeCreateReq =
-                "46B8ECA1E0D72A1866B5248CF6C7472D2E202400000000000000013021000114"
-                        + "13743670039E308A8409BA5FD47B67F956B36FEE88AC3B70BB5D789B8218A135"
-                        + "1B3D83E260E87B3EDB1BF064F09D4DC2611AEDBC99951B4B2DE767BD4AA2ACC3"
-                        + "3653549CFC66B75869DF003CDC9A137A9CC27776AD5732B34203E74BE8CA4858"
-                        + "1D5C0D9C9CA52D680EB299B4B21C7FA25FFEE174D57015E0FF2EAED653AAD95C"
-                        + "071ABE269A8C2C9FBC1188E07550EB992F910D4CA9689E44BA66DE0FABB2BDF9"
-                        + "8DD377186DBB25EF9B68B027BB2A27981779D8303D88D7CE860010A42862D50B"
-                        + "1E0DBFD3D27C36F14809D7F493B2B96A65534CF98B0C32AD5219AD77F681AC04"
-                        + "9D5CB89A0230A91A243FA7F16251B0D9B4B65E7330BEEAC9663EF4578991EAC8"
-                        + "46C19EBB726E7D113F1D0D601102C05E";
-        final String rekeyIkeDeleteReq =
-                "46B8ECA1E0D72A1866B5248CF6C7472D2E20250000000001000000502A000034"
-                        + "02E40C0C7B1ED977729F705BB9B643FAC513A1070A6EB28ECD2AEA8A441ADC05"
-                        + "7841382A7967BBF116AE52496590B2AD";
-        final String deleteIkeReq =
-                "7D3DEDC65407D1FC9361C8CF8C47162A2E20250800000000000000502A000034"
-                        + "201915C9E4E9173AA9EE79F3E02FE2D4954B22085C66D164762C34D347C16E9F"
-                        + "FC5F7F114428C54D8D915860C57B1BC1";
-        final long newIkeDeterministicInitSpi = Long.parseLong("7D3DEDC65407D1FC", 16);
-
-        // Open IKE Session
-        IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
-        PortPair localRemotePorts = performSetupIkeAndFirstChildBlocking(ikeInitResp, ikeAuthResp);
-
-        // Local request message ID starts from 2 because there is one IKE_INIT message and a single
-        // IKE_AUTH message.
-        int expectedReqMsgId = 2;
-        int expectedRespMsgId = 0;
-
-        verifyIkeSessionSetupBlocking();
-        verifyChildSessionSetupBlocking(
-                mFirstChildSessionCallback,
-                Arrays.asList(TRANSPORT_MODE_INBOUND_TS),
-                Arrays.asList(TRANSPORT_MODE_OUTBOUND_TS),
-                new ArrayList<LinkAddress>());
-        IpSecTransformCallRecord firstTransformRecordA =
-                mFirstChildSessionCallback.awaitNextCreatedIpSecTransform();
-        IpSecTransformCallRecord firstTransformRecordB =
-                mFirstChildSessionCallback.awaitNextCreatedIpSecTransform();
-        verifyCreateIpSecTransformPair(firstTransformRecordA, firstTransformRecordB);
-
-        // Inject rekey IKE requests
-        mTunUtils.injectPacket(buildInboundPkt(localRemotePorts, rekeyIkeCreateReq));
-        mTunUtils.awaitResp(
-                IKE_DETERMINISTIC_INITIATOR_SPI, expectedRespMsgId++, true /* expectedUseEncap */);
-        mTunUtils.injectPacket(buildInboundPkt(localRemotePorts, rekeyIkeDeleteReq));
-        mTunUtils.awaitResp(
-                IKE_DETERMINISTIC_INITIATOR_SPI, expectedRespMsgId++, true /* expectedUseEncap */);
-
-        // IKE has been rekeyed, reset message IDs
-        expectedReqMsgId = 0;
-        expectedRespMsgId = 0;
-
-        // Inject delete IKE request
-        mTunUtils.injectPacket(buildInboundPkt(localRemotePorts, deleteIkeReq));
-        mTunUtils.awaitResp(
-                newIkeDeterministicInitSpi, expectedRespMsgId++, true /* expectedUseEncap */);
-
-        verifyDeleteIpSecTransformPair(
-                mFirstChildSessionCallback, firstTransformRecordA, firstTransformRecordB);
-        mFirstChildSessionCallback.awaitOnClosed();
-        mIkeSessionCallback.awaitOnClosed();
-    }
-
-    @Test
-    public void testRekeyTransportModeChildSa() throws Exception {
-        final String ikeInitResp =
-                "46B8ECA1E0D72A18CECD871146CF83A121202220000000000000015022000030"
-                        + "0000002C010100040300000C0100000C800E0100030000080300000C03000008"
-                        + "0200000500000008040000022800008800020000C4904458957746BCF1C12972"
-                        + "1D4E19EB8A584F78DE673053396D167CE0F34552DBC69BA63FE7C673B4CF4A99"
-                        + "62481518EE985357876E8C47BAAA0DBE9C40AE47B12E52165874703586E8F786"
-                        + "045F72EEEB238C5D1823352BED44B71B3214609276ADC0B3D42DAC820168C4E2"
-                        + "660730DAAC92492403288805EBB9053F1AB060DA290000242D9364ACB93519FF"
-                        + "8F8B019BAA43A40D699F59714B327B8382216EF427ED52282900001C00004004"
-                        + "06D91438A0D6B734E152F76F5CC55A72A2E38A0A2900001C000040052EFF78B3"
-                        + "55B37F3CE75AFF26C721B050F892C0D6290000080000402E290000100000402F"
-                        + "00020003000400050000000800004014";
-        final String ikeAuthResp =
-                "46B8ECA1E0D72A18CECD871146CF83A12E20232000000001000000F0240000D4"
-                        + "A17BC258BA2714CF536663639DD5F665A60C75E93557CD5141990A8CEEDD2017"
-                        + "93F5B181C8569FBCD6C2A00198EC2B62D42BEFAC016B8B6BF6A7BC9CEDE3413A"
-                        + "6C495A6B8EC941864DC3E08F57D015EA6520C4B05884960B85478FCA53DA5F17"
-                        + "9628BB1097DA77461C71837207A9EB80720B3E6E661816EE4E14AC995B5E8441"
-                        + "A4C3F9097CC148142BA300076C94A23EC4ADE82B1DD2B121F7E9102860A8C3BF"
-                        + "58DDC207285A3176E924C44DE820322524E1AA438EFDFBA781B36084AED80846"
-                        + "3B77FCED9682B6E4E476408EF3F1037E";
-        final String rekeyChildCreateReq =
-                "46B8ECA1E0D72A18CECD871146CF83A12E202400000000000000015029000134"
-                        + "319D74B6B155B86942143CEC1D29D21F073F24B7BEDC9BFE0F0FDD8BDB5458C0"
-                        + "8DB93506E1A43DD0640FE7370C97F9B34FF4EC9B2DB7257A87B75632301FB68A"
-                        + "86B54871249534CA3D01C9BEB127B669F46470E1C8AAF72574C3CEEC15B901CF"
-                        + "5A0D6ADAE59C3CA64AC8C86689C860FAF9500E608DFE63F2DCD30510FD6FFCD5"
-                        + "A50838574132FD1D069BCACD4C7BAF45C9B1A7689FAD132E3F56DBCFAF905A8C"
-                        + "4145D4BA1B74A54762F8F43308D94DE05649C49D885121CE30681D51AC1E3E68"
-                        + "AB82F9A19B99579AFE257F32DBD1037814DA577379E4F42DEDAC84502E49C933"
-                        + "9EA83F6F5DB4401B660CB1681B023B8603D205DFDD1DE86AD8DE22B6B754F30D"
-                        + "05EAE81A709C2CEE81386133DC3DC7B5EF8F166E48E54A0722DD0C64F4D00638"
-                        + "40F272144C47F6ECED72A248180645DB";
-        final String rekeyChildDeleteReq =
-                "46B8ECA1E0D72A18CECD871146CF83A12E20250000000001000000502A000034"
-                        + "02D98DAF0432EBD991CA4F2D89C1E0EFABC6E91A3327A85D8914FB2F1485BE1B"
-                        + "8D3415D548F7CE0DC4224E7E9D0D3355";
-        final String deleteIkeReq =
-                "46B8ECA1E0D72A18CECD871146CF83A12E20250000000002000000502A000034"
-                        + "095041F4026B4634F04B0AB4F9349484F7BE9AEF03E3733EEE293330043B75D2"
-                        + "ABF5F965ED51127629585E1B1BBA787F";
-
-        // Open IKE Session
-        IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
-        PortPair localRemotePorts = performSetupIkeAndFirstChildBlocking(ikeInitResp, ikeAuthResp);
-
-        // IKE INIT and IKE AUTH takes two exchanges. Local request message ID starts from 2
-        int expectedReqMsgId = 2;
-        int expectedRespMsgId = 0;
-
-        verifyIkeSessionSetupBlocking();
-        verifyChildSessionSetupBlocking(
-                mFirstChildSessionCallback,
-                Arrays.asList(TRANSPORT_MODE_INBOUND_TS),
-                Arrays.asList(TRANSPORT_MODE_OUTBOUND_TS),
-                new ArrayList<LinkAddress>());
-        IpSecTransformCallRecord oldTransformRecordA =
-                mFirstChildSessionCallback.awaitNextCreatedIpSecTransform();
-        IpSecTransformCallRecord oldTransformRecordB =
-                mFirstChildSessionCallback.awaitNextCreatedIpSecTransform();
-        verifyCreateIpSecTransformPair(oldTransformRecordA, oldTransformRecordB);
-
-        // Inject rekey Child requests
-        mTunUtils.injectPacket(buildInboundPkt(localRemotePorts, rekeyChildCreateReq));
-        mTunUtils.awaitResp(
-                IKE_DETERMINISTIC_INITIATOR_SPI, expectedRespMsgId++, true /* expectedUseEncap */);
-        mTunUtils.injectPacket(buildInboundPkt(localRemotePorts, rekeyChildDeleteReq));
-        mTunUtils.awaitResp(
-                IKE_DETERMINISTIC_INITIATOR_SPI, expectedRespMsgId++, true /* expectedUseEncap */);
-
-        // Verify IpSecTransforms are renewed
-        IpSecTransformCallRecord newTransformRecordA =
-                mFirstChildSessionCallback.awaitNextCreatedIpSecTransform();
-        IpSecTransformCallRecord newTransformRecordB =
-                mFirstChildSessionCallback.awaitNextCreatedIpSecTransform();
-        verifyCreateIpSecTransformPair(newTransformRecordA, newTransformRecordB);
-        verifyDeleteIpSecTransformPair(
-                mFirstChildSessionCallback, oldTransformRecordA, oldTransformRecordB);
-
-        // Inject delete IKE request
-        mTunUtils.injectPacket(buildInboundPkt(localRemotePorts, deleteIkeReq));
-        mTunUtils.awaitResp(
-                IKE_DETERMINISTIC_INITIATOR_SPI, expectedRespMsgId++, true /* expectedUseEncap */);
-
-        verifyDeleteIpSecTransformPair(
-                mFirstChildSessionCallback, newTransformRecordA, newTransformRecordB);
-        mFirstChildSessionCallback.awaitOnClosed();
-        mIkeSessionCallback.awaitOnClosed();
-    }
-}
diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java
deleted file mode 100644
index 6264cea..0000000
--- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java
+++ /dev/null
@@ -1,598 +0,0 @@
-/*
- * 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
- *
- * 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 android.net.ipsec.ike.cts;
-
-import static android.net.ipsec.ike.IkeSessionConfiguration.EXTENSION_TYPE_FRAGMENTATION;
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.AF_INET6;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import android.annotation.NonNull;
-import android.app.AppOpsManager;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.net.ConnectivityManager;
-import android.net.InetAddresses;
-import android.net.IpSecManager;
-import android.net.IpSecTransform;
-import android.net.LinkAddress;
-import android.net.Network;
-import android.net.TestNetworkInterface;
-import android.net.TestNetworkManager;
-import android.net.annotations.PolicyDirection;
-import android.net.ipsec.ike.ChildSessionCallback;
-import android.net.ipsec.ike.ChildSessionConfiguration;
-import android.net.ipsec.ike.IkeSessionCallback;
-import android.net.ipsec.ike.IkeSessionConfiguration;
-import android.net.ipsec.ike.IkeSessionConnectionInfo;
-import android.net.ipsec.ike.IkeTrafficSelector;
-import android.net.ipsec.ike.TransportModeChildSessionParams;
-import android.net.ipsec.ike.TunnelModeChildSessionParams;
-import android.net.ipsec.ike.cts.IkeTunUtils.PortPair;
-import android.net.ipsec.ike.cts.TestNetworkUtils.TestNetworkCallback;
-import android.net.ipsec.ike.exceptions.IkeException;
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-import android.os.Binder;
-import android.os.ParcelFileDescriptor;
-import android.platform.test.annotations.AppModeFull;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import com.android.compatibility.common.util.SystemUtil;
-import com.android.net.module.util.ArrayTrackRecord;
-
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.runner.RunWith;
-
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Package private base class for testing IkeSessionParams and IKE exchanges.
- *
- * <p>Subclasses MUST explicitly call #setUpTestNetwork and #tearDownTestNetwork to be able to use
- * the test network
- *
- * <p>All IKE Sessions running in test mode will generate SPIs deterministically. That is to say
- * each IKE Session will always generate the same IKE INIT SPI and test vectors are generated based
- * on this deterministic IKE SPI. Each test will use different local and remote addresses to avoid
- * the case that the next test try to allocate the same SPI before the previous test has released
- * it, since SPI resources are not released in testing thread. Similarly, each test MUST use
- * different Network instances to avoid sharing the same IkeSocket and hitting IKE SPI collision.
- */
-@RunWith(AndroidJUnit4.class)
-@AppModeFull(reason = "MANAGE_TEST_NETWORKS permission can't be granted to instant apps")
-abstract class IkeSessionTestBase extends IkeTestBase {
-    // Package-wide common expected results that will be shared by all IKE/Child SA creation tests
-    static final String EXPECTED_REMOTE_APP_VERSION_EMPTY = "";
-    static final byte[] EXPECTED_PROTOCOL_ERROR_DATA_NONE = new byte[0];
-
-    static final InetAddress EXPECTED_DNS_SERVERS_ONE =
-            InetAddresses.parseNumericAddress("8.8.8.8");
-    static final InetAddress EXPECTED_DNS_SERVERS_TWO =
-            InetAddresses.parseNumericAddress("8.8.4.4");
-
-    static final InetAddress EXPECTED_INTERNAL_ADDR =
-            InetAddresses.parseNumericAddress("198.51.100.10");
-    static final LinkAddress EXPECTED_INTERNAL_LINK_ADDR =
-            new LinkAddress(EXPECTED_INTERNAL_ADDR, IP4_PREFIX_LEN);
-    static final InetAddress EXPECTED_INTERNAL_ADDR_V6 =
-            InetAddresses.parseNumericAddress("2001:db8::2");
-    static final LinkAddress EXPECTED_INTERNAL_LINK_ADDR_V6 =
-            new LinkAddress(EXPECTED_INTERNAL_ADDR_V6, IP6_PREFIX_LEN);
-
-    static final IkeTrafficSelector TUNNEL_MODE_INBOUND_TS =
-            new IkeTrafficSelector(
-                    MIN_PORT, MAX_PORT, EXPECTED_INTERNAL_ADDR, EXPECTED_INTERNAL_ADDR);
-    static final IkeTrafficSelector TUNNEL_MODE_OUTBOUND_TS = DEFAULT_V4_TS;
-    static final IkeTrafficSelector TUNNEL_MODE_INBOUND_TS_V6 =
-            new IkeTrafficSelector(
-                    MIN_PORT, MAX_PORT, EXPECTED_INTERNAL_ADDR_V6, EXPECTED_INTERNAL_ADDR_V6);
-    static final IkeTrafficSelector TUNNEL_MODE_OUTBOUND_TS_V6 = DEFAULT_V6_TS;
-
-    // This value is align with the test vectors hex that are generated in an IPv4 environment
-    static final IkeTrafficSelector TRANSPORT_MODE_OUTBOUND_TS =
-            new IkeTrafficSelector(
-                    MIN_PORT,
-                    MAX_PORT,
-                    InetAddresses.parseNumericAddress("10.138.0.2"),
-                    InetAddresses.parseNumericAddress("10.138.0.2"));
-
-    static final long IKE_DETERMINISTIC_INITIATOR_SPI = Long.parseLong("46B8ECA1E0D72A18", 16);
-
-    // Static state to reduce setup/teardown
-    static Context sContext = InstrumentationRegistry.getContext();
-    static ConnectivityManager sCM =
-            (ConnectivityManager) sContext.getSystemService(Context.CONNECTIVITY_SERVICE);
-    static TestNetworkManager sTNM;
-
-    private static final int TIMEOUT_MS = 500;
-
-    // Constants to be used for providing different IP addresses for each tests
-    private static final byte IP_ADDR_LAST_BYTE_MAX = (byte) 100;
-    private static final byte[] INITIAL_AVAILABLE_IP4_ADDR_LOCAL =
-            InetAddresses.parseNumericAddress("192.0.2.1").getAddress();
-    private static final byte[] INITIAL_AVAILABLE_IP4_ADDR_REMOTE =
-            InetAddresses.parseNumericAddress("198.51.100.1").getAddress();
-    private static final byte[] NEXT_AVAILABLE_IP4_ADDR_LOCAL = INITIAL_AVAILABLE_IP4_ADDR_LOCAL;
-    private static final byte[] NEXT_AVAILABLE_IP4_ADDR_REMOTE = INITIAL_AVAILABLE_IP4_ADDR_REMOTE;
-
-    ParcelFileDescriptor mTunFd;
-    TestNetworkCallback mTunNetworkCallback;
-    Network mTunNetwork;
-    IkeTunUtils mTunUtils;
-
-    InetAddress mLocalAddress;
-    InetAddress mRemoteAddress;
-
-    Executor mUserCbExecutor;
-    TestIkeSessionCallback mIkeSessionCallback;
-    TestChildSessionCallback mFirstChildSessionCallback;
-
-    // This method is guaranteed to run in subclasses and will run before subclasses' @BeforeClass
-    // methods.
-    @BeforeClass
-    public static void setUpPermissionBeforeClass() throws Exception {
-        InstrumentationRegistry.getInstrumentation()
-                .getUiAutomation()
-                .adoptShellPermissionIdentity();
-        sTNM = sContext.getSystemService(TestNetworkManager.class);
-    }
-
-    // This method is guaranteed to run in subclasses and will run after subclasses' @AfterClass
-    // methods.
-    @AfterClass
-    public static void tearDownPermissionAfterClass() throws Exception {
-        InstrumentationRegistry.getInstrumentation()
-                .getUiAutomation()
-                .dropShellPermissionIdentity();
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        mLocalAddress = getNextAvailableIpv4AddressLocal();
-        mRemoteAddress = getNextAvailableIpv4AddressRemote();
-        setUpTestNetwork(mLocalAddress);
-
-        mUserCbExecutor = Executors.newSingleThreadExecutor();
-        mIkeSessionCallback = new TestIkeSessionCallback();
-        mFirstChildSessionCallback = new TestChildSessionCallback();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        tearDownTestNetwork();
-    }
-
-    void setUpTestNetwork(InetAddress localAddr) throws Exception {
-        int prefixLen = localAddr instanceof Inet4Address ? IP4_PREFIX_LEN : IP6_PREFIX_LEN;
-
-        TestNetworkInterface testIface =
-                sTNM.createTunInterface(new LinkAddress[] {new LinkAddress(localAddr, prefixLen)});
-
-        mTunFd = testIface.getFileDescriptor();
-        mTunNetworkCallback =
-                TestNetworkUtils.setupAndGetTestNetwork(
-                        sCM, sTNM, testIface.getInterfaceName(), new Binder());
-        mTunNetwork = mTunNetworkCallback.getNetworkBlocking();
-        mTunUtils = new IkeTunUtils(mTunFd);
-    }
-
-    void tearDownTestNetwork() throws Exception {
-        sCM.unregisterNetworkCallback(mTunNetworkCallback);
-
-        sTNM.teardownTestNetwork(mTunNetwork);
-        mTunFd.close();
-    }
-
-    static void setAppOp(int appop, boolean allow) {
-        String opName = AppOpsManager.opToName(appop);
-        for (String pkg : new String[] {"com.android.shell", sContext.getPackageName()}) {
-            String cmd =
-                    String.format(
-                            "appops set %s %s %s",
-                            pkg, // Package name
-                            opName, // Appop
-                            (allow ? "allow" : "deny")); // Action
-
-            SystemUtil.runShellCommand(cmd);
-        }
-    }
-
-    Inet4Address getNextAvailableIpv4AddressLocal() throws Exception {
-        return (Inet4Address)
-                getNextAvailableAddress(
-                        NEXT_AVAILABLE_IP4_ADDR_LOCAL,
-                        INITIAL_AVAILABLE_IP4_ADDR_LOCAL,
-                        false /* isIp6 */);
-    }
-
-    Inet4Address getNextAvailableIpv4AddressRemote() throws Exception {
-        return (Inet4Address)
-                getNextAvailableAddress(
-                        NEXT_AVAILABLE_IP4_ADDR_REMOTE,
-                        INITIAL_AVAILABLE_IP4_ADDR_REMOTE,
-                        false /* isIp6 */);
-    }
-
-    InetAddress getNextAvailableAddress(
-            byte[] nextAddressBytes, byte[] initialAddressBytes, boolean isIp6) throws Exception {
-        int addressLen = isIp6 ? IP6_ADDRESS_LEN : IP4_ADDRESS_LEN;
-
-        synchronized (nextAddressBytes) {
-            if (nextAddressBytes[addressLen - 1] == IP_ADDR_LAST_BYTE_MAX) {
-                resetNextAvailableAddress(nextAddressBytes, initialAddressBytes);
-            }
-
-            InetAddress address = InetAddress.getByAddress(nextAddressBytes);
-            nextAddressBytes[addressLen - 1]++;
-            return address;
-        }
-    }
-
-    private void resetNextAvailableAddress(byte[] nextAddressBytes, byte[] initialAddressBytes) {
-        synchronized (nextAddressBytes) {
-            System.arraycopy(
-                    nextAddressBytes, 0, initialAddressBytes, 0, initialAddressBytes.length);
-        }
-    }
-
-    TransportModeChildSessionParams buildTransportModeChildParamsWithTs(
-            IkeTrafficSelector inboundTs, IkeTrafficSelector outboundTs) {
-        return new TransportModeChildSessionParams.Builder()
-                .addSaProposal(SaProposalTest.buildChildSaProposalWithCombinedModeCipher())
-                .addSaProposal(SaProposalTest.buildChildSaProposalWithNormalModeCipher())
-                .addInboundTrafficSelectors(inboundTs)
-                .addOutboundTrafficSelectors(outboundTs)
-                .build();
-    }
-
-    TransportModeChildSessionParams buildTransportModeChildParamsWithDefaultTs() {
-        return new TransportModeChildSessionParams.Builder()
-                .addSaProposal(SaProposalTest.buildChildSaProposalWithCombinedModeCipher())
-                .addSaProposal(SaProposalTest.buildChildSaProposalWithNormalModeCipher())
-                .build();
-    }
-
-    TunnelModeChildSessionParams buildTunnelModeChildSessionParams() {
-        return new TunnelModeChildSessionParams.Builder()
-                .addSaProposal(SaProposalTest.buildChildSaProposalWithNormalModeCipher())
-                .addSaProposal(SaProposalTest.buildChildSaProposalWithCombinedModeCipher())
-                .addInternalAddressRequest(AF_INET)
-                .addInternalAddressRequest(AF_INET6)
-                .build();
-    }
-
-    PortPair performSetupIkeAndFirstChildBlocking(String ikeInitRespHex, String... ikeAuthRespHexes)
-            throws Exception {
-        return performSetupIkeAndFirstChildBlocking(
-                ikeInitRespHex,
-                1 /* expectedAuthReqPktCnt */,
-                true /*expectedAuthUseEncap*/,
-                ikeAuthRespHexes);
-    }
-
-    PortPair performSetupIkeAndFirstChildBlocking(
-            String ikeInitRespHex, boolean expectedAuthUseEncap, String... ikeAuthRespHexes)
-            throws Exception {
-        return performSetupIkeAndFirstChildBlocking(
-                ikeInitRespHex,
-                1 /* expectedAuthReqPktCnt */,
-                expectedAuthUseEncap,
-                ikeAuthRespHexes);
-    }
-
-    PortPair performSetupIkeAndFirstChildBlocking(
-            String ikeInitRespHex,
-            int expectedAuthReqPktCnt,
-            boolean expectedAuthUseEncap,
-            String... ikeAuthRespHexes)
-            throws Exception {
-        mTunUtils.awaitReqAndInjectResp(
-                IKE_DETERMINISTIC_INITIATOR_SPI,
-                0 /* expectedMsgId */,
-                false /* expectedUseEncap */,
-                ikeInitRespHex);
-
-        byte[] ikeAuthReqPkt =
-                mTunUtils
-                        .awaitReqAndInjectResp(
-                                IKE_DETERMINISTIC_INITIATOR_SPI,
-                                1 /* expectedMsgId */,
-                                expectedAuthUseEncap,
-                                expectedAuthReqPktCnt,
-                                ikeAuthRespHexes)
-                        .get(0);
-        return IkeTunUtils.getSrcDestPortPair(ikeAuthReqPkt);
-    }
-
-    void performCloseIkeBlocking(int expectedMsgId, String deleteIkeRespHex) throws Exception {
-        performCloseIkeBlocking(expectedMsgId, true /* expectedUseEncap*/, deleteIkeRespHex);
-    }
-
-    void performCloseIkeBlocking(
-            int expectedMsgId, boolean expectedUseEncap, String deleteIkeRespHex) throws Exception {
-        mTunUtils.awaitReqAndInjectResp(
-                IKE_DETERMINISTIC_INITIATOR_SPI, expectedMsgId, expectedUseEncap, deleteIkeRespHex);
-    }
-
-    /** Testing callback that allows caller to block current thread until a method get called */
-    static class TestIkeSessionCallback implements IkeSessionCallback {
-        private CompletableFuture<IkeSessionConfiguration> mFutureIkeConfig =
-                new CompletableFuture<>();
-        private CompletableFuture<Boolean> mFutureOnClosedCall = new CompletableFuture<>();
-        private CompletableFuture<IkeException> mFutureOnClosedException =
-                new CompletableFuture<>();
-
-        private int mOnErrorExceptionsCount = 0;
-        private ArrayTrackRecord<IkeProtocolException> mOnErrorExceptionsTrackRecord =
-                new ArrayTrackRecord<>();
-
-        @Override
-        public void onOpened(@NonNull IkeSessionConfiguration sessionConfiguration) {
-            mFutureIkeConfig.complete(sessionConfiguration);
-        }
-
-        @Override
-        public void onClosed() {
-            mFutureOnClosedCall.complete(true /* unused */);
-        }
-
-        @Override
-        public void onClosedExceptionally(@NonNull IkeException exception) {
-            mFutureOnClosedException.complete(exception);
-        }
-
-        @Override
-        public void onError(@NonNull IkeProtocolException exception) {
-            mOnErrorExceptionsTrackRecord.add(exception);
-        }
-
-        public IkeSessionConfiguration awaitIkeConfig() throws Exception {
-            return mFutureIkeConfig.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
-        }
-
-        public IkeException awaitOnClosedException() throws Exception {
-            return mFutureOnClosedException.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
-        }
-
-        public IkeProtocolException awaitNextOnErrorException() {
-            return mOnErrorExceptionsTrackRecord.poll(
-                    (long) TIMEOUT_MS,
-                    mOnErrorExceptionsCount++,
-                    (transform) -> {
-                        return true;
-                    });
-        }
-
-        public void awaitOnClosed() throws Exception {
-            mFutureOnClosedCall.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
-        }
-    }
-
-    /** Testing callback that allows caller to block current thread until a method get called */
-    static class TestChildSessionCallback implements ChildSessionCallback {
-        private CompletableFuture<ChildSessionConfiguration> mFutureChildConfig =
-                new CompletableFuture<>();
-        private CompletableFuture<Boolean> mFutureOnClosedCall = new CompletableFuture<>();
-        private CompletableFuture<IkeException> mFutureOnClosedException =
-                new CompletableFuture<>();
-
-        private int mCreatedIpSecTransformCount = 0;
-        private int mDeletedIpSecTransformCount = 0;
-        private ArrayTrackRecord<IpSecTransformCallRecord> mCreatedIpSecTransformsTrackRecord =
-                new ArrayTrackRecord<>();
-        private ArrayTrackRecord<IpSecTransformCallRecord> mDeletedIpSecTransformsTrackRecord =
-                new ArrayTrackRecord<>();
-
-        @Override
-        public void onOpened(@NonNull ChildSessionConfiguration sessionConfiguration) {
-            mFutureChildConfig.complete(sessionConfiguration);
-        }
-
-        @Override
-        public void onClosed() {
-            mFutureOnClosedCall.complete(true /* unused */);
-        }
-
-        @Override
-        public void onClosedExceptionally(@NonNull IkeException exception) {
-            mFutureOnClosedException.complete(exception);
-        }
-
-        @Override
-        public void onIpSecTransformCreated(@NonNull IpSecTransform ipSecTransform, int direction) {
-            mCreatedIpSecTransformsTrackRecord.add(
-                    new IpSecTransformCallRecord(ipSecTransform, direction));
-        }
-
-        @Override
-        public void onIpSecTransformDeleted(@NonNull IpSecTransform ipSecTransform, int direction) {
-            mDeletedIpSecTransformsTrackRecord.add(
-                    new IpSecTransformCallRecord(ipSecTransform, direction));
-        }
-
-        public ChildSessionConfiguration awaitChildConfig() throws Exception {
-            return mFutureChildConfig.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
-        }
-
-        public IkeException awaitOnClosedException() throws Exception {
-            return mFutureOnClosedException.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
-        }
-
-        public IpSecTransformCallRecord awaitNextCreatedIpSecTransform() {
-            return mCreatedIpSecTransformsTrackRecord.poll(
-                    (long) TIMEOUT_MS,
-                    mCreatedIpSecTransformCount++,
-                    (transform) -> {
-                        return true;
-                    });
-        }
-
-        public IpSecTransformCallRecord awaitNextDeletedIpSecTransform() {
-            return mDeletedIpSecTransformsTrackRecord.poll(
-                    (long) TIMEOUT_MS,
-                    mDeletedIpSecTransformCount++,
-                    (transform) -> {
-                        return true;
-                    });
-        }
-
-        public void awaitOnClosed() throws Exception {
-            mFutureOnClosedCall.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
-        }
-    }
-
-    /**
-     * This class represents a created or deleted IpSecTransfrom that is provided by
-     * ChildSessionCallback
-     */
-    static class IpSecTransformCallRecord {
-        public final IpSecTransform ipSecTransform;
-        public final int direction;
-
-        IpSecTransformCallRecord(IpSecTransform ipSecTransform, @PolicyDirection int direction) {
-            this.ipSecTransform = ipSecTransform;
-            this.direction = direction;
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(ipSecTransform, direction);
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (!(o instanceof IpSecTransformCallRecord)) return false;
-
-            IpSecTransformCallRecord record = (IpSecTransformCallRecord) o;
-            return ipSecTransform.equals(record.ipSecTransform) && direction == record.direction;
-        }
-    }
-
-    void verifyIkeSessionSetupBlocking() throws Exception {
-        IkeSessionConfiguration ikeConfig = mIkeSessionCallback.awaitIkeConfig();
-        assertNotNull(ikeConfig);
-        assertEquals(EXPECTED_REMOTE_APP_VERSION_EMPTY, ikeConfig.getRemoteApplicationVersion());
-        assertTrue(ikeConfig.getRemoteVendorIds().isEmpty());
-        assertTrue(ikeConfig.getPcscfServers().isEmpty());
-        assertTrue(ikeConfig.isIkeExtensionEnabled(EXTENSION_TYPE_FRAGMENTATION));
-
-        IkeSessionConnectionInfo ikeConnectInfo = ikeConfig.getIkeSessionConnectionInfo();
-        assertNotNull(ikeConnectInfo);
-        assertEquals(mLocalAddress, ikeConnectInfo.getLocalAddress());
-        assertEquals(mRemoteAddress, ikeConnectInfo.getRemoteAddress());
-        assertEquals(mTunNetwork, ikeConnectInfo.getNetwork());
-    }
-
-    void verifyChildSessionSetupBlocking(
-            TestChildSessionCallback childCallback,
-            List<IkeTrafficSelector> expectedInboundTs,
-            List<IkeTrafficSelector> expectedOutboundTs,
-            List<LinkAddress> expectedInternalAddresses)
-            throws Exception {
-        verifyChildSessionSetupBlocking(
-                childCallback,
-                expectedInboundTs,
-                expectedOutboundTs,
-                expectedInternalAddresses,
-                new ArrayList<InetAddress>() /* expectedDnsServers */);
-    }
-
-    void verifyChildSessionSetupBlocking(
-            TestChildSessionCallback childCallback,
-            List<IkeTrafficSelector> expectedInboundTs,
-            List<IkeTrafficSelector> expectedOutboundTs,
-            List<LinkAddress> expectedInternalAddresses,
-            List<InetAddress> expectedDnsServers)
-            throws Exception {
-        ChildSessionConfiguration childConfig = childCallback.awaitChildConfig();
-        assertNotNull(childConfig);
-        assertEquals(expectedInboundTs, childConfig.getInboundTrafficSelectors());
-        assertEquals(expectedOutboundTs, childConfig.getOutboundTrafficSelectors());
-        assertEquals(expectedInternalAddresses, childConfig.getInternalAddresses());
-        assertEquals(expectedDnsServers, childConfig.getInternalDnsServers());
-        assertTrue(childConfig.getInternalSubnets().isEmpty());
-        assertTrue(childConfig.getInternalDhcpServers().isEmpty());
-    }
-
-    void verifyCloseIkeAndChildBlocking(
-            IpSecTransformCallRecord expectedTransformRecordA,
-            IpSecTransformCallRecord expectedTransformRecordB)
-            throws Exception {
-        verifyDeleteIpSecTransformPair(
-                mFirstChildSessionCallback, expectedTransformRecordA, expectedTransformRecordB);
-        mFirstChildSessionCallback.awaitOnClosed();
-        mIkeSessionCallback.awaitOnClosed();
-    }
-
-    static void verifyCreateIpSecTransformPair(
-            IpSecTransformCallRecord transformRecordA, IpSecTransformCallRecord transformRecordB) {
-        IpSecTransform transformA = transformRecordA.ipSecTransform;
-        IpSecTransform transformB = transformRecordB.ipSecTransform;
-
-        assertNotNull(transformA);
-        assertNotNull(transformB);
-
-        Set<Integer> expectedDirections = new HashSet<>();
-        expectedDirections.add(IpSecManager.DIRECTION_IN);
-        expectedDirections.add(IpSecManager.DIRECTION_OUT);
-
-        Set<Integer> resultDirections = new HashSet<>();
-        resultDirections.add(transformRecordA.direction);
-        resultDirections.add(transformRecordB.direction);
-
-        assertEquals(expectedDirections, resultDirections);
-    }
-
-    static void verifyDeleteIpSecTransformPair(
-            TestChildSessionCallback childCb,
-            IpSecTransformCallRecord expectedTransformRecordA,
-            IpSecTransformCallRecord expectedTransformRecordB) {
-        Set<IpSecTransformCallRecord> expectedTransforms = new HashSet<>();
-        expectedTransforms.add(expectedTransformRecordA);
-        expectedTransforms.add(expectedTransformRecordB);
-
-        Set<IpSecTransformCallRecord> resultTransforms = new HashSet<>();
-        resultTransforms.add(childCb.awaitNextDeletedIpSecTransform());
-        resultTransforms.add(childCb.awaitNextDeletedIpSecTransform());
-
-        assertEquals(expectedTransforms, resultTransforms);
-    }
-
-    /** Package private method to check if device has IPsec tunnels feature */
-    static boolean hasTunnelsFeature() {
-        return sContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS);
-    }
-
-    // TODO(b/148689509): Verify hostname based creation
-}
diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java
deleted file mode 100644
index c70e537..0000000
--- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * 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 android.net.ipsec.ike.cts;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import android.net.InetAddresses;
-import android.net.ipsec.ike.IkeTrafficSelector;
-
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/** Shared parameters and util methods for testing different components of IKE */
-abstract class IkeTestBase {
-    static final int MIN_PORT = 0;
-    static final int MAX_PORT = 65535;
-    private static final int INBOUND_TS_START_PORT = MIN_PORT;
-    private static final int INBOUND_TS_END_PORT = 65520;
-    private static final int OUTBOUND_TS_START_PORT = 16;
-    private static final int OUTBOUND_TS_END_PORT = MAX_PORT;
-
-    static final int IP4_ADDRESS_LEN = 4;
-    static final int IP6_ADDRESS_LEN = 16;
-    static final int IP4_PREFIX_LEN = 32;
-    static final int IP6_PREFIX_LEN = 64;
-
-    static final byte[] IKE_PSK = "ikeAndroidPsk".getBytes();
-
-    static final String LOCAL_HOSTNAME = "client.test.ike.android.net";
-    static final String REMOTE_HOSTNAME = "server.test.ike.android.net";
-    static final String LOCAL_ASN1_DN_STRING = "CN=client.test.ike.android.net, O=Android, C=US";
-    static final String LOCAL_RFC822_NAME = "client.test.ike@example.com";
-    static final byte[] LOCAL_KEY_ID = "Local Key ID".getBytes();
-
-    static final int SUB_ID = 1;
-    static final byte[] EAP_IDENTITY = "test@android.net".getBytes();
-    static final String NETWORK_NAME = "android.net";
-    static final String EAP_MSCHAPV2_USERNAME = "mschapv2user";
-    static final String EAP_MSCHAPV2_PASSWORD = "password";
-
-    static final Inet4Address IPV4_ADDRESS_LOCAL =
-            (Inet4Address) (InetAddresses.parseNumericAddress("192.0.2.100"));
-    static final Inet4Address IPV4_ADDRESS_REMOTE =
-            (Inet4Address) (InetAddresses.parseNumericAddress("198.51.100.100"));
-    static final Inet6Address IPV6_ADDRESS_LOCAL =
-            (Inet6Address) (InetAddresses.parseNumericAddress("2001:db8::100"));
-    static final Inet6Address IPV6_ADDRESS_REMOTE =
-            (Inet6Address) (InetAddresses.parseNumericAddress("2001:db8:255::100"));
-
-    static final InetAddress PCSCF_IPV4_ADDRESS_1 = InetAddresses.parseNumericAddress("192.0.2.1");
-    static final InetAddress PCSCF_IPV4_ADDRESS_2 = InetAddresses.parseNumericAddress("192.0.2.2");
-    static final InetAddress PCSCF_IPV6_ADDRESS_1 =
-            InetAddresses.parseNumericAddress("2001:DB8::1");
-    static final InetAddress PCSCF_IPV6_ADDRESS_2 =
-            InetAddresses.parseNumericAddress("2001:DB8::2");
-
-    static final IkeTrafficSelector DEFAULT_V4_TS =
-            new IkeTrafficSelector(
-                    MIN_PORT,
-                    MAX_PORT,
-                    InetAddresses.parseNumericAddress("0.0.0.0"),
-                    InetAddresses.parseNumericAddress("255.255.255.255"));
-    static final IkeTrafficSelector DEFAULT_V6_TS =
-            new IkeTrafficSelector(
-                    MIN_PORT,
-                    MAX_PORT,
-                    InetAddresses.parseNumericAddress("::"),
-                    InetAddresses.parseNumericAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
-    static final IkeTrafficSelector INBOUND_V4_TS =
-            new IkeTrafficSelector(
-                    INBOUND_TS_START_PORT,
-                    INBOUND_TS_END_PORT,
-                    InetAddresses.parseNumericAddress("192.0.2.10"),
-                    InetAddresses.parseNumericAddress("192.0.2.20"));
-    static final IkeTrafficSelector OUTBOUND_V4_TS =
-            new IkeTrafficSelector(
-                    OUTBOUND_TS_START_PORT,
-                    OUTBOUND_TS_END_PORT,
-                    InetAddresses.parseNumericAddress("198.51.100.0"),
-                    InetAddresses.parseNumericAddress("198.51.100.255"));
-
-    static final IkeTrafficSelector INBOUND_V6_TS =
-            new IkeTrafficSelector(
-                    INBOUND_TS_START_PORT,
-                    INBOUND_TS_END_PORT,
-                    InetAddresses.parseNumericAddress("2001:db8::10"),
-                    InetAddresses.parseNumericAddress("2001:db8::128"));
-    static final IkeTrafficSelector OUTBOUND_V6_TS =
-            new IkeTrafficSelector(
-                    OUTBOUND_TS_START_PORT,
-                    OUTBOUND_TS_END_PORT,
-                    InetAddresses.parseNumericAddress("2001:db8:255::64"),
-                    InetAddresses.parseNumericAddress("2001:db8:255::255"));
-
-    // Verify Config requests in TunnelModeChildSessionParams and IkeSessionParams
-    <T> void verifyConfigRequestTypes(
-            Map<Class<? extends T>, Integer> expectedReqCntMap, List<? extends T> resultReqList) {
-        Map<Class<? extends T>, Integer> resultReqCntMap = new HashMap<>();
-
-        // Verify that every config request type in resultReqList is expected, and build
-        // resultReqCntMap at the same time
-        for (T resultReq : resultReqList) {
-            boolean isResultReqExpected = false;
-
-            for (Class<? extends T> expectedReqInterface : expectedReqCntMap.keySet()) {
-                if (expectedReqInterface.isInstance(resultReq)) {
-                    isResultReqExpected = true;
-
-                    resultReqCntMap.put(
-                            expectedReqInterface,
-                            resultReqCntMap.getOrDefault(expectedReqInterface, 0) + 1);
-                }
-            }
-
-            if (!isResultReqExpected) {
-                fail("Failed due to unexpected config request " + resultReq);
-            }
-        }
-
-        assertEquals(expectedReqCntMap, resultReqCntMap);
-
-        // TODO: Think of a neat way to validate both counts and values in this method. Probably can
-        // build Runnables as validators for count and values.
-    }
-}
diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTunUtils.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTunUtils.java
deleted file mode 100644
index 41cbf0b..0000000
--- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTunUtils.java
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * 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 android.net.ipsec.ike.cts;
-
-import static android.net.ipsec.ike.cts.PacketUtils.BytePayload;
-import static android.net.ipsec.ike.cts.PacketUtils.IP4_HDRLEN;
-import static android.net.ipsec.ike.cts.PacketUtils.IP6_HDRLEN;
-import static android.net.ipsec.ike.cts.PacketUtils.Ip4Header;
-import static android.net.ipsec.ike.cts.PacketUtils.Ip6Header;
-import static android.net.ipsec.ike.cts.PacketUtils.IpHeader;
-import static android.net.ipsec.ike.cts.PacketUtils.Payload;
-import static android.net.ipsec.ike.cts.PacketUtils.UDP_HDRLEN;
-import static android.net.ipsec.ike.cts.PacketUtils.UdpHeader;
-import static android.system.OsConstants.IPPROTO_UDP;
-
-import static com.android.internal.util.HexDump.hexStringToByteArray;
-
-import static org.junit.Assert.fail;
-
-import android.os.ParcelFileDescriptor;
-
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.function.Predicate;
-
-public class IkeTunUtils extends TunUtils {
-    private static final int PORT_LEN = 2;
-
-    private static final int NON_ESP_MARKER_LEN = 4;
-    private static final byte[] NON_ESP_MARKER = new byte[NON_ESP_MARKER_LEN];
-
-    private static final int IKE_INIT_SPI_OFFSET = 0;
-    private static final int IKE_FIRST_PAYLOAD_OFFSET = 16;
-    private static final int IKE_IS_RESP_BYTE_OFFSET = 19;
-    private static final int IKE_MSG_ID_OFFSET = 20;
-    private static final int IKE_HEADER_LEN = 28;
-    private static final int IKE_FRAG_NUM_OFFSET = 32;
-    private static final int IKE_PAYLOAD_TYPE_SKF = 53;
-
-    private static final int RSP_FLAG_MASK = 0x20;
-
-    public IkeTunUtils(ParcelFileDescriptor tunFd) {
-        super(tunFd);
-    }
-
-    /**
-     * Await the expected IKE request inject an IKE response (or a list of response fragments)
-     *
-     * @param ikeRespDataFragmentsHex IKE response hex (or a list of response fragments) without
-     *     IP/UDP headers or NON ESP MARKER.
-     */
-    public byte[] awaitReqAndInjectResp(
-            long expectedInitIkeSpi,
-            int expectedMsgId,
-            boolean expectedUseEncap,
-            String... ikeRespDataFragmentsHex)
-            throws Exception {
-        return awaitReqAndInjectResp(
-                        expectedInitIkeSpi,
-                        expectedMsgId,
-                        expectedUseEncap,
-                        1 /* expectedReqPktCnt */,
-                        ikeRespDataFragmentsHex)
-                .get(0);
-    }
-
-    /**
-     * Await the expected IKE request (or the list of IKE request fragments) and inject an IKE
-     * response (or a list of response fragments)
-     *
-     * @param ikeRespDataFragmentsHex IKE response hex (or a list of response fragments) without
-     *     IP/UDP headers or NON ESP MARKER.
-     */
-    public List<byte[]> awaitReqAndInjectResp(
-            long expectedInitIkeSpi,
-            int expectedMsgId,
-            boolean expectedUseEncap,
-            int expectedReqPktCnt,
-            String... ikeRespDataFragmentsHex)
-            throws Exception {
-        List<byte[]> reqList = new ArrayList<>(expectedReqPktCnt);
-        if (expectedReqPktCnt == 1) {
-            // Expecting one complete IKE packet
-            byte[] req =
-                    awaitIkePacket(
-                            (pkt) -> {
-                                return isExpectedIkePkt(
-                                        pkt,
-                                        expectedInitIkeSpi,
-                                        expectedMsgId,
-                                        false /* expectedResp */,
-                                        expectedUseEncap);
-                            });
-            reqList.add(req);
-        } else {
-            // Expecting "expectedReqPktCnt" number of request fragments
-            for (int i = 0; i < expectedReqPktCnt; i++) {
-                // IKE Fragment number always starts from 1
-                int expectedFragNum = i + 1;
-                byte[] req =
-                        awaitIkePacket(
-                                (pkt) -> {
-                                    return isExpectedIkeFragPkt(
-                                            pkt,
-                                            expectedInitIkeSpi,
-                                            expectedMsgId,
-                                            false /* expectedResp */,
-                                            expectedUseEncap,
-                                            expectedFragNum);
-                                });
-                reqList.add(req);
-            }
-        }
-
-        // All request fragments have the same addresses and ports
-        byte[] request = reqList.get(0);
-
-        // Build response header by flipping address and port
-        InetAddress srcAddr = getAddress(request, false /* shouldGetSource */);
-        InetAddress dstAddr = getAddress(request, true /* shouldGetSource */);
-        int srcPort = getPort(request, false /* shouldGetSource */);
-        int dstPort = getPort(request, true /* shouldGetSource */);
-        for (String resp : ikeRespDataFragmentsHex) {
-            byte[] response =
-                    buildIkePacket(
-                            srcAddr,
-                            dstAddr,
-                            srcPort,
-                            dstPort,
-                            expectedUseEncap,
-                            hexStringToByteArray(resp));
-            injectPacket(response);
-        }
-
-        return reqList;
-    }
-
-    /** Await the expected IKE response */
-    public byte[] awaitResp(long expectedInitIkeSpi, int expectedMsgId, boolean expectedUseEncap)
-            throws Exception {
-        return awaitIkePacket(
-                (pkt) -> {
-                    return isExpectedIkePkt(
-                            pkt,
-                            expectedInitIkeSpi,
-                            expectedMsgId,
-                            true /* expectedResp*/,
-                            expectedUseEncap);
-                });
-    }
-
-    private byte[] awaitIkePacket(Predicate<byte[]> pktVerifier) throws Exception {
-        long endTime = System.currentTimeMillis() + TIMEOUT;
-        int startIndex = 0;
-        synchronized (mPackets) {
-            while (System.currentTimeMillis() < endTime) {
-                byte[] ikePkt = getFirstMatchingPacket(pktVerifier, startIndex);
-                if (ikePkt != null) {
-                    return ikePkt; // We've found the packet we're looking for.
-                }
-
-                startIndex = mPackets.size();
-
-                // Try to prevent waiting too long. If waitTimeout <= 0, we've already hit timeout
-                long waitTimeout = endTime - System.currentTimeMillis();
-                if (waitTimeout > 0) {
-                    mPackets.wait(waitTimeout);
-                }
-            }
-
-            fail("No matching packet found");
-        }
-
-        throw new IllegalStateException(
-                "Hit an impossible case where fail() didn't throw an exception");
-    }
-
-    private static boolean isExpectedIkePkt(
-            byte[] pkt,
-            long expectedInitIkeSpi,
-            int expectedMsgId,
-            boolean expectedResp,
-            boolean expectedUseEncap) {
-        int ipProtocolOffset = isIpv6(pkt) ? IP6_PROTO_OFFSET : IP4_PROTO_OFFSET;
-        int ikeOffset = getIkeOffset(pkt, expectedUseEncap);
-
-        return pkt[ipProtocolOffset] == IPPROTO_UDP
-                && expectedUseEncap == hasNonEspMarker(pkt)
-                && isExpectedSpiAndMsgId(
-                        pkt, ikeOffset, expectedInitIkeSpi, expectedMsgId, expectedResp);
-    }
-
-    private static boolean isExpectedIkeFragPkt(
-            byte[] pkt,
-            long expectedInitIkeSpi,
-            int expectedMsgId,
-            boolean expectedResp,
-            boolean expectedUseEncap,
-            int expectedFragNum) {
-        return isExpectedIkePkt(
-                        pkt, expectedInitIkeSpi, expectedMsgId, expectedResp, expectedUseEncap)
-                && isExpectedFragNum(pkt, getIkeOffset(pkt, expectedUseEncap), expectedFragNum);
-    }
-
-    private static int getIkeOffset(byte[] pkt, boolean useEncap) {
-        if (isIpv6(pkt)) {
-            // IPv6 UDP expectedUseEncap not supported by kernels; assume non-expectedUseEncap.
-            return IP6_HDRLEN + UDP_HDRLEN;
-        } else {
-            // Use default IPv4 header length (assuming no options)
-            int ikeOffset = IP4_HDRLEN + UDP_HDRLEN;
-            return useEncap ? ikeOffset + NON_ESP_MARKER_LEN : ikeOffset;
-        }
-    }
-
-    private static boolean hasNonEspMarker(byte[] pkt) {
-        ByteBuffer buffer = ByteBuffer.wrap(pkt);
-        int ikeOffset = IP4_HDRLEN + UDP_HDRLEN;
-        if (buffer.remaining() < ikeOffset) return false;
-
-        buffer.get(new byte[ikeOffset]); // Skip IP and UDP header
-        byte[] nonEspMarker = new byte[NON_ESP_MARKER_LEN];
-        if (buffer.remaining() < NON_ESP_MARKER_LEN) return false;
-
-        buffer.get(nonEspMarker);
-        return Arrays.equals(NON_ESP_MARKER, nonEspMarker);
-    }
-
-    private static boolean isExpectedSpiAndMsgId(
-            byte[] pkt,
-            int ikeOffset,
-            long expectedInitIkeSpi,
-            int expectedMsgId,
-            boolean expectedResp) {
-        if (pkt.length <= ikeOffset + IKE_HEADER_LEN) return false;
-
-        ByteBuffer buffer = ByteBuffer.wrap(pkt);
-        buffer.get(new byte[ikeOffset]); // Skip IP, UDP header (and NON_ESP_MARKER)
-        buffer.mark(); // Mark this position so that later we can reset back here
-
-        // Check SPI
-        buffer.get(new byte[IKE_INIT_SPI_OFFSET]);
-        long initSpi = buffer.getLong();
-        if (expectedInitIkeSpi != initSpi) {
-            return false;
-        }
-
-        // Check direction
-        buffer.reset();
-        buffer.get(new byte[IKE_IS_RESP_BYTE_OFFSET]);
-        byte flagsByte = buffer.get();
-        boolean isResp = ((flagsByte & RSP_FLAG_MASK) != 0);
-        if (expectedResp != isResp) {
-            return false;
-        }
-
-        // Check message ID
-        buffer.reset();
-        buffer.get(new byte[IKE_MSG_ID_OFFSET]);
-
-        // Both the expected message ID and the packet's msgId are signed integers, so directly
-        // compare them.
-        int msgId = buffer.getInt();
-        if (expectedMsgId != msgId) {
-            return false;
-        }
-
-        return true;
-    }
-
-    private static boolean isExpectedFragNum(byte[] pkt, int ikeOffset, int expectedFragNum) {
-        ByteBuffer buffer = ByteBuffer.wrap(pkt);
-        buffer.get(new byte[ikeOffset]);
-        buffer.mark(); // Mark this position so that later we can reset back here
-
-        // Check if it is a fragment packet
-        buffer.get(new byte[IKE_FIRST_PAYLOAD_OFFSET]);
-        int firstPayload = Byte.toUnsignedInt(buffer.get());
-        if (firstPayload != IKE_PAYLOAD_TYPE_SKF) {
-            return false;
-        }
-
-        // Check fragment number
-        buffer.reset();
-        buffer.get(new byte[IKE_FRAG_NUM_OFFSET]);
-        int fragNum = Short.toUnsignedInt(buffer.getShort());
-        return expectedFragNum == fragNum;
-    }
-
-    public static class PortPair {
-        public final int srcPort;
-        public final int dstPort;
-
-        public PortPair(int sourcePort, int destinationPort) {
-            srcPort = sourcePort;
-            dstPort = destinationPort;
-        }
-    }
-
-    public static PortPair getSrcDestPortPair(byte[] outboundIkePkt) throws Exception {
-        return new PortPair(
-                getPort(outboundIkePkt, true /* shouldGetSource */),
-                getPort(outboundIkePkt, false /* shouldGetSource */));
-    }
-
-    private static InetAddress getAddress(byte[] pkt, boolean shouldGetSource) throws Exception {
-        int ipLen = isIpv6(pkt) ? IP6_ADDR_LEN : IP4_ADDR_LEN;
-        int srcIpOffset = isIpv6(pkt) ? IP6_ADDR_OFFSET : IP4_ADDR_OFFSET;
-        int ipOffset = shouldGetSource ? srcIpOffset : srcIpOffset + ipLen;
-
-        ByteBuffer buffer = ByteBuffer.wrap(pkt);
-        buffer.get(new byte[ipOffset]);
-        byte[] ipAddrBytes = new byte[ipLen];
-        buffer.get(ipAddrBytes);
-        return InetAddress.getByAddress(ipAddrBytes);
-    }
-
-    private static int getPort(byte[] pkt, boolean shouldGetSource) {
-        ByteBuffer buffer = ByteBuffer.wrap(pkt);
-        int srcPortOffset = isIpv6(pkt) ? IP6_HDRLEN : IP4_HDRLEN;
-        int portOffset = shouldGetSource ? srcPortOffset : srcPortOffset + PORT_LEN;
-
-        buffer.get(new byte[portOffset]);
-        return Short.toUnsignedInt(buffer.getShort());
-    }
-
-    public static byte[] buildIkePacket(
-            InetAddress srcAddr,
-            InetAddress dstAddr,
-            int srcPort,
-            int dstPort,
-            boolean useEncap,
-            byte[] ikePacket)
-            throws Exception {
-        if (useEncap) {
-            ByteBuffer buffer = ByteBuffer.allocate(NON_ESP_MARKER_LEN + ikePacket.length);
-            buffer.put(NON_ESP_MARKER);
-            buffer.put(ikePacket);
-            ikePacket = buffer.array();
-        }
-
-        UdpHeader udpPkt = new UdpHeader(srcPort, dstPort, new BytePayload(ikePacket));
-        IpHeader ipPkt = getIpHeader(udpPkt.getProtocolId(), srcAddr, dstAddr, udpPkt);
-        return ipPkt.getPacketBytes();
-    }
-
-    private static IpHeader getIpHeader(
-            int protocol, InetAddress src, InetAddress dst, Payload payload) {
-        if ((src instanceof Inet6Address) != (dst instanceof Inet6Address)) {
-            throw new IllegalArgumentException("Invalid src/dst address combination");
-        }
-
-        if (src instanceof Inet6Address) {
-            return new Ip6Header(protocol, (Inet6Address) src, (Inet6Address) dst, payload);
-        } else {
-            return new Ip4Header(protocol, (Inet4Address) src, (Inet4Address) dst, payload);
-        }
-    }
-}
diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/PacketUtils.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/PacketUtils.java
deleted file mode 100644
index 35e6719..0000000
--- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/PacketUtils.java
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * 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 android.net.ipsec.ike.cts;
-
-import static android.system.OsConstants.IPPROTO_IPV6;
-import static android.system.OsConstants.IPPROTO_UDP;
-
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.nio.ByteBuffer;
-import java.nio.ShortBuffer;
-import java.security.GeneralSecurityException;
-import java.security.SecureRandom;
-import java.util.Arrays;
-
-import javax.crypto.Cipher;
-import javax.crypto.Mac;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-
-/**
- * This code is a exact copy of {@link PacketUtils} in
- * cts/tests/tests/net/src/android/net/cts/PacketUtils.java.
- *
- * <p>TODO(b/148689509): Statically include the PacketUtils source file instead of copying it.
- */
-public class PacketUtils {
-    private static final String TAG = PacketUtils.class.getSimpleName();
-
-    private static final int DATA_BUFFER_LEN = 4096;
-
-    static final int IP4_HDRLEN = 20;
-    static final int IP6_HDRLEN = 40;
-    static final int UDP_HDRLEN = 8;
-    static final int TCP_HDRLEN = 20;
-    static final int TCP_HDRLEN_WITH_TIMESTAMP_OPT = TCP_HDRLEN + 12;
-
-    // Not defined in OsConstants
-    static final int IPPROTO_IPV4 = 4;
-    static final int IPPROTO_ESP = 50;
-
-    // Encryption parameters
-    static final int AES_GCM_IV_LEN = 8;
-    static final int AES_CBC_IV_LEN = 16;
-    static final int AES_GCM_BLK_SIZE = 4;
-    static final int AES_CBC_BLK_SIZE = 16;
-
-    // Encryption algorithms
-    static final String AES = "AES";
-    static final String AES_CBC = "AES/CBC/NoPadding";
-    static final String HMAC_SHA_256 = "HmacSHA256";
-
-    public interface Payload {
-        byte[] getPacketBytes(IpHeader header) throws Exception;
-
-        void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) throws Exception;
-
-        short length();
-
-        int getProtocolId();
-    }
-
-    public abstract static class IpHeader {
-
-        public final byte proto;
-        public final InetAddress srcAddr;
-        public final InetAddress dstAddr;
-        public final Payload payload;
-
-        public IpHeader(int proto, InetAddress src, InetAddress dst, Payload payload) {
-            this.proto = (byte) proto;
-            this.srcAddr = src;
-            this.dstAddr = dst;
-            this.payload = payload;
-        }
-
-        public abstract byte[] getPacketBytes() throws Exception;
-
-        public abstract int getProtocolId();
-    }
-
-    public static class Ip4Header extends IpHeader {
-        private short checksum;
-
-        public Ip4Header(int proto, Inet4Address src, Inet4Address dst, Payload payload) {
-            super(proto, src, dst, payload);
-        }
-
-        public byte[] getPacketBytes() throws Exception {
-            ByteBuffer resultBuffer = buildHeader();
-            payload.addPacketBytes(this, resultBuffer);
-
-            return getByteArrayFromBuffer(resultBuffer);
-        }
-
-        public ByteBuffer buildHeader() {
-            ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN);
-
-            // Version, IHL
-            bb.put((byte) (0x45));
-
-            // DCSP, ECN
-            bb.put((byte) 0);
-
-            // Total Length
-            bb.putShort((short) (IP4_HDRLEN + payload.length()));
-
-            // Empty for Identification, Flags and Fragment Offset
-            bb.putShort((short) 0);
-            bb.put((byte) 0x40);
-            bb.put((byte) 0x00);
-
-            // TTL
-            bb.put((byte) 64);
-
-            // Protocol
-            bb.put(proto);
-
-            // Header Checksum
-            final int ipChecksumOffset = bb.position();
-            bb.putShort((short) 0);
-
-            // Src/Dst addresses
-            bb.put(srcAddr.getAddress());
-            bb.put(dstAddr.getAddress());
-
-            bb.putShort(ipChecksumOffset, calculateChecksum(bb));
-
-            return bb;
-        }
-
-        private short calculateChecksum(ByteBuffer bb) {
-            int checksum = 0;
-
-            // Calculate sum of 16-bit values, excluding checksum. IPv4 headers are always 32-bit
-            // aligned, so no special cases needed for unaligned values.
-            ShortBuffer shortBuffer = ByteBuffer.wrap(getByteArrayFromBuffer(bb)).asShortBuffer();
-            while (shortBuffer.hasRemaining()) {
-                short val = shortBuffer.get();
-
-                // Wrap as needed
-                checksum = addAndWrapForChecksum(checksum, val);
-            }
-
-            return onesComplement(checksum);
-        }
-
-        public int getProtocolId() {
-            return IPPROTO_IPV4;
-        }
-    }
-
-    public static class Ip6Header extends IpHeader {
-        public Ip6Header(int nextHeader, Inet6Address src, Inet6Address dst, Payload payload) {
-            super(nextHeader, src, dst, payload);
-        }
-
-        public byte[] getPacketBytes() throws Exception {
-            ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN);
-
-            // Version | Traffic Class (First 4 bits)
-            bb.put((byte) 0x60);
-
-            // Traffic class (Last 4 bits), Flow Label
-            bb.put((byte) 0);
-            bb.put((byte) 0);
-            bb.put((byte) 0);
-
-            // Payload Length
-            bb.putShort((short) payload.length());
-
-            // Next Header
-            bb.put(proto);
-
-            // Hop Limit
-            bb.put((byte) 64);
-
-            // Src/Dst addresses
-            bb.put(srcAddr.getAddress());
-            bb.put(dstAddr.getAddress());
-
-            // Payload
-            payload.addPacketBytes(this, bb);
-
-            return getByteArrayFromBuffer(bb);
-        }
-
-        public int getProtocolId() {
-            return IPPROTO_IPV6;
-        }
-    }
-
-    public static class BytePayload implements Payload {
-        public final byte[] payload;
-
-        public BytePayload(byte[] payload) {
-            this.payload = payload;
-        }
-
-        public int getProtocolId() {
-            return -1;
-        }
-
-        public byte[] getPacketBytes(IpHeader header) {
-            ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN);
-
-            addPacketBytes(header, bb);
-            return getByteArrayFromBuffer(bb);
-        }
-
-        public void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) {
-            resultBuffer.put(payload);
-        }
-
-        public short length() {
-            return (short) payload.length;
-        }
-    }
-
-    public static class UdpHeader implements Payload {
-
-        public final short srcPort;
-        public final short dstPort;
-        public final Payload payload;
-
-        public UdpHeader(int srcPort, int dstPort, Payload payload) {
-            this.srcPort = (short) srcPort;
-            this.dstPort = (short) dstPort;
-            this.payload = payload;
-        }
-
-        public int getProtocolId() {
-            return IPPROTO_UDP;
-        }
-
-        public short length() {
-            return (short) (payload.length() + 8);
-        }
-
-        public byte[] getPacketBytes(IpHeader header) throws Exception {
-            ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN);
-
-            addPacketBytes(header, bb);
-            return getByteArrayFromBuffer(bb);
-        }
-
-        public void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) throws Exception {
-            // Source, Destination port
-            resultBuffer.putShort(srcPort);
-            resultBuffer.putShort(dstPort);
-
-            // Payload Length
-            resultBuffer.putShort(length());
-
-            // Get payload bytes for checksum + payload
-            ByteBuffer payloadBuffer = ByteBuffer.allocate(DATA_BUFFER_LEN);
-            payload.addPacketBytes(header, payloadBuffer);
-            byte[] payloadBytes = getByteArrayFromBuffer(payloadBuffer);
-
-            // Checksum
-            resultBuffer.putShort(calculateChecksum(header, payloadBytes));
-
-            // Payload
-            resultBuffer.put(payloadBytes);
-        }
-
-        private short calculateChecksum(IpHeader header, byte[] payloadBytes) throws Exception {
-            int newChecksum = 0;
-            ShortBuffer srcBuffer = ByteBuffer.wrap(header.srcAddr.getAddress()).asShortBuffer();
-            ShortBuffer dstBuffer = ByteBuffer.wrap(header.dstAddr.getAddress()).asShortBuffer();
-
-            while (srcBuffer.hasRemaining() || dstBuffer.hasRemaining()) {
-                short val = srcBuffer.hasRemaining() ? srcBuffer.get() : dstBuffer.get();
-
-                // Wrap as needed
-                newChecksum = addAndWrapForChecksum(newChecksum, val);
-            }
-
-            // Add pseudo-header values. Proto is 0-padded, so just use the byte.
-            newChecksum = addAndWrapForChecksum(newChecksum, header.proto);
-            newChecksum = addAndWrapForChecksum(newChecksum, length());
-            newChecksum = addAndWrapForChecksum(newChecksum, srcPort);
-            newChecksum = addAndWrapForChecksum(newChecksum, dstPort);
-            newChecksum = addAndWrapForChecksum(newChecksum, length());
-
-            ShortBuffer payloadShortBuffer = ByteBuffer.wrap(payloadBytes).asShortBuffer();
-            while (payloadShortBuffer.hasRemaining()) {
-                newChecksum = addAndWrapForChecksum(newChecksum, payloadShortBuffer.get());
-            }
-            if (payload.length() % 2 != 0) {
-                newChecksum =
-                        addAndWrapForChecksum(
-                                newChecksum, (payloadBytes[payloadBytes.length - 1] << 8));
-            }
-
-            return onesComplement(newChecksum);
-        }
-    }
-
-    public static class EspHeader implements Payload {
-        public final int nextHeader;
-        public final int spi;
-        public final int seqNum;
-        public final byte[] key;
-        public final byte[] payload;
-
-        /**
-         * Generic constructor for ESP headers.
-         *
-         * <p>For Tunnel mode, payload will be a full IP header + attached payloads
-         *
-         * <p>For Transport mode, payload will be only the attached payloads, but with the checksum
-         * calculated using the pre-encryption IP header
-         */
-        public EspHeader(int nextHeader, int spi, int seqNum, byte[] key, byte[] payload) {
-            this.nextHeader = nextHeader;
-            this.spi = spi;
-            this.seqNum = seqNum;
-            this.key = key;
-            this.payload = payload;
-        }
-
-        public int getProtocolId() {
-            return IPPROTO_ESP;
-        }
-
-        public short length() {
-            // ALWAYS uses AES-CBC, HMAC-SHA256 (128b trunc len)
-            return (short)
-                    calculateEspPacketSize(payload.length, AES_CBC_IV_LEN, AES_CBC_BLK_SIZE, 128);
-        }
-
-        public byte[] getPacketBytes(IpHeader header) throws Exception {
-            ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN);
-
-            addPacketBytes(header, bb);
-            return getByteArrayFromBuffer(bb);
-        }
-
-        public void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) throws Exception {
-            ByteBuffer espPayloadBuffer = ByteBuffer.allocate(DATA_BUFFER_LEN);
-            espPayloadBuffer.putInt(spi);
-            espPayloadBuffer.putInt(seqNum);
-            espPayloadBuffer.put(getCiphertext(key));
-
-            espPayloadBuffer.put(getIcv(getByteArrayFromBuffer(espPayloadBuffer)), 0, 16);
-            resultBuffer.put(getByteArrayFromBuffer(espPayloadBuffer));
-        }
-
-        private byte[] getIcv(byte[] authenticatedSection) throws GeneralSecurityException {
-            Mac sha256HMAC = Mac.getInstance(HMAC_SHA_256);
-            SecretKeySpec authKey = new SecretKeySpec(key, HMAC_SHA_256);
-            sha256HMAC.init(authKey);
-
-            return sha256HMAC.doFinal(authenticatedSection);
-        }
-
-        /**
-         * Encrypts and builds ciphertext block. Includes the IV, Padding and Next-Header blocks
-         *
-         * <p>The ciphertext does NOT include the SPI/Sequence numbers, or the ICV.
-         */
-        private byte[] getCiphertext(byte[] key) throws GeneralSecurityException {
-            int paddedLen = calculateEspEncryptedLength(payload.length, AES_CBC_BLK_SIZE);
-            ByteBuffer paddedPayload = ByteBuffer.allocate(paddedLen);
-            paddedPayload.put(payload);
-
-            // Add padding - consecutive integers from 0x01
-            int pad = 1;
-            while (paddedPayload.position() < paddedPayload.limit()) {
-                paddedPayload.put((byte) pad++);
-            }
-
-            paddedPayload.position(paddedPayload.limit() - 2);
-            paddedPayload.put((byte) (paddedLen - 2 - payload.length)); // Pad length
-            paddedPayload.put((byte) nextHeader);
-
-            // Generate Initialization Vector
-            byte[] iv = new byte[AES_CBC_IV_LEN];
-            new SecureRandom().nextBytes(iv);
-            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
-            SecretKeySpec secretKeySpec = new SecretKeySpec(key, AES);
-
-            // Encrypt payload
-            Cipher cipher = Cipher.getInstance(AES_CBC);
-            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
-            byte[] encrypted = cipher.doFinal(getByteArrayFromBuffer(paddedPayload));
-
-            // Build ciphertext
-            ByteBuffer cipherText = ByteBuffer.allocate(AES_CBC_IV_LEN + encrypted.length);
-            cipherText.put(iv);
-            cipherText.put(encrypted);
-
-            return getByteArrayFromBuffer(cipherText);
-        }
-    }
-
-    private static int addAndWrapForChecksum(int currentChecksum, int value) {
-        currentChecksum += value & 0x0000ffff;
-
-        // Wrap anything beyond the first 16 bits, and add to lower order bits
-        return (currentChecksum >>> 16) + (currentChecksum & 0x0000ffff);
-    }
-
-    private static short onesComplement(int val) {
-        val = (val >>> 16) + (val & 0xffff);
-
-        if (val == 0) return 0;
-        return (short) ((~val) & 0xffff);
-    }
-
-    public static int calculateEspPacketSize(
-            int payloadLen, int cryptIvLength, int cryptBlockSize, int authTruncLen) {
-        final int ESP_HDRLEN = 4 + 4; // SPI + Seq#
-        final int ICV_LEN = authTruncLen / 8; // Auth trailer; based on truncation length
-        payloadLen += cryptIvLength; // Initialization Vector
-
-        // Align to block size of encryption algorithm
-        payloadLen = calculateEspEncryptedLength(payloadLen, cryptBlockSize);
-        return payloadLen + ESP_HDRLEN + ICV_LEN;
-    }
-
-    private static int calculateEspEncryptedLength(int payloadLen, int cryptBlockSize) {
-        payloadLen += 2; // ESP trailer
-
-        // Align to block size of encryption algorithm
-        return payloadLen + calculateEspPadLen(payloadLen, cryptBlockSize);
-    }
-
-    private static int calculateEspPadLen(int payloadLen, int cryptBlockSize) {
-        return (cryptBlockSize - (payloadLen % cryptBlockSize)) % cryptBlockSize;
-    }
-
-    private static byte[] getByteArrayFromBuffer(ByteBuffer buffer) {
-        return Arrays.copyOfRange(buffer.array(), 0, buffer.position());
-    }
-
-    /*
-     * Debug printing
-     */
-    private static final char[] hexArray = "0123456789ABCDEF".toCharArray();
-
-    public static String bytesToHex(byte[] bytes) {
-        StringBuilder sb = new StringBuilder();
-        for (byte b : bytes) {
-            sb.append(hexArray[b >>> 4]);
-            sb.append(hexArray[b & 0x0F]);
-            sb.append(' ');
-        }
-        return sb.toString();
-    }
-}
diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java
deleted file mode 100644
index e0d3be0..0000000
--- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * 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 android.net.ipsec.ike.cts;
-
-import static android.net.ipsec.ike.SaProposal.DH_GROUP_1024_BIT_MODP;
-import static android.net.ipsec.ike.SaProposal.DH_GROUP_2048_BIT_MODP;
-import static android.net.ipsec.ike.SaProposal.DH_GROUP_NONE;
-import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_3DES;
-import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_CBC;
-import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12;
-import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16;
-import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8;
-import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_AES_XCBC_96;
-import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96;
-import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128;
-import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_384_192;
-import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_512_256;
-import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_NONE;
-import static android.net.ipsec.ike.SaProposal.KEY_LEN_AES_128;
-import static android.net.ipsec.ike.SaProposal.KEY_LEN_AES_192;
-import static android.net.ipsec.ike.SaProposal.KEY_LEN_AES_256;
-import static android.net.ipsec.ike.SaProposal.KEY_LEN_UNUSED;
-import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC;
-import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1;
-import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_SHA2_256;
-import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_SHA2_384;
-import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_SHA2_512;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.net.ipsec.ike.ChildSaProposal;
-import android.net.ipsec.ike.IkeSaProposal;
-import android.util.Pair;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-public class SaProposalTest {
-    private static final List<Pair<Integer, Integer>> NORMAL_MODE_CIPHERS = new ArrayList<>();
-    private static final List<Pair<Integer, Integer>> COMBINED_MODE_CIPHERS = new ArrayList<>();
-    private static final List<Integer> INTEGRITY_ALGOS = new ArrayList<>();
-    private static final List<Integer> DH_GROUPS = new ArrayList<>();
-    private static final List<Integer> DH_GROUPS_WITH_NONE = new ArrayList<>();
-    private static final List<Integer> PRFS = new ArrayList<>();
-
-    static {
-        NORMAL_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED));
-        NORMAL_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_128));
-        NORMAL_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_192));
-        NORMAL_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_256));
-
-        COMBINED_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_GCM_8, KEY_LEN_AES_128));
-        COMBINED_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_192));
-        COMBINED_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_256));
-
-        INTEGRITY_ALGOS.add(INTEGRITY_ALGORITHM_HMAC_SHA1_96);
-        INTEGRITY_ALGOS.add(INTEGRITY_ALGORITHM_AES_XCBC_96);
-        INTEGRITY_ALGOS.add(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128);
-        INTEGRITY_ALGOS.add(INTEGRITY_ALGORITHM_HMAC_SHA2_384_192);
-        INTEGRITY_ALGOS.add(INTEGRITY_ALGORITHM_HMAC_SHA2_512_256);
-
-        DH_GROUPS.add(DH_GROUP_1024_BIT_MODP);
-        DH_GROUPS.add(DH_GROUP_2048_BIT_MODP);
-
-        DH_GROUPS_WITH_NONE.add(DH_GROUP_NONE);
-        DH_GROUPS_WITH_NONE.addAll(DH_GROUPS);
-
-        PRFS.add(PSEUDORANDOM_FUNCTION_HMAC_SHA1);
-        PRFS.add(PSEUDORANDOM_FUNCTION_AES128_XCBC);
-        PRFS.add(PSEUDORANDOM_FUNCTION_SHA2_256);
-        PRFS.add(PSEUDORANDOM_FUNCTION_SHA2_384);
-        PRFS.add(PSEUDORANDOM_FUNCTION_SHA2_512);
-    }
-
-    // Package private
-    static IkeSaProposal buildIkeSaProposalWithNormalModeCipher() {
-        return buildIkeSaProposal(NORMAL_MODE_CIPHERS, INTEGRITY_ALGOS, PRFS, DH_GROUPS);
-    }
-
-    // Package private
-    static IkeSaProposal buildIkeSaProposalWithCombinedModeCipher() {
-        return buildIkeSaProposalWithCombinedModeCipher(true /* hasIntegrityNone */);
-    }
-
-    private static IkeSaProposal buildIkeSaProposalWithCombinedModeCipher(
-            boolean hasIntegrityNone) {
-        List<Integer> integerAlgos = new ArrayList<>();
-        if (hasIntegrityNone) {
-            integerAlgos.add(INTEGRITY_ALGORITHM_NONE);
-        }
-        return buildIkeSaProposal(COMBINED_MODE_CIPHERS, integerAlgos, PRFS, DH_GROUPS);
-    }
-
-    private static IkeSaProposal buildIkeSaProposal(
-            List<Pair<Integer, Integer>> ciphers,
-            List<Integer> integrityAlgos,
-            List<Integer> prfs,
-            List<Integer> dhGroups) {
-        IkeSaProposal.Builder builder = new IkeSaProposal.Builder();
-
-        for (Pair<Integer, Integer> pair : ciphers) {
-            builder.addEncryptionAlgorithm(pair.first, pair.second);
-        }
-        for (int algo : integrityAlgos) {
-            builder.addIntegrityAlgorithm(algo);
-        }
-        for (int algo : prfs) {
-            builder.addPseudorandomFunction(algo);
-        }
-        for (int algo : dhGroups) {
-            builder.addDhGroup(algo);
-        }
-
-        return builder.build();
-    }
-
-    // Package private
-    static ChildSaProposal buildChildSaProposalWithNormalModeCipher() {
-        return buildChildSaProposal(NORMAL_MODE_CIPHERS, INTEGRITY_ALGOS, DH_GROUPS_WITH_NONE);
-    }
-
-    // Package private
-    static ChildSaProposal buildChildSaProposalWithCombinedModeCipher() {
-        return buildChildSaProposalWithCombinedModeCipher(true /* hasIntegrityNone */);
-    }
-
-    private static ChildSaProposal buildChildSaProposalWithCombinedModeCipher(
-            boolean hasIntegrityNone) {
-        List<Integer> integerAlgos = new ArrayList<>();
-        if (hasIntegrityNone) {
-            integerAlgos.add(INTEGRITY_ALGORITHM_NONE);
-        }
-
-        return buildChildSaProposal(COMBINED_MODE_CIPHERS, integerAlgos, DH_GROUPS_WITH_NONE);
-    }
-
-    private static ChildSaProposal buildChildSaProposal(
-            List<Pair<Integer, Integer>> ciphers,
-            List<Integer> integrityAlgos,
-            List<Integer> dhGroups) {
-        ChildSaProposal.Builder builder = new ChildSaProposal.Builder();
-
-        for (Pair<Integer, Integer> pair : ciphers) {
-            builder.addEncryptionAlgorithm(pair.first, pair.second);
-        }
-        for (int algo : integrityAlgos) {
-            builder.addIntegrityAlgorithm(algo);
-        }
-        for (int algo : dhGroups) {
-            builder.addDhGroup(algo);
-        }
-
-        return builder.build();
-    }
-
-    // Package private
-    static ChildSaProposal buildChildSaProposalWithOnlyCiphers() {
-        return buildChildSaProposal(
-                COMBINED_MODE_CIPHERS, Collections.EMPTY_LIST, Collections.EMPTY_LIST);
-    }
-
-    @Test
-    public void testBuildIkeSaProposalWithNormalModeCipher() {
-        IkeSaProposal saProposal = buildIkeSaProposalWithNormalModeCipher();
-
-        assertEquals(NORMAL_MODE_CIPHERS, saProposal.getEncryptionAlgorithms());
-        assertEquals(INTEGRITY_ALGOS, saProposal.getIntegrityAlgorithms());
-        assertEquals(PRFS, saProposal.getPseudorandomFunctions());
-        assertEquals(DH_GROUPS, saProposal.getDhGroups());
-    }
-
-    @Test
-    public void testBuildIkeSaProposalWithCombinedModeCipher() {
-        IkeSaProposal saProposal =
-                buildIkeSaProposalWithCombinedModeCipher(false /* hasIntegrityNone */);
-
-        assertEquals(COMBINED_MODE_CIPHERS, saProposal.getEncryptionAlgorithms());
-        assertEquals(PRFS, saProposal.getPseudorandomFunctions());
-        assertEquals(DH_GROUPS, saProposal.getDhGroups());
-        assertTrue(saProposal.getIntegrityAlgorithms().isEmpty());
-    }
-
-    @Test
-    public void testBuildIkeSaProposalWithCombinedModeCipherAndIntegrityNone() {
-        IkeSaProposal saProposal =
-                buildIkeSaProposalWithCombinedModeCipher(true /* hasIntegrityNone */);
-
-        assertEquals(COMBINED_MODE_CIPHERS, saProposal.getEncryptionAlgorithms());
-        assertEquals(PRFS, saProposal.getPseudorandomFunctions());
-        assertEquals(DH_GROUPS, saProposal.getDhGroups());
-        assertEquals(Arrays.asList(INTEGRITY_ALGORITHM_NONE), saProposal.getIntegrityAlgorithms());
-    }
-
-    @Test
-    public void testBuildChildSaProposalWithNormalModeCipher() {
-        ChildSaProposal saProposal = buildChildSaProposalWithNormalModeCipher();
-
-        assertEquals(NORMAL_MODE_CIPHERS, saProposal.getEncryptionAlgorithms());
-        assertEquals(INTEGRITY_ALGOS, saProposal.getIntegrityAlgorithms());
-        assertEquals(DH_GROUPS_WITH_NONE, saProposal.getDhGroups());
-    }
-
-    @Test
-    public void testBuildChildProposalWithCombinedModeCipher() {
-        ChildSaProposal saProposal =
-                buildChildSaProposalWithCombinedModeCipher(false /* hasIntegrityNone */);
-
-        assertEquals(COMBINED_MODE_CIPHERS, saProposal.getEncryptionAlgorithms());
-        assertTrue(saProposal.getIntegrityAlgorithms().isEmpty());
-        assertEquals(DH_GROUPS_WITH_NONE, saProposal.getDhGroups());
-    }
-
-    @Test
-    public void testBuildChildProposalWithCombinedModeCipherAndIntegrityNone() {
-        ChildSaProposal saProposal =
-                buildChildSaProposalWithCombinedModeCipher(true /* hasIntegrityNone */);
-
-        assertEquals(COMBINED_MODE_CIPHERS, saProposal.getEncryptionAlgorithms());
-        assertEquals(Arrays.asList(INTEGRITY_ALGORITHM_NONE), saProposal.getIntegrityAlgorithms());
-        assertEquals(DH_GROUPS_WITH_NONE, saProposal.getDhGroups());
-    }
-
-    @Test
-    public void testBuildChildSaProposalWithOnlyCiphers() {
-        ChildSaProposal saProposal = buildChildSaProposalWithOnlyCiphers();
-
-        assertEquals(COMBINED_MODE_CIPHERS, saProposal.getEncryptionAlgorithms());
-        assertTrue(saProposal.getIntegrityAlgorithms().isEmpty());
-        assertTrue(saProposal.getDhGroups().isEmpty());
-    }
-
-    // TODO(b/148689509): Test throwing exception when algorithm combination is invalid
-}
diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TestNetworkUtils.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TestNetworkUtils.java
deleted file mode 100644
index 5b08cdc..0000000
--- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TestNetworkUtils.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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 android.net.ipsec.ike.cts;
-
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
-import static android.net.NetworkCapabilities.TRANSPORT_TEST;
-
-import android.net.ConnectivityManager;
-import android.net.Network;
-import android.net.NetworkRequest;
-import android.net.TestNetworkManager;
-import android.os.IBinder;
-import android.os.RemoteException;
-
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
-
-// TODO(b/148689509): Share this class with net CTS test (e.g. IpSecManagerTunnelTest)
-public class TestNetworkUtils {
-    private static final int TIMEOUT_MS = 500;
-
-    /** Callback to receive requested test network. */
-    public static class TestNetworkCallback extends ConnectivityManager.NetworkCallback {
-        private final CompletableFuture<Network> futureNetwork = new CompletableFuture<>();
-
-        @Override
-        public void onAvailable(Network network) {
-            futureNetwork.complete(network);
-        }
-
-        public Network getNetworkBlocking() throws Exception {
-            return futureNetwork.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
-        }
-    }
-
-    /**
-     * Set up test network.
-     *
-     * <p>Caller MUST have MANAGE_TEST_NETWORKS permission to use this method.
-     *
-     * @param connMgr ConnectivityManager to request network.
-     * @param testNetworkMgr TestNetworkManager to set up test network.
-     * @param ifname the name of the interface to be used for the Network LinkProperties.
-     * @param binder a binder object guarding the lifecycle of this test network.
-     * @return TestNetworkCallback to retrieve the test network.
-     * @throws RemoteException if test network setup failed.
-     * @see android.net.TestNetworkManager
-     */
-    public static TestNetworkCallback setupAndGetTestNetwork(
-            ConnectivityManager connMgr,
-            TestNetworkManager testNetworkMgr,
-            String ifname,
-            IBinder binder)
-            throws RemoteException {
-        NetworkRequest nr =
-                new NetworkRequest.Builder()
-                        .addTransportType(TRANSPORT_TEST)
-                        .removeCapability(NET_CAPABILITY_TRUSTED)
-                        .removeCapability(NET_CAPABILITY_NOT_VPN)
-                        .setNetworkSpecifier(ifname)
-                        .build();
-
-        TestNetworkCallback cb = new TestNetworkCallback();
-        connMgr.requestNetwork(nr, cb);
-
-        // Setup the test network after network request is filed to prevent Network from being
-        // reaped due to no requests matching it.
-        testNetworkMgr.setupTestNetwork(ifname, binder);
-
-        return cb;
-    }
-}
diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TunUtils.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TunUtils.java
deleted file mode 100644
index 5539dbc..0000000
--- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TunUtils.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * 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 android.net.ipsec.ike.cts;
-
-import static android.net.ipsec.ike.cts.PacketUtils.IP4_HDRLEN;
-import static android.net.ipsec.ike.cts.PacketUtils.IP6_HDRLEN;
-import static android.net.ipsec.ike.cts.PacketUtils.IPPROTO_ESP;
-import static android.net.ipsec.ike.cts.PacketUtils.UDP_HDRLEN;
-import static android.system.OsConstants.IPPROTO_UDP;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.fail;
-
-import android.os.ParcelFileDescriptor;
-
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.function.Predicate;
-
-/**
- * This code is a exact copy of {@link TunUtils} in
- * cts/tests/tests/net/src/android/net/cts/TunUtils.java, except the import path of PacketUtils is
- * the path to the copy of PacktUtils.
- *
- * <p>TODO(b/148689509): Statically include the TunUtils source file instead of copying it.
- */
-public class TunUtils {
-    private static final String TAG = TunUtils.class.getSimpleName();
-
-    private static final int DATA_BUFFER_LEN = 4096;
-    static final int TIMEOUT = 500;
-
-    static final int IP4_PROTO_OFFSET = 9;
-    static final int IP6_PROTO_OFFSET = 6;
-
-    static final int IP4_ADDR_OFFSET = 12;
-    static final int IP4_ADDR_LEN = 4;
-    static final int IP6_ADDR_OFFSET = 8;
-    static final int IP6_ADDR_LEN = 16;
-
-    final List<byte[]> mPackets = new ArrayList<>();
-    private final ParcelFileDescriptor mTunFd;
-    private final Thread mReaderThread;
-
-    public TunUtils(ParcelFileDescriptor tunFd) {
-        mTunFd = tunFd;
-
-        // Start background reader thread
-        mReaderThread =
-                new Thread(
-                        () -> {
-                            try {
-                                // Loop will exit and thread will quit when tunFd is closed.
-                                // Receiving either EOF or an exception will exit this reader loop.
-                                // FileInputStream in uninterruptable, so there's no good way to
-                                // ensure that this thread shuts down except upon FD closure.
-                                while (true) {
-                                    byte[] intercepted = receiveFromTun();
-                                    if (intercepted == null) {
-                                        // Exit once we've hit EOF
-                                        return;
-                                    } else if (intercepted.length > 0) {
-                                        // Only save packet if we've received any bytes.
-                                        synchronized (mPackets) {
-                                            mPackets.add(intercepted);
-                                            mPackets.notifyAll();
-                                        }
-                                    }
-                                }
-                            } catch (IOException ignored) {
-                                // Simply exit this reader thread
-                                return;
-                            }
-                        });
-        mReaderThread.start();
-    }
-
-    private byte[] receiveFromTun() throws IOException {
-        FileInputStream in = new FileInputStream(mTunFd.getFileDescriptor());
-        byte[] inBytes = new byte[DATA_BUFFER_LEN];
-        int bytesRead = in.read(inBytes);
-
-        if (bytesRead < 0) {
-            return null; // return null for EOF
-        } else if (bytesRead >= DATA_BUFFER_LEN) {
-            throw new IllegalStateException("Too big packet. Fragmentation unsupported");
-        }
-        return Arrays.copyOf(inBytes, bytesRead);
-    }
-
-    byte[] getFirstMatchingPacket(Predicate<byte[]> verifier, int startIndex) {
-        synchronized (mPackets) {
-            for (int i = startIndex; i < mPackets.size(); i++) {
-                byte[] pkt = mPackets.get(i);
-                if (verifier.test(pkt)) {
-                    return pkt;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Checks if the specified bytes were ever sent in plaintext.
-     *
-     * <p>Only checks for known plaintext bytes to prevent triggering on ICMP/RA packets or the like
-     *
-     * @param plaintext the plaintext bytes to check for
-     * @param startIndex the index in the list to check for
-     */
-    public boolean hasPlaintextPacket(byte[] plaintext, int startIndex) {
-        Predicate<byte[]> verifier =
-                (pkt) -> {
-                    return Collections.indexOfSubList(Arrays.asList(pkt), Arrays.asList(plaintext))
-                            != -1;
-                };
-        return getFirstMatchingPacket(verifier, startIndex) != null;
-    }
-
-    public byte[] getEspPacket(int spi, boolean encap, int startIndex) {
-        return getFirstMatchingPacket(
-                (pkt) -> {
-                    return isEsp(pkt, spi, encap);
-                },
-                startIndex);
-    }
-
-    public byte[] awaitEspPacketNoPlaintext(
-            int spi, byte[] plaintext, boolean useEncap, int expectedPacketSize) throws Exception {
-        long endTime = System.currentTimeMillis() + TIMEOUT;
-        int startIndex = 0;
-
-        synchronized (mPackets) {
-            while (System.currentTimeMillis() < endTime) {
-                byte[] espPkt = getEspPacket(spi, useEncap, startIndex);
-                if (espPkt != null) {
-                    // Validate packet size
-                    assertEquals(expectedPacketSize, espPkt.length);
-
-                    // Always check plaintext from start
-                    assertFalse(hasPlaintextPacket(plaintext, 0));
-                    return espPkt; // We've found the packet we're looking for.
-                }
-
-                startIndex = mPackets.size();
-
-                // Try to prevent waiting too long. If waitTimeout <= 0, we've already hit timeout
-                long waitTimeout = endTime - System.currentTimeMillis();
-                if (waitTimeout > 0) {
-                    mPackets.wait(waitTimeout);
-                }
-            }
-
-            fail("No such ESP packet found with SPI " + spi);
-        }
-        return null;
-    }
-
-    private static boolean isSpiEqual(byte[] pkt, int espOffset, int spi) {
-        // Check SPI byte by byte.
-        return pkt[espOffset] == (byte) ((spi >>> 24) & 0xff)
-                && pkt[espOffset + 1] == (byte) ((spi >>> 16) & 0xff)
-                && pkt[espOffset + 2] == (byte) ((spi >>> 8) & 0xff)
-                && pkt[espOffset + 3] == (byte) (spi & 0xff);
-    }
-
-    private static boolean isEsp(byte[] pkt, int spi, boolean encap) {
-        if (isIpv6(pkt)) {
-            // IPv6 UDP encap not supported by kernels; assume non-encap.
-            return pkt[IP6_PROTO_OFFSET] == IPPROTO_ESP && isSpiEqual(pkt, IP6_HDRLEN, spi);
-        } else {
-            // Use default IPv4 header length (assuming no options)
-            if (encap) {
-                return pkt[IP4_PROTO_OFFSET] == IPPROTO_UDP
-                        && isSpiEqual(pkt, IP4_HDRLEN + UDP_HDRLEN, spi);
-            } else {
-                return pkt[IP4_PROTO_OFFSET] == IPPROTO_ESP && isSpiEqual(pkt, IP4_HDRLEN, spi);
-            }
-        }
-    }
-
-    static boolean isIpv6(byte[] pkt) {
-        // First nibble shows IP version. 0x60 for IPv6
-        return (pkt[0] & (byte) 0xF0) == (byte) 0x60;
-    }
-
-    private static byte[] getReflectedPacket(byte[] pkt) {
-        byte[] reflected = Arrays.copyOf(pkt, pkt.length);
-
-        if (isIpv6(pkt)) {
-            // Set reflected packet's dst to that of the original's src
-            System.arraycopy(
-                    pkt, // src
-                    IP6_ADDR_OFFSET + IP6_ADDR_LEN, // src offset
-                    reflected, // dst
-                    IP6_ADDR_OFFSET, // dst offset
-                    IP6_ADDR_LEN); // len
-            // Set reflected packet's src IP to that of the original's dst IP
-            System.arraycopy(
-                    pkt, // src
-                    IP6_ADDR_OFFSET, // src offset
-                    reflected, // dst
-                    IP6_ADDR_OFFSET + IP6_ADDR_LEN, // dst offset
-                    IP6_ADDR_LEN); // len
-        } else {
-            // Set reflected packet's dst to that of the original's src
-            System.arraycopy(
-                    pkt, // src
-                    IP4_ADDR_OFFSET + IP4_ADDR_LEN, // src offset
-                    reflected, // dst
-                    IP4_ADDR_OFFSET, // dst offset
-                    IP4_ADDR_LEN); // len
-            // Set reflected packet's src IP to that of the original's dst IP
-            System.arraycopy(
-                    pkt, // src
-                    IP4_ADDR_OFFSET, // src offset
-                    reflected, // dst
-                    IP4_ADDR_OFFSET + IP4_ADDR_LEN, // dst offset
-                    IP4_ADDR_LEN); // len
-        }
-        return reflected;
-    }
-
-    /** Takes all captured packets, flips the src/dst, and re-injects them. */
-    public void reflectPackets() throws IOException {
-        synchronized (mPackets) {
-            for (byte[] pkt : mPackets) {
-                injectPacket(getReflectedPacket(pkt));
-            }
-        }
-    }
-
-    public void injectPacket(byte[] pkt) throws IOException {
-        FileOutputStream out = new FileOutputStream(mTunFd.getFileDescriptor());
-        out.write(pkt);
-        out.flush();
-    }
-
-    /** Resets the intercepted packets. */
-    public void reset() throws IOException {
-        synchronized (mPackets) {
-            mPackets.clear();
-        }
-    }
-}
diff --git a/tests/cts/net/jni/NativeMultinetworkJni.cpp b/tests/cts/net/jni/NativeMultinetworkJni.cpp
index cd94709..60e31bc 100644
--- a/tests/cts/net/jni/NativeMultinetworkJni.cpp
+++ b/tests/cts/net/jni/NativeMultinetworkJni.cpp
@@ -458,20 +458,16 @@
     setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo));
 
     // For reference see:
-    //     https://tools.ietf.org/html/draft-tsvwg-quic-protocol#section-6.1
+    //     https://datatracker.ietf.org/doc/html/draft-ietf-quic-invariants
     uint8_t quic_packet[1200] = {
-        0x0d,                    // public flags:
-                                 //   - version present (0x01),
-                                 //   - 64bit connection ID (0x0c),
-                                 //   - 1 byte packet number (0x00)
+        0xc0,                    // long header
+        0xaa, 0xda, 0xca, 0xca,  // reserved-space version number
+        0x08,                    // destination connection ID length
         0, 0, 0, 0, 0, 0, 0, 0,  // 64bit connection ID
-        0xaa, 0xda, 0xca, 0xaa,  // reserved-space version number
-        1,                       // 1 byte packet number
-        0x00,                    // private flags
-        0x07,                    // PING frame (cuz why not)
+        0x00,                    // source connection ID length
     };
 
-    arc4random_buf(quic_packet + 1, 8);  // random connection ID
+    arc4random_buf(quic_packet + 6, 8);  // random connection ID
 
     uint8_t response[1500];
     ssize_t sent, rcvd;
@@ -496,7 +492,7 @@
                   i + 1, MAX_RETRIES, rcvd, errnum);
         }
     }
-    if (rcvd < 9) {
+    if (rcvd < 15) {
         LOGD("QUIC UDP %s: sent=%zd but rcvd=%zd, errno=%d", kPort, sent, rcvd, errnum);
         if (rcvd <= 0) {
             LOGD("Does this network block UDP port %s?", kPort);
@@ -505,7 +501,7 @@
         return -EPROTO;
     }
 
-    int conn_id_cmp = memcmp(quic_packet + 1, response + 1, 8);
+    int conn_id_cmp = memcmp(quic_packet + 6, response + 7, 8);
     if (conn_id_cmp != 0) {
         LOGD("sent and received connection IDs do not match");
         close(fd);
diff --git a/tests/cts/net/native/dns/Android.bp b/tests/cts/net/native/dns/Android.bp
index 1704a2b..6defd35 100644
--- a/tests/cts/net/native/dns/Android.bp
+++ b/tests/cts/net/native/dns/Android.bp
@@ -35,6 +35,7 @@
     },
     test_suites: [
         "cts",
+        "general-tests",
         "mts",
     ],
 }
diff --git a/tests/cts/net/native/qtaguid/Android.bp b/tests/cts/net/native/qtaguid/Android.bp
index 23a0cf7..4861651 100644
--- a/tests/cts/net/native/qtaguid/Android.bp
+++ b/tests/cts/net/native/qtaguid/Android.bp
@@ -42,7 +42,7 @@
     // Tag this module as a cts test artifact
     test_suites: [
         "cts",
-        "vts10",
+        "general-tests",
     ],
 
     cflags: [
diff --git a/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt b/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt
index 12a966f..eb5048f 100644
--- a/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt
+++ b/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt
@@ -30,11 +30,9 @@
 import android.net.NetworkRequest
 import android.net.Uri
 import android.net.cts.NetworkValidationTestUtil.clearValidationTestUrlsDeviceConfig
-import android.net.cts.NetworkValidationTestUtil.runAsShell
 import android.net.cts.NetworkValidationTestUtil.setHttpUrlDeviceConfig
 import android.net.cts.NetworkValidationTestUtil.setHttpsUrlDeviceConfig
 import android.net.cts.NetworkValidationTestUtil.setUrlExpirationDeviceConfig
-import com.android.testutils.TestHttpServer.Request
 import android.net.cts.util.CtsNetUtils
 import android.net.util.NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTPS_URL
 import android.net.util.NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTP_URL
@@ -47,7 +45,9 @@
 import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
 import androidx.test.runner.AndroidJUnit4
 import com.android.testutils.TestHttpServer
+import com.android.testutils.TestHttpServer.Request
 import com.android.testutils.isDevSdkInRange
+import com.android.testutils.runAsShell
 import fi.iki.elonen.NanoHTTPD.Response.Status
 import junit.framework.AssertionFailedError
 import org.junit.After
@@ -123,7 +123,7 @@
     fun testCaptivePortalIsNotDefaultNetwork() {
         assumeTrue(pm.hasSystemFeature(FEATURE_TELEPHONY))
         assumeTrue(pm.hasSystemFeature(FEATURE_WIFI))
-        utils.connectToWifi()
+        utils.ensureWifiConnected()
         utils.connectToCell()
 
         // Have network validation use a local server that serves a HTTPS error / HTTP redirect
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index 4f42ccc..db4e3e7 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -224,6 +224,16 @@
         if (mCtsNetUtils.cellConnectAttempted()) {
             mCtsNetUtils.disconnectFromCell();
         }
+
+        // All tests in this class require a working Internet connection as they start. Make
+        // sure there is still one as they end that's ready to use for the next test to use.
+        final TestNetworkCallback callback = new TestNetworkCallback();
+        mCm.registerDefaultNetworkCallback(callback);
+        try {
+            assertNotNull("Couldn't restore Internet connectivity", callback.waitForAvailable());
+        } finally {
+            mCm.unregisterNetworkCallback(callback);
+        }
     }
 
     /**
diff --git a/tests/cts/net/src/android/net/cts/NetworkValidationTest.kt b/tests/cts/net/src/android/net/cts/NetworkValidationTest.kt
index ec656de..5290f0d 100644
--- a/tests/cts/net/src/android/net/cts/NetworkValidationTest.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkValidationTest.kt
@@ -31,7 +31,6 @@
 import android.net.TestNetworkInterface
 import android.net.TestNetworkManager
 import android.net.Uri
-import android.net.cts.NetworkValidationTestUtil.runAsShell
 import android.net.dhcp.DhcpDiscoverPacket
 import android.net.dhcp.DhcpPacket
 import android.net.dhcp.DhcpPacket.DHCP_MESSAGE_TYPE
@@ -45,8 +44,7 @@
 import androidx.test.runner.AndroidJUnit4
 import com.android.net.module.util.Inet4AddressUtils.getBroadcastAddress
 import com.android.net.module.util.Inet4AddressUtils.getPrefixMaskAsInet4Address
-import com.android.server.util.NetworkStackConstants.IPV4_ADDR_ANY
-import com.android.testutils.ArpResponder
+import com.android.net.module.util.NetworkStackConstants.IPV4_ADDR_ANY
 import com.android.testutils.DevSdkIgnoreRule
 import com.android.testutils.DhcpClientPacketFilter
 import com.android.testutils.DhcpOptionFilter
@@ -54,10 +52,10 @@
 import com.android.testutils.TapPacketReader
 import com.android.testutils.TestHttpServer
 import com.android.testutils.TestableNetworkCallback
+import com.android.testutils.runAsShell
 import fi.iki.elonen.NanoHTTPD.Response.Status
 import org.junit.After
 import org.junit.Assume.assumeFalse
-import org.junit.Assume.assumeTrue
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
@@ -131,7 +129,7 @@
                 handlerThread.threadHandler,
                 iface.fileDescriptor.fileDescriptor,
                 MAX_PACKET_LENGTH)
-        handlerThread.threadHandler.post { reader.start() }
+        reader.startAsyncForTest()
         httpServer.start()
 
         // Pad the listening port to make sure it is always of length 5. This ensures the URL has
@@ -233,7 +231,7 @@
     timeoutMs: Long,
     type: Byte
 ): T {
-    val packetBytes = popPacket(timeoutMs, DhcpClientPacketFilter()
+    val packetBytes = poll(timeoutMs, DhcpClientPacketFilter()
             .and(DhcpOptionFilter(DHCP_MESSAGE_TYPE, type)))
             ?: fail("${packetType.simpleName} not received within timeout")
     val packet = DhcpPacket.decodeFullPacket(packetBytes, packetBytes.size, DhcpPacket.ENCAP_L2)
diff --git a/tests/cts/net/src/android/net/cts/NetworkValidationTestUtil.kt b/tests/cts/net/src/android/net/cts/NetworkValidationTestUtil.kt
index 5ef1854..f6fc75b 100644
--- a/tests/cts/net/src/android/net/cts/NetworkValidationTestUtil.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkValidationTestUtil.kt
@@ -19,9 +19,7 @@
 import android.Manifest
 import android.net.util.NetworkStackUtils
 import android.provider.DeviceConfig
-import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity
-import com.android.compatibility.common.util.ThrowingRunnable
-import kotlin.test.fail
+import com.android.testutils.runAsShell
 
 /**
  * Collection of utility methods for configuring network validation.
@@ -67,13 +65,4 @@
                     DeviceConfig.NAMESPACE_CONNECTIVITY, configKey, value, false /* makeDefault */)
         }
     }
-
-    /**
-     * Wrapper around runWithShellPermissionIdentity with kotlin-like syntax.
-     */
-    fun <T> runAsShell(vararg permissions: String, task: () -> T): T {
-        var ret: T? = null
-        runWithShellPermissionIdentity(ThrowingRunnable { ret = task() }, *permissions)
-        return ret ?: fail("ThrowingRunnable did not return")
-    }
 }
\ No newline at end of file
diff --git a/tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java b/tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java
deleted file mode 100644
index 8d7dff0..0000000
--- a/tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2011 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 android.net.http.cts;
-
-import org.apache.http.HttpResponse;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.DefaultHttpClient;
-
-import android.net.Uri;
-import android.platform.test.annotations.AppModeFull;
-import android.test.AndroidTestCase;
-import android.webkit.cts.CtsTestServer;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-
-@AppModeFull(reason = "Socket cannot bind in instant app mode")
-public class ApacheHttpClientTest extends AndroidTestCase {
-
-    private static final int NUM_DOWNLOADS = 20;
-
-    private static final int SMALL_DOWNLOAD_SIZE = 100 * 1024;
-
-    private CtsTestServer mWebServer;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mWebServer = new CtsTestServer(mContext);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        mWebServer.shutdown();
-    }
-
-    public void testExecute() throws Exception {
-        downloadMultipleFiles();
-    }
-
-    private void downloadMultipleFiles() throws ClientProtocolException, IOException {
-        List<HttpResponse> responses = new ArrayList<HttpResponse>();
-        for (int i = 0; i < NUM_DOWNLOADS; i++) {
-            HttpClient httpClient = new DefaultHttpClient();
-            HttpGet request = new HttpGet(getSmallDownloadUrl(i).toString());
-            HttpResponse response = httpClient.execute(request);
-            responses.add(response);
-        }
-
-        for (int i = 0; i < NUM_DOWNLOADS; i++) {
-            assertDownloadResponse("Download " + i, SMALL_DOWNLOAD_SIZE, responses.get(i));
-        }
-    }
-
-    private Uri getSmallDownloadUrl(int index) {
-        return Uri.parse(mWebServer.getTestDownloadUrl("cts-small-download-" + index,
-                SMALL_DOWNLOAD_SIZE));
-    }
-
-    private void assertDownloadResponse(String message, int expectedNumBytes, HttpResponse response)
-            throws IllegalStateException, IOException {
-        byte[] buffer = new byte[4096];
-        assertEquals(200, response.getStatusLine().getStatusCode());
-
-        InputStream stream = response.getEntity().getContent();
-        int numBytes = 0;
-        while (true) {
-            int bytesRead = stream.read(buffer);
-            if (bytesRead < 0) {
-                break;
-            } else {
-                numBytes += bytesRead;
-            }
-        }
-        assertEquals(message, expectedNumBytes, numBytes);
-    }
-}
diff --git a/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java b/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java
deleted file mode 100644
index 354954e..0000000
--- a/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2011 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 android.net.http.cts;
-
-import com.google.mockwebserver.MockResponse;
-import com.google.mockwebserver.MockWebServer;
-
-import junit.framework.TestCase;
-
-import android.net.http.HttpResponseCache;
-import android.platform.test.annotations.AppModeFull;
-
-import com.android.compatibility.common.util.FileUtils;
-
-import java.io.File;
-import java.io.InputStream;
-import java.net.CacheRequest;
-import java.net.CacheResponse;
-import java.net.ResponseCache;
-import java.net.URI;
-import java.net.URLConnection;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-public final class HttpResponseCacheTest extends TestCase {
-
-    private File cacheDir;
-    private MockWebServer server;
-
-    @Override public void setUp() throws Exception {
-        super.setUp();
-        server = new MockWebServer();
-        String tmp = System.getProperty("java.io.tmpdir");
-        cacheDir = new File(tmp, "HttpCache-" + UUID.randomUUID());
-        cacheDir.mkdirs();
-        // Make the cache directory read / writable.
-        FileUtils.setPermissions(cacheDir.getPath(), 0777);
-    }
-
-    @Override protected void tearDown() throws Exception {
-        ResponseCache.setDefault(null);
-        server.shutdown();
-        super.tearDown();
-    }
-
-    public void testInstall() throws Exception {
-        HttpResponseCache installed = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
-        assertNotNull(installed);
-        assertSame(installed, ResponseCache.getDefault());
-        assertSame(installed, HttpResponseCache.getDefault());
-    }
-
-    public void testSecondEquivalentInstallDoesNothing() throws Exception {
-        HttpResponseCache first = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
-        HttpResponseCache another = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
-        assertSame(first, another);
-    }
-
-    public void testInstallClosesPreviouslyInstalled() throws Exception {
-        HttpResponseCache first = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
-        initializeCache(first);
-
-        HttpResponseCache another = HttpResponseCache.install(cacheDir, 8 * 1024 * 1024);
-        initializeCache(first);
-
-        assertNotSame(first, another);
-        try {
-            first.flush();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-    }
-
-    public void testGetInstalledWithWrongTypeInstalled() {
-        ResponseCache.setDefault(new ResponseCache() {
-            @Override public CacheResponse get(URI uri, String requestMethod,
-                    Map<String, List<String>> requestHeaders) {
-                return null;
-            }
-            @Override public CacheRequest put(URI uri, URLConnection connection) {
-                return null;
-            }
-        });
-        assertNull(HttpResponseCache.getInstalled());
-    }
-
-    public void testCloseCloses() throws Exception {
-        HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
-        initializeCache(cache);
-
-        cache.close();
-        try {
-            cache.flush();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-    }
-
-    public void testCloseUninstalls() throws Exception {
-        HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
-        cache.close();
-        assertNull(ResponseCache.getDefault());
-    }
-
-    public void testDeleteUninstalls() throws Exception {
-        HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
-        cache.delete();
-        assertNull(ResponseCache.getDefault());
-    }
-
-    /**
-     * Make sure that statistics tracking are wired all the way through the
-     * wrapper class. http://code.google.com/p/android/issues/detail?id=25418
-     */
-    @AppModeFull(reason = "Socket cannot bind in instant app mode")
-    public void testStatisticsTracking() throws Exception {
-        HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
-
-        server.enqueue(new MockResponse()
-                .addHeader("Cache-Control: max-age=60")
-                .setBody("A"));
-        server.play();
-
-        URLConnection c1 = server.getUrl("/").openConnection();
-        InputStream inputStream1 = c1.getInputStream();
-        assertEquals('A', inputStream1.read());
-        inputStream1.close();
-
-        assertEquals(1, cache.getRequestCount());
-        assertEquals(1, cache.getNetworkCount());
-        assertEquals(0, cache.getHitCount());
-
-        URLConnection c2 = server.getUrl("/").openConnection();
-        assertEquals('A', c2.getInputStream().read());
-
-        URLConnection c3 = server.getUrl("/").openConnection();
-        assertEquals('A', c3.getInputStream().read());
-        assertEquals(3, cache.getRequestCount());
-        assertEquals(1, cache.getNetworkCount());
-        assertEquals(2, cache.getHitCount());
-    }
-
-    private void initializeCache(HttpResponseCache cache) {
-        // Ensure the cache is initialized, otherwise various methods are no-ops.
-        cache.size();
-    }
-}
diff --git a/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java b/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java
deleted file mode 100644
index 95f415c..0000000
--- a/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.net.http.cts;
-
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.Principal;
-import java.security.PublicKey;
-import java.security.SignatureException;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateExpiredException;
-import java.security.cert.CertificateNotYetValidException;
-import java.security.cert.X509Certificate;
-import java.text.DateFormat;
-import java.util.Date;
-import java.util.Set;
-
-import junit.framework.TestCase;
-import android.net.http.SslCertificate;
-import android.net.http.SslCertificate.DName;
-import android.os.Bundle;
-
-public class SslCertificateTest extends TestCase {
-
-    public void testConstructor() {
-        // new the SslCertificate instance
-        String date = DateFormat.getInstance().format(new Date());
-        new SslCertificate("c=129", "e=weji", date, date);
-
-        // new the SslCertificate instance
-        new SslCertificate(new MockX509Certificate());
-
-    }
-
-    class MockX509Certificate extends X509Certificate {
-
-        @Override
-        public void checkValidity() throws CertificateExpiredException,
-                CertificateNotYetValidException {
-        }
-
-        @Override
-        public void checkValidity(Date date) throws CertificateExpiredException,
-                CertificateNotYetValidException {
-        }
-
-        @Override
-        public int getBasicConstraints() {
-            return 0;
-        }
-
-        @Override
-        public Principal getIssuerDN() {
-            return new MockPrincipal();
-        }
-
-        @Override
-        public boolean[] getIssuerUniqueID() {
-            return null;
-        }
-
-        @Override
-        public boolean[] getKeyUsage() {
-            return null;
-        }
-
-        @Override
-        public Date getNotAfter() {
-            return new Date(System.currentTimeMillis());
-        }
-
-        @Override
-        public Date getNotBefore() {
-            return new Date(System.currentTimeMillis() - 1000);
-        }
-
-        @Override
-        public BigInteger getSerialNumber() {
-            return null;
-        }
-
-        @Override
-        public String getSigAlgName() {
-            return null;
-        }
-
-        @Override
-        public String getSigAlgOID() {
-            return null;
-        }
-
-        @Override
-        public byte[] getSigAlgParams() {
-            return null;
-        }
-
-        @Override
-        public byte[] getSignature() {
-            return null;
-        }
-
-        @Override
-        public Principal getSubjectDN() {
-            return new MockPrincipal();
-        }
-
-        class MockPrincipal implements Principal {
-            public String getName() {
-                return null;
-            }
-        }
-        @Override
-        public boolean[] getSubjectUniqueID() {
-            return null;
-        }
-
-        @Override
-        public byte[] getTBSCertificate() throws CertificateEncodingException {
-            return null;
-        }
-
-        @Override
-        public int getVersion() {
-            return 0;
-        }
-
-        @Override
-        public byte[] getEncoded() throws CertificateEncodingException {
-            return null;
-        }
-
-        @Override
-        public PublicKey getPublicKey() {
-            return null;
-        }
-
-        @Override
-        public String toString() {
-            return null;
-        }
-
-        @Override
-        public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException,
-                InvalidKeyException, NoSuchProviderException, SignatureException {
-        }
-
-        @Override
-        public void verify(PublicKey key, String sigProvider) throws CertificateException,
-                NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,
-                SignatureException {
-        }
-
-        public Set<String> getCriticalExtensionOIDs() {
-            return null;
-        }
-
-        public byte[] getExtensionValue(String oid) {
-            return null;
-        }
-
-        public Set<String> getNonCriticalExtensionOIDs() {
-            return null;
-        }
-
-        public boolean hasUnsupportedCriticalExtension() {
-            return false;
-        }
-    }
-
-    public void testState() {
-        // set the expected value
-
-        Date date1 = new Date(System.currentTimeMillis() - 1000);
-        Date date2 = new Date(System.currentTimeMillis());
-        SslCertificate ssl = new SslCertificate("c=129", "e=weji", date1, date2);
-        Bundle saved = SslCertificate.saveState(ssl);
-        assertTrue(saved.size() == 4);
-
-        assertNotNull(saved.getString("issued-to"));
-        assertNotNull(saved.getString("issued-by"));
-        assertNotNull(saved.getString("valid-not-before"));
-        assertNotNull(saved.getString("valid-not-after"));
-        assertNull(SslCertificate.saveState(null));
-
-        SslCertificate restored = SslCertificate.restoreState(saved);
-        assertEquals(ssl.getValidNotAfter(), restored.getValidNotAfter());
-        assertEquals(ssl.getValidNotBefore(), restored.getValidNotBefore());
-    }
-
-    public void testSslCertificate() {
-
-        final String TO = "c=ccc,o=testOName,ou=testUName,cn=testCName";
-        final String BY = "e=aeei,c=adb,o=testOName,ou=testUName,cn=testCName";
-        // new the SslCertificate instance
-        Date date1 = new Date(System.currentTimeMillis() - 1000);
-        Date date2 = new Date(System.currentTimeMillis());
-        SslCertificate ssl = new SslCertificate(TO, BY, date1, date2);
-        DName issuedTo = ssl.getIssuedTo();
-        DName issuedBy = ssl.getIssuedBy();
-
-        assertEquals("testCName", issuedTo.getCName());
-        assertEquals(TO, issuedTo.getDName());
-        assertEquals("testOName", issuedTo.getOName());
-        assertEquals("testUName", issuedTo.getUName());
-
-        assertEquals("testCName", issuedBy.getCName());
-        assertEquals(BY, issuedBy.getDName());
-        assertEquals("testOName", issuedBy.getOName());
-        assertEquals("testUName", issuedBy.getUName());
-
-        assertEquals(date1, ssl.getValidNotBeforeDate());
-        assertEquals(date2, ssl.getValidNotAfterDate());
-        final String EXPECTED = "Issued to: c=ccc,o=testOName,ou=testUName,cn=testCName;\n"
-            + "Issued by: e=aeei,c=adb,o=testOName,ou=testUName,cn=testCName;\n";
-        assertEquals(EXPECTED, ssl.toString());
-        assertNull(ssl.getX509Certificate());
-    }
-
-    public void testGetX509Certificate() {
-        final String TO = "c=ccc,o=testOName,ou=testUName,cn=testCName";
-        final String BY = "e=aeei,c=adb,o=testOName,ou=testUName,cn=testCName";
-        Date validNotBefore = new Date(System.currentTimeMillis() - 1000);
-        Date validNotAfter = new Date(System.currentTimeMillis());
-        SslCertificate ssl = new SslCertificate(TO, BY, validNotBefore, validNotAfter);
-        assertNull(ssl.getX509Certificate());
-
-        X509Certificate cert = new MockX509Certificate();
-        ssl = new SslCertificate(cert);
-        assertSame(cert, ssl.getX509Certificate());
-    }
-}
diff --git a/tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java b/tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java
deleted file mode 100644
index b0c71e8..0000000
--- a/tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.net.http.cts;
-
-import java.text.DateFormat;
-import java.util.Date;
-
-import junit.framework.TestCase;
-import android.net.http.SslCertificate;
-import android.net.http.SslCertificate.DName;
-
-public class SslCertificate_DNameTest extends TestCase {
-
-    public void testDName() {
-        final String TO = "c=ccc,o=testOName,ou=testUName,cn=testCName";
-        final String BY = "e=aeei,c=adb,o=testOName,ou=testUName,cn=testCName";
-        // new the SslCertificate instance
-        Date date1 = new Date(System.currentTimeMillis() - 1000);
-        Date date2 = new Date(System.currentTimeMillis());
-        SslCertificate ssl = new SslCertificate(TO, BY, DateFormat.getInstance().format(
-                date1), DateFormat.getInstance().format(date2));
-        DName issuedTo = ssl.getIssuedTo();
-
-        assertNotNull(issuedTo);
-
-        assertEquals("testCName", issuedTo.getCName());
-        assertEquals(TO, issuedTo.getDName());
-        assertEquals("testOName", issuedTo.getOName());
-        assertEquals("testUName", issuedTo.getUName());
-    }
-
-}
diff --git a/tests/cts/net/src/android/net/http/cts/SslErrorTest.java b/tests/cts/net/src/android/net/http/cts/SslErrorTest.java
deleted file mode 100644
index 0058c90..0000000
--- a/tests/cts/net/src/android/net/http/cts/SslErrorTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2011 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 android.net.http.cts;
-
-import android.net.http.SslCertificate;
-import android.net.http.SslError;
-
-
-import java.util.Date;
-
-import junit.framework.TestCase;
-
-public class SslErrorTest extends TestCase {
-    private SslCertificate mCertificate;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mCertificate = new SslCertificate("foo", "bar", new Date(42), new Date(43));
-    }
-
-    public void testHasError() {
-        SslError error = new SslError(SslError.SSL_EXPIRED, mCertificate);
-        assertTrue(error.hasError(SslError.SSL_EXPIRED));
-        assertFalse(error.hasError(SslError.SSL_UNTRUSTED));
-    }
-
-    public void testAddError() {
-        SslError error = new SslError(SslError.SSL_EXPIRED, mCertificate);
-        assertFalse(error.hasError(SslError.SSL_UNTRUSTED));
-        error.addError(SslError.SSL_UNTRUSTED);
-        assertTrue(error.hasError(SslError.SSL_UNTRUSTED));
-    }
-
-    public void testAddErrorIgnoresInvalidValues() {
-        SslError error = new SslError(SslError.SSL_EXPIRED, mCertificate);
-        error.addError(42);
-        assertFalse(error.hasError(42));
-    }
-
-    public void testConstructorIgnoresInvalidValues() {
-        SslError error = new SslError(42, mCertificate);
-        assertFalse(error.hasError(42));
-    }
-
-    public void testGetPrimaryError() {
-        SslError error = new SslError(SslError.SSL_EXPIRED, mCertificate);
-        error.addError(SslError.SSL_UNTRUSTED);
-        assertEquals(error.getPrimaryError(), SslError.SSL_UNTRUSTED);
-    }
-
-    public void testGetPrimaryErrorWithEmptySet() {
-        SslError error = new SslError(42, mCertificate);
-        assertEquals(error.getPrimaryError(), -1);
-    }
-
-    public void testGetUrl() {
-        SslError error = new SslError(SslError.SSL_EXPIRED, mCertificate, "foo");
-        assertEquals(error.getUrl(), "foo");
-    }
-
-    public void testGetUrlWithDeprecatedConstructor() {
-        SslError error = new SslError(SslError.SSL_EXPIRED, mCertificate);
-        assertEquals(error.getUrl(), "");
-    }
-
-    public void testGetCertificate() {
-        SslError error = new SslError(SslError.SSL_EXPIRED, mCertificate);
-        assertEquals(mCertificate, error.getCertificate());
-    }
-}
diff --git a/tests/cts/net/src/android/net/http/cts/X509TrustManagerExtensionsTest.java b/tests/cts/net/src/android/net/http/cts/X509TrustManagerExtensionsTest.java
deleted file mode 100644
index 99de614..0000000
--- a/tests/cts/net/src/android/net/http/cts/X509TrustManagerExtensionsTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2012 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 android.net.http.cts;
-
-import android.net.http.X509TrustManagerExtensions;
-
-import java.security.KeyStore;
-import java.security.cert.Certificate;
-import java.security.cert.X509Certificate;
-
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509TrustManager;
-
-import junit.framework.TestCase;
-
-public class X509TrustManagerExtensionsTest extends TestCase {
-
-    private static X509TrustManager getFirstX509TrustManager(TrustManagerFactory tmf)
-            throws Exception {
-        for (TrustManager trustManager : tmf.getTrustManagers()) {
-             if (trustManager instanceof X509TrustManager) {
-                 return (X509TrustManager) trustManager;
-             }
-        }
-        fail("Unable to find X509TrustManager");
-        return null;
-    }
-
-    public void testIsUserAddedCertificateDefaults() throws Exception {
-        final TrustManagerFactory tmf =
-                TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-        tmf.init((KeyStore) null);
-        X509TrustManager tm = getFirstX509TrustManager(tmf);
-        X509TrustManagerExtensions xtm = new X509TrustManagerExtensions(tm);
-        // Verify that all the default system provided CAs are not marked as user added.
-        for (Certificate cert : tm.getAcceptedIssuers()) {
-            assertFalse(xtm.isUserAddedCertificate((X509Certificate) cert));
-        }
-    }
-}
diff --git a/tests/cts/net/src/org/apache/http/conn/ssl/cts/AbstractVerifierTest.java b/tests/cts/net/src/org/apache/http/conn/ssl/cts/AbstractVerifierTest.java
deleted file mode 100644
index 5e2a55e..0000000
--- a/tests/cts/net/src/org/apache/http/conn/ssl/cts/AbstractVerifierTest.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Copyright (C) 2010 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 org.apache.http.conn.ssl.cts;
-
-import javax.security.auth.x500.X500Principal;
-import junit.framework.TestCase;
-
-import org.apache.http.conn.ssl.AbstractVerifier;
-
-import java.lang.Override;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.Principal;
-import java.security.PublicKey;
-import java.security.SignatureException;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateExpiredException;
-import java.security.cert.CertificateNotYetValidException;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.Set;
-
-/**
- * See also {@link libcore.javax.security.auth.x500.X500PrincipalTest} as it shows some cases
- * we are not checking as they are not allowed by the X500 principal in the first place.
- */
-public final class AbstractVerifierTest extends TestCase {
-
-    public void testGetCns() {
-        assertCns("");
-        assertCns("ou=xxx");
-        assertCns("ou=xxx,cn=xxx", "xxx");
-        assertCns("ou=xxx+cn=yyy,cn=zzz+cn=abc", "yyy", "zzz", "abc");
-        assertCns("cn=a,cn=b", "a", "b");
-        assertCns("cn=a   c,cn=b", "a   c", "b");
-        assertCns("cn=a   ,cn=b", "a", "b");
-        assertCns("cn=Cc,cn=Bb,cn=Aa", "Cc", "Bb", "Aa");
-        assertCns("cn=imap.gmail.com", "imap.gmail.com");
-        assertCns("l=\"abcn=a,b\", cn=c", "c");
-        assertCns("l=\"abcn=a,b\", cn=c", "c");
-        assertCns("l=\"abcn=a,b\", cn= c", "c");
-        assertCns("cn=<", "<");
-        assertCns("cn=>", ">");
-        assertCns("cn= >", ">");
-        assertCns("cn=a b", "a b");
-        assertCns("cn   =a b", "a b");
-        assertCns("Cn=a b", "a b");
-        assertCns("cN=a b", "a b");
-        assertCns("CN=a b", "a b");
-        assertCns("cn=a#b", "a#b");
-        assertCns("cn=#130161", "a");
-        assertCns("l=q\t+cn=p", "p");
-        assertCns("l=q\n+cn=p", "p");
-        assertCns("l=q\n,cn=p", "p");
-        assertCns("l=,cn=p", "p");
-        assertCns("l=\tq\n,cn=\tp", "\tp");
-    }
-
-    /** A cn=, generates an empty value, unless it's at the very end */
-    public void testEmptyValues() {
-        assertCns("l=,cn=+cn=q", "", "q");
-        assertCns("l=,cn=,cn=q", "", "q");
-        assertCns("l=,cn=");
-        assertCns("l=,cn=q,cn=   ", "q");
-        assertCns("l=,cn=q  ,cn=   ", "q");
-        assertCns("l=,cn=\"\"");
-        assertCns("l=,cn=\"  \",cn=\"  \"", "  ", "  ");
-        assertCns("l=,cn=  ,cn=  ","");
-        assertCns("l=,cn=,cn=  ,cn=  ", "", "");
-    }
-
-
-    public void testGetCns_escapedChars() {
-        assertCns("cn=\\,", ",");
-        assertCns("cn=\\#", "#");
-        assertCns("cn=\\+", "+");
-        assertCns("cn=\\\"", "\"");
-        assertCns("cn=\\\\", "\\");
-        assertCns("cn=\\<", "<");
-        assertCns("cn=\\>", ">");
-        assertCns("cn=\\;", ";");
-        assertCns("cn=\\+", "+");
-        assertCns("cn=\"\\+\"", "+");
-        assertCns("cn=\"\\,\"", ",");
-        assertCns("cn= a =", "a =");
-        assertCns("cn==", "=");
-    }
-
-    public void testGetCns_whitespace() {
-        assertCns("cn= p", "p");
-        assertCns("cn=\np", "p");
-        assertCns("cn=\tp", "\tp");
-    }
-
-    public void testGetCnsWithOid() {
-        assertCns("2.5.4.3=a,ou=xxx", "a");
-        assertCns("2.5.4.3=\" a \",ou=xxx", " a ");
-        assertCns("2.5.5.3=a,ou=xxx,cn=b", "b");
-    }
-
-    public void testGetCnsWithQuotedStrings() {
-        assertCns("cn=\"\\\" a ,=<>#;\"", "\" a ,=<>#;");
-        assertCns("cn=abc\\,def", "abc,def");
-        assertCns("cn=\"\\\" a ,\\=<>\\#;\"", "\" a ,=<>#;");
-    }
-
-    public void testGetCnsWithUtf8() {
-        assertCns("cn=\"Lu\\C4\\8Di\\C4\\87\"", "\u004c\u0075\u010d\u0069\u0107");
-        assertCns("cn=Lu\\C4\\8Di\\C4\\87", "\u004c\u0075\u010d\u0069\u0107");
-        assertCns("cn=Lu\\C4\\8di\\c4\\87", "\u004c\u0075\u010d\u0069\u0107");
-        assertCns("cn=\"Lu\\C4\\8di\\c4\\87\"", "\u004c\u0075\u010d\u0069\u0107");
-        assertCns("cn=\u004c\u0075\u010d\u0069\u0107", "\u004c\u0075\u010d\u0069\u0107");
-        // \63=c
-        assertExceptionInPrincipal("\\63n=ab");
-        assertExceptionInPrincipal("cn=\\a");
-    }
-
-    public void testGetCnsWithWhitespace() {
-        assertCns("ou=a, cn=  a  b  ,o=x", "a  b");
-        assertCns("cn=\"  a  b  \" ,o=x", "  a  b  ");
-    }
-
-    private static void assertCns(String dn, String... expected) {
-        String[] result = AbstractVerifier.getCNs(createStubCertificate(dn));
-        if (expected.length == 0) {
-            assertNull(result);
-        } else {
-            assertNotNull(dn, result);
-            assertEquals(dn, Arrays.asList(expected), Arrays.asList(result));
-        }
-    }
-
-    private static void assertExceptionInPrincipal(String dn) {
-        try {
-            X500Principal principal = new X500Principal(dn);
-            fail("Expected " + IllegalArgumentException.class.getName()
-                    + " because of incorrect input name");
-        } catch (IllegalArgumentException e) {
-            // Expected.
-        }
-    }
-
-    private static X509Certificate createStubCertificate(final String subjectName) {
-        return new X509Certificate() {
-            @Override
-            public X500Principal getSubjectX500Principal() {
-                return new X500Principal(subjectName);
-            }
-
-            @Override
-            public Set<String> getCriticalExtensionOIDs() {
-                return null;
-            }
-
-            @Override
-            public byte[] getExtensionValue(String oid) {
-                return new byte[0];
-            }
-
-            @Override
-            public Set<String> getNonCriticalExtensionOIDs() {
-                return null;
-            }
-
-            @Override
-            public boolean hasUnsupportedCriticalExtension() {
-                return false;
-            }
-
-            @Override
-            public byte[] getEncoded() throws CertificateEncodingException {
-                return new byte[0];
-            }
-
-            @Override
-            public void verify(PublicKey key)
-                    throws CertificateException, NoSuchAlgorithmException, InvalidKeyException,
-                    NoSuchProviderException, SignatureException {
-
-            }
-
-            @Override
-            public void verify(PublicKey key, String sigProvider)
-                    throws CertificateException, NoSuchAlgorithmException, InvalidKeyException,
-                    NoSuchProviderException, SignatureException {
-
-            }
-
-            @Override
-            public String toString() {
-                return null;
-            }
-
-            @Override
-            public PublicKey getPublicKey() {
-                return null;
-            }
-
-            @Override
-            public void checkValidity()
-                    throws CertificateExpiredException, CertificateNotYetValidException {
-
-            }
-
-            @Override
-            public void checkValidity(Date date)
-                    throws CertificateExpiredException, CertificateNotYetValidException {
-
-            }
-
-            @Override
-            public int getVersion() {
-                return 0;
-            }
-
-            @Override
-            public BigInteger getSerialNumber() {
-                return null;
-            }
-
-            @Override
-            public Principal getIssuerDN() {
-                return null;
-            }
-
-            @Override
-            public Principal getSubjectDN() {
-                return null;
-            }
-
-            @Override
-            public Date getNotBefore() {
-                return null;
-            }
-
-            @Override
-            public Date getNotAfter() {
-                return null;
-            }
-
-            @Override
-            public byte[] getTBSCertificate() throws CertificateEncodingException {
-                return new byte[0];
-            }
-
-            @Override
-            public byte[] getSignature() {
-                return new byte[0];
-            }
-
-            @Override
-            public String getSigAlgName() {
-                return null;
-            }
-
-            @Override
-            public String getSigAlgOID() {
-                return null;
-            }
-
-            @Override
-            public byte[] getSigAlgParams() {
-                return new byte[0];
-            }
-
-            @Override
-            public boolean[] getIssuerUniqueID() {
-                return new boolean[0];
-            }
-
-            @Override
-            public boolean[] getSubjectUniqueID() {
-                return new boolean[0];
-            }
-
-            @Override
-            public boolean[] getKeyUsage() {
-                return new boolean[0];
-            }
-
-            @Override
-            public int getBasicConstraints() {
-                return 0;
-            }
-        };
-    }
-}
-
diff --git a/tests/cts/net/util/Android.bp b/tests/cts/net/util/Android.bp
index 1f94613..c36d976 100644
--- a/tests/cts/net/util/Android.bp
+++ b/tests/cts/net/util/Android.bp
@@ -21,5 +21,6 @@
     static_libs: [
         "compatibility-device-util-axt",
         "junit",
+        "net-tests-utils",
     ],
 }
\ No newline at end of file
diff --git a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
index f1bc130..be0daae 100644
--- a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
+++ b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
@@ -23,10 +23,11 @@
 import static android.net.NetworkCapabilities.TRANSPORT_TEST;
 import static android.net.wifi.WifiManager.SCAN_RESULTS_AVAILABLE_ACTION;
 
-import static com.android.compatibility.common.util.ShellIdentityUtils.invokeWithShellPermissions;
+import static com.android.testutils.TestPermissionUtil.runAsShell;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -71,7 +72,6 @@
 import java.net.Socket;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
@@ -219,13 +219,18 @@
             if (config == null) {
                 // TODO: this may not clear the BSSID blacklist, as opposed to
                 // mWifiManager.connect(config)
-                SystemUtil.runWithShellPermissionIdentity(() -> mWifiManager.reconnect(),
-                        NETWORK_SETTINGS);
+                assertTrue("Error reconnecting wifi", runAsShell(NETWORK_SETTINGS,
+                        mWifiManager::reconnect));
             } else {
                 // When running CTS, devices are expected to have wifi networks pre-configured.
                 // This condition is only hit on virtual devices.
-                SystemUtil.runWithShellPermissionIdentity(
-                        () -> mWifiManager.connect(config, null /* listener */), NETWORK_SETTINGS);
+                final Integer error = runAsShell(NETWORK_SETTINGS, () -> {
+                    final ConnectWifiListener listener = new ConnectWifiListener();
+                    mWifiManager.connect(config, listener);
+                    return listener.connectFuture.get(
+                            CONNECTIVITY_CHANGE_TIMEOUT_SECS, TimeUnit.SECONDS);
+                });
+                assertNull("Error connecting to wifi: " + error, error);
             }
             // Ensure we get an onAvailable callback and possibly a CONNECTIVITY_ACTION.
             wifiNetwork = callback.waitForAvailable();
@@ -242,8 +247,24 @@
         return wifiNetwork;
     }
 
+    private static class ConnectWifiListener implements WifiManager.ActionListener {
+        /**
+         * Future completed when the connect process ends. Provides the error code or null if none.
+         */
+        final CompletableFuture<Integer> connectFuture = new CompletableFuture<>();
+        @Override
+        public void onSuccess() {
+            connectFuture.complete(null);
+        }
+
+        @Override
+        public void onFailure(int reason) {
+            connectFuture.complete(reason);
+        }
+    }
+
     private WifiConfiguration maybeAddVirtualWifiConfiguration() {
-        final List<WifiConfiguration> configs = invokeWithShellPermissions(
+        final List<WifiConfiguration> configs = runAsShell(NETWORK_SETTINGS,
                 mWifiManager::getConfiguredNetworks);
         // If no network is configured, add a config for virtual access points if applicable
         if (configs.size() == 0) {
@@ -259,7 +280,7 @@
 
     private List<ScanResult> getWifiScanResults() {
         final CompletableFuture<List<ScanResult>> scanResultsFuture = new CompletableFuture<>();
-        SystemUtil.runWithShellPermissionIdentity(() -> {
+        runAsShell(NETWORK_SETTINGS, () -> {
             final BroadcastReceiver receiver = new BroadcastReceiver() {
                 @Override
                 public void onReceive(Context context, Intent intent) {
@@ -296,7 +317,7 @@
         virtualConfig.SSID = "\"" + virtualScanResult.SSID + "\"";
         virtualConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
 
-        SystemUtil.runWithShellPermissionIdentity(() -> {
+        runAsShell(NETWORK_SETTINGS, () -> {
             final int networkId = mWifiManager.addNetwork(virtualConfig);
             assertTrue(networkId >= 0);
             assertTrue(mWifiManager.enableNetwork(networkId, false /* attemptConnect */));
@@ -310,7 +331,7 @@
      * to them.
      */
     private void clearWifiBlacklist() {
-        SystemUtil.runWithShellPermissionIdentity(() -> {
+        runAsShell(NETWORK_SETTINGS, () -> {
             for (WifiConfiguration cfg : mWifiManager.getConfiguredNetworks()) {
                 assertTrue(mWifiManager.enableNetwork(cfg.networkId, false /* attemptConnect */));
             }
diff --git a/tests/cts/net/util/java/android/net/cts/util/CtsTetheringUtils.java b/tests/cts/net/util/java/android/net/cts/util/CtsTetheringUtils.java
new file mode 100644
index 0000000..c95dc28
--- /dev/null
+++ b/tests/cts/net/util/java/android/net/cts/util/CtsTetheringUtils.java
@@ -0,0 +1,447 @@
+/*
+ * 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 android.net.cts.util;
+
+import static android.net.TetheringManager.TETHERING_WIFI;
+import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
+import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED;
+import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
+import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.net.Network;
+import android.net.TetheredClient;
+import android.net.TetheringManager;
+import android.net.TetheringManager.TetheringEventCallback;
+import android.net.TetheringManager.TetheringInterfaceRegexps;
+import android.net.TetheringManager.TetheringRequest;
+import android.net.wifi.WifiClient;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiManager.SoftApCallback;
+import android.os.ConditionVariable;
+
+import androidx.annotation.NonNull;
+
+import com.android.compatibility.common.util.SystemUtil;
+import com.android.net.module.util.ArrayTrackRecord;
+
+import java.util.Collection;
+import java.util.List;
+
+public final class CtsTetheringUtils {
+    private TetheringManager mTm;
+    private WifiManager mWm;
+    private Context mContext;
+
+    private static final int DEFAULT_TIMEOUT_MS = 60_000;
+
+    public CtsTetheringUtils(Context ctx) {
+        mContext = ctx;
+        mTm = mContext.getSystemService(TetheringManager.class);
+        mWm = mContext.getSystemService(WifiManager.class);
+    }
+
+    public static class StartTetheringCallback implements TetheringManager.StartTetheringCallback {
+        private static int TIMEOUT_MS = 30_000;
+        public static class CallbackValue {
+            public final int error;
+
+            private CallbackValue(final int e) {
+                error = e;
+            }
+
+            public static class OnTetheringStarted extends CallbackValue {
+                OnTetheringStarted() { super(TETHER_ERROR_NO_ERROR); }
+            }
+
+            public static class OnTetheringFailed extends CallbackValue {
+                OnTetheringFailed(final int error) { super(error); }
+            }
+
+            @Override
+            public String toString() {
+                return String.format("%s(%d)", getClass().getSimpleName(), error);
+            }
+        }
+
+        private final ArrayTrackRecord<CallbackValue>.ReadHead mHistory =
+                new ArrayTrackRecord<CallbackValue>().newReadHead();
+
+        @Override
+        public void onTetheringStarted() {
+            mHistory.add(new CallbackValue.OnTetheringStarted());
+        }
+
+        @Override
+        public void onTetheringFailed(final int error) {
+            mHistory.add(new CallbackValue.OnTetheringFailed(error));
+        }
+
+        public void verifyTetheringStarted() {
+            final CallbackValue cv = mHistory.poll(TIMEOUT_MS, c -> true);
+            assertNotNull("No onTetheringStarted after " + TIMEOUT_MS + " ms", cv);
+            assertTrue("Fail start tethering:" + cv,
+                    cv instanceof CallbackValue.OnTetheringStarted);
+        }
+
+        public void expectTetheringFailed(final int expected) throws InterruptedException {
+            final CallbackValue cv = mHistory.poll(TIMEOUT_MS, c -> true);
+            assertNotNull("No onTetheringFailed after " + TIMEOUT_MS + " ms", cv);
+            assertTrue("Expect fail with error code " + expected + ", but received: " + cv,
+                    (cv instanceof CallbackValue.OnTetheringFailed) && (cv.error == expected));
+        }
+    }
+
+    public static boolean isIfaceMatch(final List<String> ifaceRegexs, final List<String> ifaces) {
+        return isIfaceMatch(ifaceRegexs.toArray(new String[0]), ifaces);
+    }
+
+    public static boolean isIfaceMatch(final String[] ifaceRegexs, final List<String> ifaces) {
+        if (ifaceRegexs == null) fail("ifaceRegexs should not be null");
+
+        if (ifaces == null) return false;
+
+        for (String s : ifaces) {
+            for (String regex : ifaceRegexs) {
+                if (s.matches(regex)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    // Must poll the callback before looking at the member.
+    public static class TestTetheringEventCallback implements TetheringEventCallback {
+        private static final int TIMEOUT_MS = 30_000;
+
+        public enum CallbackType {
+            ON_SUPPORTED,
+            ON_UPSTREAM,
+            ON_TETHERABLE_REGEX,
+            ON_TETHERABLE_IFACES,
+            ON_TETHERED_IFACES,
+            ON_ERROR,
+            ON_CLIENTS,
+            ON_OFFLOAD_STATUS,
+        };
+
+        public static class CallbackValue {
+            public final CallbackType callbackType;
+            public final Object callbackParam;
+            public final int callbackParam2;
+
+            private CallbackValue(final CallbackType type, final Object param, final int param2) {
+                this.callbackType = type;
+                this.callbackParam = param;
+                this.callbackParam2 = param2;
+            }
+        }
+
+        private final ArrayTrackRecord<CallbackValue> mHistory =
+                new ArrayTrackRecord<CallbackValue>();
+
+        private final ArrayTrackRecord<CallbackValue>.ReadHead mCurrent =
+                mHistory.newReadHead();
+
+        private TetheringInterfaceRegexps mTetherableRegex;
+        private List<String> mTetherableIfaces;
+        private List<String> mTetheredIfaces;
+
+        @Override
+        public void onTetheringSupported(boolean supported) {
+            mHistory.add(new CallbackValue(CallbackType.ON_SUPPORTED, null, (supported ? 1 : 0)));
+        }
+
+        @Override
+        public void onUpstreamChanged(Network network) {
+            mHistory.add(new CallbackValue(CallbackType.ON_UPSTREAM, network, 0));
+        }
+
+        @Override
+        public void onTetherableInterfaceRegexpsChanged(TetheringInterfaceRegexps reg) {
+            mTetherableRegex = reg;
+            mHistory.add(new CallbackValue(CallbackType.ON_TETHERABLE_REGEX, reg, 0));
+        }
+
+        @Override
+        public void onTetherableInterfacesChanged(List<String> interfaces) {
+            mTetherableIfaces = interfaces;
+            mHistory.add(new CallbackValue(CallbackType.ON_TETHERABLE_IFACES, interfaces, 0));
+        }
+
+        @Override
+        public void onTetheredInterfacesChanged(List<String> interfaces) {
+            mTetheredIfaces = interfaces;
+            mHistory.add(new CallbackValue(CallbackType.ON_TETHERED_IFACES, interfaces, 0));
+        }
+
+        @Override
+        public void onError(String ifName, int error) {
+            mHistory.add(new CallbackValue(CallbackType.ON_ERROR, ifName, error));
+        }
+
+        @Override
+        public void onClientsChanged(Collection<TetheredClient> clients) {
+            mHistory.add(new CallbackValue(CallbackType.ON_CLIENTS, clients, 0));
+        }
+
+        @Override
+        public void onOffloadStatusChanged(int status) {
+            mHistory.add(new CallbackValue(CallbackType.ON_OFFLOAD_STATUS, status, 0));
+        }
+
+        public void expectTetherableInterfacesChanged(@NonNull List<String> regexs) {
+            assertNotNull("No expected tetherable ifaces callback", mCurrent.poll(TIMEOUT_MS,
+                (cv) -> {
+                    if (cv.callbackType != CallbackType.ON_TETHERABLE_IFACES) return false;
+                    final List<String> interfaces = (List<String>) cv.callbackParam;
+                    return isIfaceMatch(regexs, interfaces);
+                }));
+        }
+
+        public void expectTetheredInterfacesChanged(@NonNull List<String> regexs) {
+            assertNotNull("No expected tethered ifaces callback", mCurrent.poll(TIMEOUT_MS,
+                (cv) -> {
+                    if (cv.callbackType != CallbackType.ON_TETHERED_IFACES) return false;
+
+                    final List<String> interfaces = (List<String>) cv.callbackParam;
+
+                    // Null regexs means no active tethering.
+                    if (regexs == null) return interfaces.isEmpty();
+
+                    return isIfaceMatch(regexs, interfaces);
+                }));
+        }
+
+        public void expectCallbackStarted() {
+            int receivedBitMap = 0;
+            // The each bit represent a type from CallbackType.ON_*.
+            // Expect all of callbacks except for ON_ERROR.
+            final int expectedBitMap = 0xff ^ (1 << CallbackType.ON_ERROR.ordinal());
+            // Receive ON_ERROR on started callback is not matter. It just means tethering is
+            // failed last time, should able to continue the test this time.
+            while ((receivedBitMap & expectedBitMap) != expectedBitMap) {
+                final CallbackValue cv = mCurrent.poll(TIMEOUT_MS, c -> true);
+                if (cv == null) {
+                    fail("No expected callbacks, " + "expected bitmap: "
+                            + expectedBitMap + ", actual: " + receivedBitMap);
+                }
+
+                receivedBitMap |= (1 << cv.callbackType.ordinal());
+            }
+        }
+
+        public void expectOneOfOffloadStatusChanged(int... offloadStatuses) {
+            assertNotNull("No offload status changed", mCurrent.poll(TIMEOUT_MS, (cv) -> {
+                if (cv.callbackType != CallbackType.ON_OFFLOAD_STATUS) return false;
+
+                final int status = (int) cv.callbackParam;
+                for (int offloadStatus : offloadStatuses) {
+                    if (offloadStatus == status) return true;
+                }
+
+                return false;
+            }));
+        }
+
+        public void expectErrorOrTethered(final String iface) {
+            assertNotNull("No expected callback", mCurrent.poll(TIMEOUT_MS, (cv) -> {
+                if (cv.callbackType == CallbackType.ON_ERROR
+                        && iface.equals((String) cv.callbackParam)) {
+                    return true;
+                }
+                if (cv.callbackType == CallbackType.ON_TETHERED_IFACES
+                        && ((List<String>) cv.callbackParam).contains(iface)) {
+                    return true;
+                }
+
+                return false;
+            }));
+        }
+
+        public Network getCurrentValidUpstream() {
+            final CallbackValue result = mCurrent.poll(TIMEOUT_MS, (cv) -> {
+                return (cv.callbackType == CallbackType.ON_UPSTREAM)
+                        && cv.callbackParam != null;
+            });
+
+            assertNotNull("No valid upstream", result);
+            return (Network) result.callbackParam;
+        }
+
+        public void assumeTetheringSupported() {
+            final ArrayTrackRecord<CallbackValue>.ReadHead history =
+                    mHistory.newReadHead();
+            assertNotNull("No onSupported callback", history.poll(TIMEOUT_MS, (cv) -> {
+                if (cv.callbackType != CallbackType.ON_SUPPORTED) return false;
+
+                assumeTrue(cv.callbackParam2 == 1 /* supported */);
+                return true;
+            }));
+        }
+
+        public void assumeWifiTetheringSupported(final Context ctx) throws Exception {
+            assumeTetheringSupported();
+
+            assumeTrue(!getTetheringInterfaceRegexps().getTetherableWifiRegexs().isEmpty());
+
+            final PackageManager pm = ctx.getPackageManager();
+            assumeTrue(pm.hasSystemFeature(PackageManager.FEATURE_WIFI));
+
+            WifiManager wm = ctx.getSystemService(WifiManager.class);
+            // Wifi feature flags only work when wifi is on.
+            final boolean previousWifiEnabledState = wm.isWifiEnabled();
+            try {
+                if (!previousWifiEnabledState) SystemUtil.runShellCommand("svc wifi enable");
+                waitForWifiEnabled(ctx);
+                assumeTrue(wm.isPortableHotspotSupported());
+            } finally {
+                if (!previousWifiEnabledState) SystemUtil.runShellCommand("svc wifi disable");
+            }
+        }
+
+        public TetheringInterfaceRegexps getTetheringInterfaceRegexps() {
+            return mTetherableRegex;
+        }
+
+        public List<String> getTetherableInterfaces() {
+            return mTetherableIfaces;
+        }
+
+        public List<String> getTetheredInterfaces() {
+            return mTetheredIfaces;
+        }
+    }
+
+    private static void waitForWifiEnabled(final Context ctx) throws Exception {
+        WifiManager wm = ctx.getSystemService(WifiManager.class);
+        if (wm.isWifiEnabled()) return;
+
+        final ConditionVariable mWaiting = new ConditionVariable();
+        final BroadcastReceiver receiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                String action = intent.getAction();
+                if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
+                    if (wm.isWifiEnabled()) mWaiting.open();
+                }
+            }
+        };
+        try {
+            ctx.registerReceiver(receiver, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));
+            if (!mWaiting.block(DEFAULT_TIMEOUT_MS)) {
+                assertTrue("Wifi did not become enabled after " + DEFAULT_TIMEOUT_MS + "ms",
+                        wm.isWifiEnabled());
+            }
+        } finally {
+            ctx.unregisterReceiver(receiver);
+        }
+    }
+
+    public TestTetheringEventCallback registerTetheringEventCallback() {
+        final TestTetheringEventCallback tetherEventCallback =
+                new TestTetheringEventCallback();
+
+        mTm.registerTetheringEventCallback(c -> c.run() /* executor */, tetherEventCallback);
+        tetherEventCallback.expectCallbackStarted();
+
+        return tetherEventCallback;
+    }
+
+    public void unregisterTetheringEventCallback(final TestTetheringEventCallback callback) {
+        mTm.unregisterTetheringEventCallback(callback);
+    }
+
+    private static List<String> getWifiTetherableInterfaceRegexps(
+            final TestTetheringEventCallback callback) {
+        return callback.getTetheringInterfaceRegexps().getTetherableWifiRegexs();
+    }
+
+    public static boolean isWifiTetheringSupported(final TestTetheringEventCallback callback) {
+        return !getWifiTetherableInterfaceRegexps(callback).isEmpty();
+    }
+
+    public void startWifiTethering(final TestTetheringEventCallback callback)
+            throws InterruptedException {
+        final List<String> wifiRegexs = getWifiTetherableInterfaceRegexps(callback);
+        assertFalse(isIfaceMatch(wifiRegexs, callback.getTetheredInterfaces()));
+
+        final StartTetheringCallback startTetheringCallback = new StartTetheringCallback();
+        final TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI)
+                .setShouldShowEntitlementUi(false).build();
+        mTm.startTethering(request, c -> c.run() /* executor */, startTetheringCallback);
+        startTetheringCallback.verifyTetheringStarted();
+
+        callback.expectTetheredInterfacesChanged(wifiRegexs);
+
+        callback.expectOneOfOffloadStatusChanged(
+                TETHER_HARDWARE_OFFLOAD_STARTED,
+                TETHER_HARDWARE_OFFLOAD_FAILED);
+    }
+
+    private static class StopSoftApCallback implements SoftApCallback {
+        private final ConditionVariable mWaiting = new ConditionVariable();
+        @Override
+        public void onStateChanged(int state, int failureReason) {
+            if (state == WifiManager.WIFI_AP_STATE_DISABLED) mWaiting.open();
+        }
+
+        @Override
+        public void onConnectedClientsChanged(List<WifiClient> clients) { }
+
+        public void waitForSoftApStopped() {
+            if (!mWaiting.block(DEFAULT_TIMEOUT_MS)) {
+                fail("stopSoftAp Timeout");
+            }
+        }
+    }
+
+    // Wait for softAp to be disabled. This is necessary on devices where stopping softAp
+    // deletes the interface. On these devices, tethering immediately stops when the softAp
+    // interface is removed, but softAp is not yet fully disabled. Wait for softAp to be
+    // fully disabled, because otherwise the next test might fail because it attempts to
+    // start softAp before it's fully stopped.
+    public void expectSoftApDisabled() {
+        final StopSoftApCallback callback = new StopSoftApCallback();
+        try {
+            mWm.registerSoftApCallback(c -> c.run(), callback);
+            // registerSoftApCallback will immediately call the callback with the current state, so
+            // this callback will fire even if softAp is already disabled.
+            callback.waitForSoftApStopped();
+        } finally {
+            mWm.unregisterSoftApCallback(callback);
+        }
+    }
+
+    public void stopWifiTethering(final TestTetheringEventCallback callback) {
+        mTm.stopTethering(TETHERING_WIFI);
+        expectSoftApDisabled();
+        callback.expectTetheredInterfacesChanged(null);
+        callback.expectOneOfOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
+    }
+}
diff --git a/tests/cts/tethering/AndroidManifest.xml b/tests/cts/tethering/AndroidManifest.xml
index 665002e..911dbf2 100644
--- a/tests/cts/tethering/AndroidManifest.xml
+++ b/tests/cts/tethering/AndroidManifest.xml
@@ -19,6 +19,7 @@
     package="android.tethering.cts">
 
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
 
     <application android:debuggable="true">
         <uses-library android:name="android.test.runner" />
diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
index 92dca39..71a81ff 100644
--- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
+++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
@@ -26,9 +26,8 @@
 import static android.net.TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN;
 import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION;
 import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
-import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED;
-import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
-import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
+import static android.net.cts.util.CtsTetheringUtils.isIfaceMatch;
+import static android.net.cts.util.CtsTetheringUtils.isWifiTetheringSupported;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -49,31 +48,26 @@
 import android.net.LinkAddress;
 import android.net.Network;
 import android.net.NetworkCapabilities;
-import android.net.TetheredClient;
 import android.net.TetheringManager;
 import android.net.TetheringManager.OnTetheringEntitlementResultListener;
-import android.net.TetheringManager.TetheringEventCallback;
 import android.net.TetheringManager.TetheringInterfaceRegexps;
 import android.net.TetheringManager.TetheringRequest;
 import android.net.cts.util.CtsNetUtils;
 import android.net.cts.util.CtsNetUtils.TestNetworkCallback;
-import android.net.wifi.WifiClient;
+import android.net.cts.util.CtsTetheringUtils;
+import android.net.cts.util.CtsTetheringUtils.StartTetheringCallback;
+import android.net.cts.util.CtsTetheringUtils.TestTetheringEventCallback;
 import android.net.wifi.WifiManager;
-import android.net.wifi.WifiManager.SoftApCallback;
 import android.os.Bundle;
-import android.os.ConditionVariable;
 import android.os.PersistableBundle;
 import android.os.ResultReceiver;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 
-import androidx.annotation.NonNull;
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.net.module.util.ArrayTrackRecord;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -81,7 +75,6 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.LinkedBlockingQueue;
@@ -100,6 +93,7 @@
 
     private TetherChangeReceiver mTetherChangeReceiver;
     private CtsNetUtils mCtsNetUtils;
+    private CtsTetheringUtils mCtsTetheringUtils;
 
     private static final int DEFAULT_TIMEOUT_MS = 60_000;
 
@@ -124,6 +118,7 @@
         mWm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
         mPm = mContext.getPackageManager();
         mCtsNetUtils = new CtsNetUtils(mContext);
+        mCtsTetheringUtils = new CtsTetheringUtils(mContext);
         mTetherChangeReceiver = new TetherChangeReceiver();
         final IntentFilter filter = new IntentFilter(
                 TetheringManager.ACTION_TETHER_STATE_CHANGED);
@@ -138,40 +133,6 @@
         dropShellPermissionIdentity();
     }
 
-    private static class StopSoftApCallback implements SoftApCallback {
-        private final ConditionVariable mWaiting = new ConditionVariable();
-        @Override
-        public void onStateChanged(int state, int failureReason) {
-            if (state == WifiManager.WIFI_AP_STATE_DISABLED) mWaiting.open();
-        }
-
-        @Override
-        public void onConnectedClientsChanged(List<WifiClient> clients) { }
-
-        public void waitForSoftApStopped() {
-            if (!mWaiting.block(DEFAULT_TIMEOUT_MS)) {
-                fail("stopSoftAp Timeout");
-            }
-        }
-    }
-
-    // Wait for softAp to be disabled. This is necessary on devices where stopping softAp
-    // deletes the interface. On these devices, tethering immediately stops when the softAp
-    // interface is removed, but softAp is not yet fully disabled. Wait for softAp to be
-    // fully disabled, because otherwise the next test might fail because it attempts to
-    // start softAp before it's fully stopped.
-    private void expectSoftApDisabled() {
-        final StopSoftApCallback callback = new StopSoftApCallback();
-        try {
-            mWm.registerSoftApCallback(c -> c.run(), callback);
-            // registerSoftApCallback will immediately call the callback with the current state, so
-            // this callback will fire even if softAp is already disabled.
-            callback.waitForSoftApStopped();
-        } finally {
-            mWm.unregisterSoftApCallback(callback);
-        }
-    }
-
     private class TetherChangeReceiver extends BroadcastReceiver {
         private class TetherState {
             final ArrayList<String> mAvailable;
@@ -241,87 +202,17 @@
         }
     }
 
-    private static class StartTetheringCallback implements TetheringManager.StartTetheringCallback {
-        private static int TIMEOUT_MS = 30_000;
-        public static class CallbackValue {
-            public final int error;
-
-            private CallbackValue(final int e) {
-                error = e;
-            }
-
-            public static class OnTetheringStarted extends CallbackValue {
-                OnTetheringStarted() { super(TETHER_ERROR_NO_ERROR); }
-            }
-
-            public static class OnTetheringFailed extends CallbackValue {
-                OnTetheringFailed(final int error) { super(error); }
-            }
-
-            @Override
-            public String toString() {
-                return String.format("%s(%d)", getClass().getSimpleName(), error);
-            }
-        }
-
-        private final ArrayTrackRecord<CallbackValue>.ReadHead mHistory =
-                new ArrayTrackRecord<CallbackValue>().newReadHead();
-
-        @Override
-        public void onTetheringStarted() {
-            mHistory.add(new CallbackValue.OnTetheringStarted());
-        }
-
-        @Override
-        public void onTetheringFailed(final int error) {
-            mHistory.add(new CallbackValue.OnTetheringFailed(error));
-        }
-
-        public void verifyTetheringStarted() {
-            final CallbackValue cv = mHistory.poll(TIMEOUT_MS, c -> true);
-            assertNotNull("No onTetheringStarted after " + TIMEOUT_MS + " ms", cv);
-            assertTrue("Fail start tethering:" + cv,
-                    cv instanceof CallbackValue.OnTetheringStarted);
-        }
-
-        public void expectTetheringFailed(final int expected) throws InterruptedException {
-            final CallbackValue cv = mHistory.poll(TIMEOUT_MS, c -> true);
-            assertNotNull("No onTetheringFailed after " + TIMEOUT_MS + " ms", cv);
-            assertTrue("Expect fail with error code " + expected + ", but received: " + cv,
-                (cv instanceof CallbackValue.OnTetheringFailed) && (cv.error == expected));
-        }
-    }
-
-    private static boolean isIfaceMatch(final List<String> ifaceRegexs,
-            final List<String> ifaces) {
-        return isIfaceMatch(ifaceRegexs.toArray(new String[0]), ifaces);
-    }
-
-    private static boolean isIfaceMatch(final String[] ifaceRegexs, final List<String> ifaces) {
-        if (ifaceRegexs == null) fail("ifaceRegexs should not be null");
-
-        if (ifaces == null) return false;
-
-        for (String s : ifaces) {
-            for (String regex : ifaceRegexs) {
-                if (s.matches(regex)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
     @Test
     public void testStartTetheringWithStateChangeBroadcast() throws Exception {
-        if (!mTM.isTetheringSupported()) return;
+        final TestTetheringEventCallback tetherEventCallback =
+                mCtsTetheringUtils.registerTetheringEventCallback();
+        try {
+            tetherEventCallback.assumeWifiTetheringSupported(mContext);
+        } finally {
+            mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
+        }
 
         final String[] wifiRegexs = mTM.getTetherableWifiRegexs();
-        if (wifiRegexs.length == 0) return;
-
-        final String[] tetheredIfaces = mTM.getTetheredIfaces();
-        assertTrue(tetheredIfaces.length == 0);
-
         final StartTetheringCallback startTetheringCallback = new StartTetheringCallback();
         final TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI)
                 .setShouldShowEntitlementUi(false).build();
@@ -331,7 +222,7 @@
         mTetherChangeReceiver.expectTethering(true /* active */, wifiRegexs);
 
         mTM.stopTethering(TETHERING_WIFI);
-        expectSoftApDisabled();
+        mCtsTetheringUtils.expectSoftApDisabled();
         mTetherChangeReceiver.expectTethering(false /* active */, wifiRegexs);
     }
 
@@ -358,272 +249,43 @@
         assertFalse(tr2.getShouldShowEntitlementUi());
     }
 
-    // Must poll the callback before looking at the member.
-    private static class TestTetheringEventCallback implements TetheringEventCallback {
-        private static final int TIMEOUT_MS = 30_000;
-
-        public enum CallbackType {
-            ON_SUPPORTED,
-            ON_UPSTREAM,
-            ON_TETHERABLE_REGEX,
-            ON_TETHERABLE_IFACES,
-            ON_TETHERED_IFACES,
-            ON_ERROR,
-            ON_CLIENTS,
-            ON_OFFLOAD_STATUS,
-        };
-
-        public static class CallbackValue {
-            public final CallbackType callbackType;
-            public final Object callbackParam;
-            public final int callbackParam2;
-
-            private CallbackValue(final CallbackType type, final Object param, final int param2) {
-                this.callbackType = type;
-                this.callbackParam = param;
-                this.callbackParam2 = param2;
-            }
-        }
-
-        private final ArrayTrackRecord<CallbackValue> mHistory =
-                new ArrayTrackRecord<CallbackValue>();
-
-        private final ArrayTrackRecord<CallbackValue>.ReadHead mCurrent =
-                mHistory.newReadHead();
-
-        private TetheringInterfaceRegexps mTetherableRegex;
-        private List<String> mTetherableIfaces;
-        private List<String> mTetheredIfaces;
-
-        @Override
-        public void onTetheringSupported(boolean supported) {
-            mHistory.add(new CallbackValue(CallbackType.ON_SUPPORTED, null, (supported ? 1 : 0)));
-        }
-
-        @Override
-        public void onUpstreamChanged(Network network) {
-            mHistory.add(new CallbackValue(CallbackType.ON_UPSTREAM, network, 0));
-        }
-
-        @Override
-        public void onTetherableInterfaceRegexpsChanged(TetheringInterfaceRegexps reg) {
-            mTetherableRegex = reg;
-            mHistory.add(new CallbackValue(CallbackType.ON_TETHERABLE_REGEX, reg, 0));
-        }
-
-        @Override
-        public void onTetherableInterfacesChanged(List<String> interfaces) {
-            mTetherableIfaces = interfaces;
-            mHistory.add(new CallbackValue(CallbackType.ON_TETHERABLE_IFACES, interfaces, 0));
-        }
-
-        @Override
-        public void onTetheredInterfacesChanged(List<String> interfaces) {
-            mTetheredIfaces = interfaces;
-            mHistory.add(new CallbackValue(CallbackType.ON_TETHERED_IFACES, interfaces, 0));
-        }
-
-        @Override
-        public void onError(String ifName, int error) {
-            mHistory.add(new CallbackValue(CallbackType.ON_ERROR, ifName, error));
-        }
-
-        @Override
-        public void onClientsChanged(Collection<TetheredClient> clients) {
-            mHistory.add(new CallbackValue(CallbackType.ON_CLIENTS, clients, 0));
-        }
-
-        @Override
-        public void onOffloadStatusChanged(int status) {
-            mHistory.add(new CallbackValue(CallbackType.ON_OFFLOAD_STATUS, status, 0));
-        }
-
-        public void expectTetherableInterfacesChanged(@NonNull List<String> regexs) {
-            assertNotNull("No expected tetherable ifaces callback", mCurrent.poll(TIMEOUT_MS,
-                (cv) -> {
-                    if (cv.callbackType != CallbackType.ON_TETHERABLE_IFACES) return false;
-                    final List<String> interfaces = (List<String>) cv.callbackParam;
-                    return isIfaceMatch(regexs, interfaces);
-                }));
-        }
-
-        public void expectTetheredInterfacesChanged(@NonNull List<String> regexs) {
-            assertNotNull("No expected tethered ifaces callback", mCurrent.poll(TIMEOUT_MS,
-                (cv) -> {
-                    if (cv.callbackType != CallbackType.ON_TETHERED_IFACES) return false;
-
-                    final List<String> interfaces = (List<String>) cv.callbackParam;
-
-                    // Null regexs means no active tethering.
-                    if (regexs == null) return interfaces.isEmpty();
-
-                    return isIfaceMatch(regexs, interfaces);
-                }));
-        }
-
-        public void expectCallbackStarted() {
-            int receivedBitMap = 0;
-            // The each bit represent a type from CallbackType.ON_*.
-            // Expect all of callbacks except for ON_ERROR.
-            final int expectedBitMap = 0xff ^ (1 << CallbackType.ON_ERROR.ordinal());
-            // Receive ON_ERROR on started callback is not matter. It just means tethering is
-            // failed last time, should able to continue the test this time.
-            while ((receivedBitMap & expectedBitMap) != expectedBitMap) {
-                final CallbackValue cv = mCurrent.poll(TIMEOUT_MS, c -> true);
-                if (cv == null) {
-                    fail("No expected callbacks, " + "expected bitmap: "
-                            + expectedBitMap + ", actual: " + receivedBitMap);
-                }
-
-                receivedBitMap |= (1 << cv.callbackType.ordinal());
-            }
-        }
-
-        public void expectOneOfOffloadStatusChanged(int... offloadStatuses) {
-            assertNotNull("No offload status changed", mCurrent.poll(TIMEOUT_MS, (cv) -> {
-                if (cv.callbackType != CallbackType.ON_OFFLOAD_STATUS) return false;
-
-                final int status = (int) cv.callbackParam;
-                for (int offloadStatus : offloadStatuses) if (offloadStatus == status) return true;
-
-                return false;
-            }));
-        }
-
-        public void expectErrorOrTethered(final String iface) {
-            assertNotNull("No expected callback", mCurrent.poll(TIMEOUT_MS, (cv) -> {
-                if (cv.callbackType == CallbackType.ON_ERROR
-                        && iface.equals((String) cv.callbackParam)) {
-                    return true;
-                }
-                if (cv.callbackType == CallbackType.ON_TETHERED_IFACES
-                        && ((List<String>) cv.callbackParam).contains(iface)) {
-                    return true;
-                }
-
-                return false;
-            }));
-        }
-
-        public Network getCurrentValidUpstream() {
-            final CallbackValue result = mCurrent.poll(TIMEOUT_MS, (cv) -> {
-                return (cv.callbackType == CallbackType.ON_UPSTREAM)
-                        && cv.callbackParam != null;
-            });
-
-            assertNotNull("No valid upstream", result);
-            return (Network) result.callbackParam;
-        }
-
-        public void assumeTetheringSupported() {
-            final ArrayTrackRecord<CallbackValue>.ReadHead history =
-                    mHistory.newReadHead();
-            assertNotNull("No onSupported callback", history.poll(TIMEOUT_MS, (cv) -> {
-                if (cv.callbackType != CallbackType.ON_SUPPORTED) return false;
-
-                assumeTrue(cv.callbackParam2 == 1 /* supported */);
-                return true;
-            }));
-        }
-
-        public TetheringInterfaceRegexps getTetheringInterfaceRegexps() {
-            return mTetherableRegex;
-        }
-
-        public List<String> getTetherableInterfaces() {
-            return mTetherableIfaces;
-        }
-
-        public List<String> getTetheredInterfaces() {
-            return mTetheredIfaces;
-        }
-    }
-
-    private TestTetheringEventCallback registerTetheringEventCallback() {
-        final TestTetheringEventCallback tetherEventCallback =
-                new TestTetheringEventCallback();
-
-        mTM.registerTetheringEventCallback(c -> c.run() /* executor */, tetherEventCallback);
-        tetherEventCallback.expectCallbackStarted();
-
-        return tetherEventCallback;
-    }
-
-    private void unregisterTetheringEventCallback(final TestTetheringEventCallback callback) {
-        mTM.unregisterTetheringEventCallback(callback);
-    }
-
-    private List<String> getWifiTetherableInterfaceRegexps(
-            final TestTetheringEventCallback callback) {
-        return callback.getTetheringInterfaceRegexps().getTetherableWifiRegexs();
-    }
-
-    private boolean isWifiTetheringSupported(final TestTetheringEventCallback callback) {
-        return !getWifiTetherableInterfaceRegexps(callback).isEmpty();
-    }
-
-    private void startWifiTethering(final TestTetheringEventCallback callback)
-            throws InterruptedException {
-        final List<String> wifiRegexs = getWifiTetherableInterfaceRegexps(callback);
-        assertFalse(isIfaceMatch(wifiRegexs, callback.getTetheredInterfaces()));
-
-        final StartTetheringCallback startTetheringCallback = new StartTetheringCallback();
-        final TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI)
-                .setShouldShowEntitlementUi(false).build();
-        mTM.startTethering(request, c -> c.run() /* executor */, startTetheringCallback);
-        startTetheringCallback.verifyTetheringStarted();
-
-        callback.expectTetheredInterfacesChanged(wifiRegexs);
-
-        callback.expectOneOfOffloadStatusChanged(
-                TETHER_HARDWARE_OFFLOAD_STARTED,
-                TETHER_HARDWARE_OFFLOAD_FAILED);
-    }
-
-    private void stopWifiTethering(final TestTetheringEventCallback callback) {
-        mTM.stopTethering(TETHERING_WIFI);
-        expectSoftApDisabled();
-        callback.expectTetheredInterfacesChanged(null);
-        callback.expectOneOfOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
-    }
-
     @Test
     public void testRegisterTetheringEventCallback() throws Exception {
-        final TestTetheringEventCallback tetherEventCallback = registerTetheringEventCallback();
-        tetherEventCallback.assumeTetheringSupported();
-
-        if (!isWifiTetheringSupported(tetherEventCallback)) {
-            unregisterTetheringEventCallback(tetherEventCallback);
-            return;
-        }
-
-        startWifiTethering(tetherEventCallback);
-
-        final List<String> tetheredIfaces = tetherEventCallback.getTetheredInterfaces();
-        assertEquals(1, tetheredIfaces.size());
-        final String wifiTetheringIface = tetheredIfaces.get(0);
-
-        stopWifiTethering(tetherEventCallback);
+        final TestTetheringEventCallback tetherEventCallback =
+                mCtsTetheringUtils.registerTetheringEventCallback();
 
         try {
-            final int ret = mTM.tether(wifiTetheringIface);
+            tetherEventCallback.assumeWifiTetheringSupported(mContext);
 
-            // There is no guarantee that the wifi interface will be available after disabling
-            // the hotspot, so don't fail the test if the call to tether() fails.
-            assumeTrue(ret == TETHER_ERROR_NO_ERROR);
+            mCtsTetheringUtils.startWifiTethering(tetherEventCallback);
 
-            // If calling #tether successful, there is a callback to tell the result of tethering
-            // setup.
-            tetherEventCallback.expectErrorOrTethered(wifiTetheringIface);
+            final List<String> tetheredIfaces = tetherEventCallback.getTetheredInterfaces();
+            assertEquals(1, tetheredIfaces.size());
+            final String wifiTetheringIface = tetheredIfaces.get(0);
+
+            mCtsTetheringUtils.stopWifiTethering(tetherEventCallback);
+
+            try {
+                final int ret = mTM.tether(wifiTetheringIface);
+                // There is no guarantee that the wifi interface will be available after disabling
+                // the hotspot, so don't fail the test if the call to tether() fails.
+                if (ret == TETHER_ERROR_NO_ERROR) {
+                    // If calling #tether successful, there is a callback to tell the result of
+                    // tethering setup.
+                    tetherEventCallback.expectErrorOrTethered(wifiTetheringIface);
+                }
+            } finally {
+                mTM.untether(wifiTetheringIface);
+            }
         } finally {
-            mTM.untether(wifiTetheringIface);
-            unregisterTetheringEventCallback(tetherEventCallback);
+            mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
         }
     }
 
     @Test
     public void testGetTetherableInterfaceRegexps() {
-        final TestTetheringEventCallback tetherEventCallback = registerTetheringEventCallback();
+        final TestTetheringEventCallback tetherEventCallback =
+                mCtsTetheringUtils.registerTetheringEventCallback();
         tetherEventCallback.assumeTetheringSupported();
 
         final TetheringInterfaceRegexps tetherableRegexs =
@@ -641,26 +303,25 @@
         wifiRegexs.forEach(s -> assertFalse(btRegexs.contains(s)));
         usbRegexs.forEach(s -> assertFalse(btRegexs.contains(s)));
 
-        unregisterTetheringEventCallback(tetherEventCallback);
+        mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
     }
 
     @Test
     public void testStopAllTethering() throws Exception {
-        final TestTetheringEventCallback tetherEventCallback = registerTetheringEventCallback();
-        tetherEventCallback.assumeTetheringSupported();
-
+        final TestTetheringEventCallback tetherEventCallback =
+                mCtsTetheringUtils.registerTetheringEventCallback();
         try {
-            if (!isWifiTetheringSupported(tetherEventCallback)) return;
+            tetherEventCallback.assumeWifiTetheringSupported(mContext);
 
             // TODO: start ethernet tethering here when TetheringManagerTest is moved to
             // TetheringIntegrationTest.
 
-            startWifiTethering(tetherEventCallback);
+            mCtsTetheringUtils.startWifiTethering(tetherEventCallback);
 
             mTM.stopAllTethering();
             tetherEventCallback.expectTetheredInterfacesChanged(null);
         } finally {
-            unregisterTetheringEventCallback(tetherEventCallback);
+            mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
         }
     }
 
@@ -749,13 +410,15 @@
     @Test
     public void testTetheringUpstream() throws Exception {
         assumeTrue(mPm.hasSystemFeature(FEATURE_TELEPHONY));
-        final TestTetheringEventCallback tetherEventCallback = registerTetheringEventCallback();
-        tetherEventCallback.assumeTetheringSupported();
-        final boolean previousWifiEnabledState = mWm.isWifiEnabled();
+        final TestTetheringEventCallback tetherEventCallback =
+                mCtsTetheringUtils.registerTetheringEventCallback();
+
+        boolean previousWifiEnabledState = false;
 
         try {
-            if (!isWifiTetheringSupported(tetherEventCallback)) return;
+            tetherEventCallback.assumeWifiTetheringSupported(mContext);
 
+            previousWifiEnabledState = mWm.isWifiEnabled();
             if (previousWifiEnabledState) {
                 mCtsNetUtils.ensureWifiDisconnected(null);
             }
@@ -778,7 +441,7 @@
 
             assertTrue(activeNetCap.hasTransport(TRANSPORT_CELLULAR));
 
-            startWifiTethering(tetherEventCallback);
+            mCtsTetheringUtils.startWifiTethering(tetherEventCallback);
 
             final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
                     Context.TELEPHONY_SERVICE);
@@ -789,9 +452,9 @@
             assertTrue(netCap.hasTransport(TRANSPORT_CELLULAR));
             assertTrue(netCap.hasCapability(expectedCap));
 
-            stopWifiTethering(tetherEventCallback);
+            mCtsTetheringUtils.stopWifiTethering(tetherEventCallback);
         } finally {
-            unregisterTetheringEventCallback(tetherEventCallback);
+            mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
             if (previousWifiEnabledState) {
                 mCtsNetUtils.connectToWifi();
             }
