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/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..b18c1e7
--- /dev/null
+++ b/tests/cts/net/util/java/android/net/cts/util/CtsTetheringUtils.java
@@ -0,0 +1,397 @@
+/*
+ * 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.Context;
+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.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 TetheringInterfaceRegexps getTetheringInterfaceRegexps() {
+            return mTetherableRegex;
+        }
+
+        public List<String> getTetherableInterfaces() {
+            return mTetherableIfaces;
+        }
+
+        public List<String> getTetheredInterfaces() {
+            return mTetheredIfaces;
+        }
+    }
+
+    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/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
index 92dca39..397b4b8 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,77 +202,6 @@
         }
     }
 
-    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;
@@ -331,7 +221,7 @@
         mTetherChangeReceiver.expectTethering(true /* active */, wifiRegexs);
 
         mTM.stopTethering(TETHERING_WIFI);
-        expectSoftApDisabled();
+        mCtsTetheringUtils.expectSoftApDisabled();
         mTetherChangeReceiver.expectTethering(false /* active */, wifiRegexs);
     }
 
@@ -358,252 +248,24 @@
         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();
+        final TestTetheringEventCallback tetherEventCallback =
+                mCtsTetheringUtils.registerTetheringEventCallback();
         tetherEventCallback.assumeTetheringSupported();
 
         if (!isWifiTetheringSupported(tetherEventCallback)) {
-            unregisterTetheringEventCallback(tetherEventCallback);
+            mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
             return;
         }
 
-        startWifiTethering(tetherEventCallback);
+        mCtsTetheringUtils.startWifiTethering(tetherEventCallback);
 
         final List<String> tetheredIfaces = tetherEventCallback.getTetheredInterfaces();
         assertEquals(1, tetheredIfaces.size());
         final String wifiTetheringIface = tetheredIfaces.get(0);
 
-        stopWifiTethering(tetherEventCallback);
+        mCtsTetheringUtils.stopWifiTethering(tetherEventCallback);
 
         try {
             final int ret = mTM.tether(wifiTetheringIface);
@@ -617,13 +279,14 @@
             tetherEventCallback.expectErrorOrTethered(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,12 +304,13 @@
         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();
+        final TestTetheringEventCallback tetherEventCallback =
+                mCtsTetheringUtils.registerTetheringEventCallback();
         tetherEventCallback.assumeTetheringSupported();
 
         try {
@@ -655,12 +319,12 @@
             // 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,7 +413,8 @@
     @Test
     public void testTetheringUpstream() throws Exception {
         assumeTrue(mPm.hasSystemFeature(FEATURE_TELEPHONY));
-        final TestTetheringEventCallback tetherEventCallback = registerTetheringEventCallback();
+        final TestTetheringEventCallback tetherEventCallback =
+                mCtsTetheringUtils.registerTetheringEventCallback();
         tetherEventCallback.assumeTetheringSupported();
         final boolean previousWifiEnabledState = mWm.isWifiEnabled();
 
@@ -778,7 +443,7 @@
 
             assertTrue(activeNetCap.hasTransport(TRANSPORT_CELLULAR));
 
-            startWifiTethering(tetherEventCallback);
+            mCtsTetheringUtils.startWifiTethering(tetherEventCallback);
 
             final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
                     Context.TELEPHONY_SERVICE);
@@ -789,9 +454,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();
             }
