diff --git a/tests/cts/hostside/AndroidTest.xml b/tests/cts/hostside/AndroidTest.xml
index 7cc0dd1..b7fefaf 100644
--- a/tests/cts/hostside/AndroidTest.xml
+++ b/tests/cts/hostside/AndroidTest.xml
@@ -20,6 +20,7 @@
     <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
 
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.LocationCheck" />
     <target_preparer class="com.android.cts.net.NetworkPolicyTestsPreparer" />
 
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
index 69dd2ad..1db0417 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
@@ -30,6 +30,7 @@
 import static com.android.cts.net.hostside.NetworkPolicyTestUtils.restrictBackgroundValueToString;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -62,13 +63,10 @@
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 
-import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
 /**
  * Superclass for tests related to background network restrictions.
  */
-@RunWith(AndroidJUnit4.class)
+@RunWith(NetworkPolicyTestRunner.class)
 public abstract class AbstractRestrictBackgroundNetworkTestCase {
     public static final String TAG = "RestrictBackgroundNetworkTests";
 
@@ -129,16 +127,13 @@
     protected Context mContext;
     protected Instrumentation mInstrumentation;
     protected ConnectivityManager mCm;
-    protected WifiManager mWfm;
     protected int mUid;
     private int mMyUid;
     private MyServiceClient mServiceClient;
     private String mDeviceIdleConstantsSetting;
-    private boolean mIsLocationOn;
 
     @Rule
-    public final RuleChain mRuleChain = RuleChain.outerRule(new DumpOnFailureRule())
-            .around(new RequiredPropertiesRule())
+    public final RuleChain mRuleChain = RuleChain.outerRule(new RequiredPropertiesRule())
             .around(new MeterednessConfigurationRule());
 
     protected void setUp() throws Exception {
@@ -148,16 +143,11 @@
         mInstrumentation = getInstrumentation();
         mContext = getContext();
         mCm = getConnectivityManager();
-        mWfm = getWifiManager();
         mUid = getUid(TEST_APP2_PKG);
         mMyUid = getUid(mContext.getPackageName());
         mServiceClient = new MyServiceClient(mContext);
         mServiceClient.bind();
         mDeviceIdleConstantsSetting = "device_idle_constants";
-        mIsLocationOn = isLocationOn();
-        if (!mIsLocationOn) {
-            enableLocation();
-        }
         executeShellCommand("cmd netpolicy start-watching " + mUid);
         setAppIdle(false);
 
@@ -168,33 +158,9 @@
 
     protected void tearDown() throws Exception {
         executeShellCommand("cmd netpolicy stop-watching");
-        if (!mIsLocationOn) {
-            disableLocation();
-        }
         mServiceClient.unbind();
     }
 
-    private void enableLocation() throws Exception {
-        Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.LOCATION_MODE,
-                Settings.Secure.LOCATION_MODE_SENSORS_ONLY);
-        assertEquals(Settings.Secure.LOCATION_MODE_SENSORS_ONLY,
-                Settings.Secure.getInt(mContext.getContentResolver(),
-                        Settings.Secure.LOCATION_MODE));
-    }
-
-    private void disableLocation() throws Exception {
-        Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.LOCATION_MODE,
-                Settings.Secure.LOCATION_MODE_OFF);
-        assertEquals(Settings.Secure.LOCATION_MODE_OFF,
-                Settings.Secure.getInt(mContext.getContentResolver(),
-                        Settings.Secure.LOCATION_MODE));
-    }
-
-    private boolean isLocationOn() throws Exception {
-        return Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.LOCATION_MODE) != Settings.Secure.LOCATION_MODE_OFF;
-    }
-
     protected int getUid(String packageName) throws Exception {
         return mContext.getPackageManager().getPackageUid(packageName, 0);
     }
@@ -212,7 +178,9 @@
         do {
             attempts++;
             count = getNumberBroadcastsReceived(receiverName, ACTION_RESTRICT_BACKGROUND_CHANGED);
-            if (count >= expectedCount) {
+            assertFalse("Expected count " + expectedCount + " but actual is " + count,
+                    count > expectedCount);
+            if (count == expectedCount) {
                 break;
             }
             Log.d(TAG, "Expecting count " + expectedCount + " but actual is " + count + " after "
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestRunner.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestRunner.java
new file mode 100644
index 0000000..f340907
--- /dev/null
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestRunner.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.net.hostside;
+
+import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner;
+
+import org.junit.rules.RunRules;
+import org.junit.rules.TestRule;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.Statement;
+
+import java.util.List;
+
+/**
+ * Custom runner to allow dumping logs after a test failure before the @After methods get to run.
+ */
+public class NetworkPolicyTestRunner extends AndroidJUnit4ClassRunner {
+    private TestRule mDumpOnFailureRule = new DumpOnFailureRule();
+
+    public NetworkPolicyTestRunner(Class<?> klass) throws InitializationError {
+        super(klass);
+    }
+
+    @Override
+    public Statement methodInvoker(FrameworkMethod method, Object test) {
+        return new RunRules(super.methodInvoker(method, test), List.of(mDumpOnFailureRule),
+                describeChild(method));
+    }
+}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java
index ca2864c..3807d79 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java
@@ -27,17 +27,20 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import android.app.ActivityManager;
 import android.app.Instrumentation;
 import android.content.Context;
+import android.location.LocationManager;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.wifi.WifiManager;
+import android.os.Process;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Pair;
@@ -113,6 +116,20 @@
         return am.isLowRamDevice();
     }
 
+    public static boolean isLocationEnabled() {
+        final LocationManager lm = (LocationManager) getContext().getSystemService(
+                Context.LOCATION_SERVICE);
+        return lm.isLocationEnabled();
+    }
+
+    public static void setLocationEnabled(boolean enabled) {
+        final LocationManager lm = (LocationManager) getContext().getSystemService(
+                Context.LOCATION_SERVICE);
+        lm.setLocationEnabledForUser(enabled, Process.myUserHandle());
+        assertEquals("Couldn't change location enabled state", lm.isLocationEnabled(), enabled);
+        Log.d(TAG, "Changed location enabled state to " + enabled);
+    }
+
     public static boolean isActiveNetworkMetered(boolean metered) {
         return getConnectivityManager().isActiveNetworkMetered() == metered;
     }
@@ -128,9 +145,21 @@
         if (isActiveNetworkMetered(metered)) {
             return null;
         }
-        final String ssid = unquoteSSID(getWifiManager().getConnectionInfo().getSSID());
-        setWifiMeteredStatus(ssid, metered);
-        return Pair.create(ssid, !metered);
+        final boolean isLocationEnabled = isLocationEnabled();
+        try {
+            if (!isLocationEnabled) {
+                setLocationEnabled(true);
+            }
+            final String ssid = unquoteSSID(getWifiManager().getConnectionInfo().getSSID());
+            assertNotEquals(WifiManager.UNKNOWN_SSID, ssid);
+            setWifiMeteredStatus(ssid, metered);
+            return Pair.create(ssid, !metered);
+        } finally {
+            // Reset the location enabled state
+            if (!isLocationEnabled) {
+                setLocationEnabled(false);
+            }
+        }
     }
 
     public static void resetMeteredNetwork(String ssid, boolean metered) throws Exception {
diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp
index 76bb27e..46fae33 100644
--- a/tests/cts/net/Android.bp
+++ b/tests/cts/net/Android.bp
@@ -47,6 +47,7 @@
         "mockwebserver",
         "junit",
         "junit-params",
+        "libnanohttpd",
         "truth-prebuilt",
     ],
 
diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml
index c2b3bf7..baf914f 100644
--- a/tests/cts/net/AndroidManifest.xml
+++ b/tests/cts/net/AndroidManifest.xml
@@ -35,6 +35,11 @@
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
 
+    <!-- This test also uses signature permissions through adopting the shell identity.
+         The permissions acquired that way include (probably not exhaustive) :
+             android.permission.MANAGE_TEST_NETWORKS
+    -->
+
     <application android:usesCleartextTraffic="true">
         <uses-library android:name="android.test.runner" />
         <uses-library android:name="org.apache.http.legacy" android:required="false" />
diff --git a/tests/cts/net/ipsec/Android.bp b/tests/cts/net/ipsec/Android.bp
new file mode 100644
index 0000000..124e93c
--- /dev/null
+++ b/tests/cts/net/ipsec/Android.bp
@@ -0,0 +1,48 @@
+// 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.stubs",
+    ],
+
+    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
new file mode 100644
index 0000000..de7d23c
--- /dev/null
+++ b/tests/cts/net/ipsec/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<?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
new file mode 100644
index 0000000..09e5c93
--- /dev/null
+++ b/tests/cts/net/ipsec/AndroidTest.xml
@@ -0,0 +1,30 @@
+<!-- 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>
+</configuration>
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
new file mode 100644
index 0000000..22736e9
--- /dev/null
+++ b/tests/cts/net/ipsec/assets/key/client-a-private-key.key
@@ -0,0 +1,28 @@
+-----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
new file mode 100644
index 0000000..e82da85
--- /dev/null
+++ b/tests/cts/net/ipsec/assets/pem/client-a-end-cert.pem
@@ -0,0 +1,21 @@
+-----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
new file mode 100644
index 0000000..707e575
--- /dev/null
+++ b/tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-one.pem
@@ -0,0 +1,21 @@
+-----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
new file mode 100644
index 0000000..39808f8
--- /dev/null
+++ b/tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-two.pem
@@ -0,0 +1,21 @@
+-----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
new file mode 100644
index 0000000..972fd55
--- /dev/null
+++ b/tests/cts/net/ipsec/assets/pem/server-a-self-signed-ca.pem
@@ -0,0 +1,20 @@
+-----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
new file mode 100644
index 0000000..c24379d
--- /dev/null
+++ b/tests/cts/net/ipsec/src/android/net/eap/cts/EapSessionConfigTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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
new file mode 100644
index 0000000..7fb1b6d
--- /dev/null
+++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java
@@ -0,0 +1,230 @@
+/*
+ * 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
new file mode 100644
index 0000000..0317def
--- /dev/null
+++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeIdentificationTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 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/IkeSessionParamsTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java
new file mode 100644
index 0000000..c767b78
--- /dev/null
+++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java
@@ -0,0 +1,414 @@
+/*
+ * 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
new file mode 100644
index 0000000..ed67dd1
--- /dev/null
+++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java
@@ -0,0 +1,258 @@
+/*
+ * 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.IkeSessionConfiguration.EXTENSION_TYPE_FRAGMENTATION;
+import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN;
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+
+import static com.android.internal.util.HexDump.hexStringToByteArray;
+
+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.ipsec.ike.ChildSessionConfiguration;
+import android.net.ipsec.ike.IkeFqdnIdentification;
+import android.net.ipsec.ike.IkeSession;
+import android.net.ipsec.ike.IkeSessionConfiguration;
+import android.net.ipsec.ike.IkeSessionConnectionInfo;
+import android.net.ipsec.ike.IkeSessionParams;
+import android.net.ipsec.ike.TunnelModeChildSessionParams;
+import android.net.ipsec.ike.exceptions.IkeException;
+import android.net.ipsec.ike.exceptions.IkeProtocolException;
+import android.platform.test.annotations.AppModeFull;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.net.InetAddress;
+import java.util.Arrays;
+
+@RunWith(AndroidJUnit4.class)
+@AppModeFull(reason = "MANAGE_TEST_NETWORKS 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 static final long IKE_INIT_SPI = Long.parseLong("46B8ECA1E0D72A18", 16);
+
+    private static final TunnelModeChildSessionParams CHILD_PARAMS =
+            new TunnelModeChildSessionParams.Builder()
+                    .addSaProposal(SaProposalTest.buildChildSaProposalWithNormalModeCipher())
+                    .addSaProposal(SaProposalTest.buildChildSaProposalWithCombinedModeCipher())
+                    .addInternalAddressRequest(AF_INET)
+                    .addInternalAddressRequest(AF_INET6)
+                    .build();
+
+    private IkeSessionParams createIkeSessionParams(InetAddress mRemoteAddress) {
+        return new IkeSessionParams.Builder(sContext)
+                .setNetwork(mTunNetwork)
+                .setServerHostname(mRemoteAddress.getHostAddress())
+                .addSaProposal(SaProposalTest.buildIkeSaProposalWithNormalModeCipher())
+                .addSaProposal(SaProposalTest.buildIkeSaProposalWithCombinedModeCipher())
+                .setLocalIdentification(new IkeFqdnIdentification(LOCAL_HOSTNAME))
+                .setRemoteIdentification(new IkeFqdnIdentification(REMOTE_HOSTNAME))
+                .setAuthPsk(IKE_PSK)
+                .build();
+    }
+
+    private IkeSession openIkeSession(IkeSessionParams ikeParams) {
+        return new IkeSession(
+                sContext,
+                ikeParams,
+                CHILD_PARAMS,
+                mUserCbExecutor,
+                mIkeSessionCallback,
+                mFirstChildSessionCallback);
+    }
+
+    @Test
+    public void testIkeSessionSetupAndManageChildSas() throws Exception {
+        // Open IKE Session
+        IkeSession ikeSession = openIkeSession(createIkeSessionParams(mRemoteAddress));
+        int expectedMsgId = 0;
+        mTunUtils.awaitReqAndInjectResp(
+                IKE_INIT_SPI,
+                expectedMsgId++,
+                false /* expectedUseEncap */,
+                hexStringToByteArray(SUCCESS_IKE_INIT_RESP));
+
+        mTunUtils.awaitReqAndInjectResp(
+                IKE_INIT_SPI,
+                expectedMsgId++,
+                true /* expectedUseEncap */,
+                hexStringToByteArray(SUCCESS_IKE_AUTH_RESP));
+
+        // Verify opening IKE Session
+        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());
+
+        // Verify opening first Child Session
+        ChildSessionConfiguration firstChildConfig = mFirstChildSessionCallback.awaitChildConfig();
+        assertNotNull(firstChildConfig);
+        assertEquals(
+                Arrays.asList(EXPECTED_INBOUND_TS), firstChildConfig.getInboundTrafficSelectors());
+        assertEquals(Arrays.asList(DEFAULT_V4_TS), firstChildConfig.getOutboundTrafficSelectors());
+        assertEquals(
+                Arrays.asList(EXPECTED_INTERNAL_LINK_ADDR),
+                firstChildConfig.getInternalAddresses());
+        assertTrue(firstChildConfig.getInternalSubnets().isEmpty());
+        assertTrue(firstChildConfig.getInternalDnsServers().isEmpty());
+        assertTrue(firstChildConfig.getInternalDhcpServers().isEmpty());
+
+        // Open additional Child Session
+        TestChildSessionCallback additionalChildCb = new TestChildSessionCallback();
+        ikeSession.openChildSession(CHILD_PARAMS, additionalChildCb);
+        mTunUtils.awaitReqAndInjectResp(
+                IKE_INIT_SPI,
+                expectedMsgId++,
+                true /* expectedUseEncap */,
+                hexStringToByteArray(SUCCESS_CREATE_CHILD_RESP));
+
+        // Verify opening additional Child Session
+        ChildSessionConfiguration additionalChildConfig = additionalChildCb.awaitChildConfig();
+        assertNotNull(additionalChildConfig);
+        assertEquals(
+                Arrays.asList(EXPECTED_INBOUND_TS), firstChildConfig.getInboundTrafficSelectors());
+        assertEquals(Arrays.asList(DEFAULT_V4_TS), firstChildConfig.getOutboundTrafficSelectors());
+        assertTrue(additionalChildConfig.getInternalAddresses().isEmpty());
+        assertTrue(firstChildConfig.getInternalSubnets().isEmpty());
+        assertTrue(firstChildConfig.getInternalDnsServers().isEmpty());
+        assertTrue(firstChildConfig.getInternalDhcpServers().isEmpty());
+
+        // Close additional Child Session
+        ikeSession.closeChildSession(additionalChildCb);
+        mTunUtils.awaitReqAndInjectResp(
+                IKE_INIT_SPI,
+                expectedMsgId++,
+                true /* expectedUseEncap */,
+                hexStringToByteArray(SUCCESS_DELETE_CHILD_RESP));
+
+        additionalChildCb.awaitOnClosed();
+
+        // Close IKE Session
+        ikeSession.close();
+        mTunUtils.awaitReqAndInjectResp(
+                IKE_INIT_SPI,
+                expectedMsgId++,
+                true /* expectedUseEncap */,
+                hexStringToByteArray(SUCCESS_DELETE_IKE_RESP));
+
+        mFirstChildSessionCallback.awaitOnClosed();
+        mIkeSessionCallback.awaitOnClosed();
+
+        // TODO: verify IpSecTransform pair is created and deleted
+    }
+
+    @Test
+    public void testIkeSessionKill() throws Exception {
+        // Open IKE Session
+        IkeSession ikeSession = openIkeSession(createIkeSessionParams(mRemoteAddress));
+        int expectedMsgId = 0;
+        mTunUtils.awaitReqAndInjectResp(
+                IKE_INIT_SPI,
+                expectedMsgId++,
+                false /* expectedUseEncap */,
+                hexStringToByteArray(SUCCESS_IKE_INIT_RESP));
+
+        mTunUtils.awaitReqAndInjectResp(
+                IKE_INIT_SPI,
+                expectedMsgId++,
+                true /* expectedUseEncap */,
+                hexStringToByteArray(SUCCESS_IKE_AUTH_RESP));
+
+        ikeSession.kill();
+
+        mFirstChildSessionCallback.awaitOnClosed();
+        mIkeSessionCallback.awaitOnClosed();
+    }
+
+    @Test
+    public void testIkeInitFail() throws Exception {
+        String ikeInitFailRespHex =
+                "46B8ECA1E0D72A180000000000000000292022200000000000000024000000080000000E";
+
+        // Open IKE Session
+        IkeSession ikeSession = openIkeSession(createIkeSessionParams(mRemoteAddress));
+        int expectedMsgId = 0;
+        mTunUtils.awaitReqAndInjectResp(
+                IKE_INIT_SPI,
+                expectedMsgId++,
+                false /* expectedUseEncap */,
+                hexStringToByteArray(ikeInitFailRespHex));
+
+        IkeException exception = mIkeSessionCallback.awaitOnClosedException();
+        assertNotNull(exception);
+        assertTrue(exception instanceof IkeProtocolException);
+        IkeProtocolException protocolException = (IkeProtocolException) exception;
+        assertEquals(ERROR_TYPE_NO_PROPOSAL_CHOSEN, protocolException.getErrorType());
+        assertArrayEquals(EXPECTED_PROTOCOL_ERROR_DATA_NONE, protocolException.getErrorData());
+    }
+
+    // TODO(b/148689509): Verify rekey process and handling IKE_AUTH failure
+}
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
new file mode 100644
index 0000000..deba8fd
--- /dev/null
+++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java
@@ -0,0 +1,374 @@
+/*
+ * 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.app.AppOpsManager.OP_MANAGE_IPSEC_TUNNELS;
+
+import android.annotation.NonNull;
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.InetAddresses;
+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.IkeTrafficSelector;
+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 android.util.Log;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.compatibility.common.util.SystemUtil;
+import com.android.testutils.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.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
+ */
+@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_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 IkeTrafficSelector EXPECTED_INBOUND_TS =
+            new IkeTrafficSelector(
+                    MIN_PORT, MAX_PORT, EXPECTED_INTERNAL_ADDR, EXPECTED_INTERNAL_ADDR);
+
+    // 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 = (TestNetworkManager) sContext.getSystemService(Context.TEST_NETWORK_SERVICE);
+
+        // 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 tearDownPermissionAfterClass() throws Exception {
+        setAppOp(OP_MANAGE_IPSEC_TUNNELS, false);
+
+        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();
+
+        resetNextAvailableAddress(NEXT_AVAILABLE_IP4_ADDR_LOCAL, INITIAL_AVAILABLE_IP4_ADDR_LOCAL);
+        resetNextAvailableAddress(
+                NEXT_AVAILABLE_IP4_ADDR_REMOTE, INITIAL_AVAILABLE_IP4_ADDR_REMOTE);
+    }
+
+    void setUpTestNetwork(InetAddress localAddr) throws Exception {
+        int prefixLen = localAddr instanceof Inet4Address ? IP4_PREFIX_LEN : IP4_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();
+    }
+
+    private 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
+            Log.d("IKE", "CTS setAppOp cmd " + cmd);
+
+            String result = 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);
+        }
+    }
+
+    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);
+        }
+    }
+
+    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;
+        }
+    }
+
+    // TODO(b/148689509): Verify IKE Session setup using EAP and digital-signature-based auth
+
+    // 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
new file mode 100644
index 0000000..f07c710
--- /dev/null
+++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 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 = "username";
+    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
new file mode 100644
index 0000000..5a8258d
--- /dev/null
+++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTunUtils.java
@@ -0,0 +1,243 @@
+/*
+ * 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 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.Arrays;
+
+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_HEADER_LEN = 28;
+    private static final int IKE_INIT_SPI_OFFSET = 0;
+    private static final int IKE_IS_RESP_BYTE_OFFSET = 19;
+    private static final int IKE_MSG_ID_OFFSET = 20;
+
+    public IkeTunUtils(ParcelFileDescriptor tunFd) {
+        super(tunFd);
+    }
+
+    /**
+     * Await the expected IKE request and inject an IKE response.
+     *
+     * @param respIkePkt IKE response packet without IP/UDP headers or NON ESP MARKER.
+     */
+    public byte[] awaitReqAndInjectResp(
+            long expectedInitIkeSpi, int expectedMsgId, boolean expectedUseEncap, byte[] respIkePkt)
+            throws Exception {
+        byte[] request =
+                awaitIkePacket(
+                        expectedInitIkeSpi,
+                        expectedMsgId,
+                        false /* expectedResp */,
+                        expectedUseEncap);
+
+        // 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 */);
+
+        byte[] response =
+                buildIkePacket(srcAddr, dstAddr, srcPort, dstPort, expectedUseEncap, respIkePkt);
+        injectPacket(response);
+        return request;
+    }
+
+    private byte[] awaitIkePacket(
+            long expectedInitIkeSpi,
+            int expectedMsgId,
+            boolean expectedResp,
+            boolean expectedUseEncap)
+            throws Exception {
+        long endTime = System.currentTimeMillis() + TIMEOUT;
+        int startIndex = 0;
+        synchronized (mPackets) {
+            while (System.currentTimeMillis() < endTime) {
+                byte[] ikePkt =
+                        getFirstMatchingPacket(
+                                (pkt) -> {
+                                    return isIke(
+                                            pkt,
+                                            expectedInitIkeSpi,
+                                            expectedMsgId,
+                                            expectedResp,
+                                            expectedUseEncap);
+                                },
+                                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);
+                }
+            }
+
+            String direction = expectedResp ? "response" : "request";
+            fail(
+                    "No such IKE "
+                            + direction
+                            + " found with Initiator SPI "
+                            + expectedInitIkeSpi
+                            + " and message ID "
+                            + expectedMsgId);
+        }
+        return null;
+    }
+
+    private static boolean isIke(
+            byte[] pkt,
+            long expectedInitIkeSpi,
+            int expectedMsgId,
+            boolean expectedResp,
+            boolean expectedUseEncap) {
+        int ipProtocolOffset = 0;
+        int ikeOffset = 0;
+        if (isIpv6(pkt)) {
+            // IPv6 UDP expectedUseEncap not supported by kernels; assume non-expectedUseEncap.
+            ipProtocolOffset = IP6_PROTO_OFFSET;
+            ikeOffset = IP6_HDRLEN + UDP_HDRLEN;
+        } else {
+            // Use default IPv4 header length (assuming no options)
+            ipProtocolOffset = IP4_PROTO_OFFSET;
+            ikeOffset = IP4_HDRLEN + UDP_HDRLEN;
+
+            if (expectedUseEncap) {
+                if (hasNonEspMarker(pkt)) {
+                    ikeOffset += NON_ESP_MARKER_LEN;
+                } else {
+                    return false;
+                }
+            }
+        }
+
+        return pkt[ipProtocolOffset] == IPPROTO_UDP
+                && areSpiAndMsgIdEqual(
+                        pkt, ikeOffset, expectedInitIkeSpi, expectedMsgId, expectedResp);
+    }
+
+    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 areSpiAndMsgIdEqual(
+            byte[] pkt,
+            int ikeOffset,
+            long expectedIkeInitSpi,
+            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)
+
+        // Check message ID.
+        buffer.get(new byte[IKE_MSG_ID_OFFSET]);
+        int msgId = buffer.getInt();
+        return expectedMsgId == msgId;
+
+        // TODO: Check SPI and packet direction
+    }
+
+    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());
+    }
+
+    private 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
new file mode 100644
index 0000000..35e6719
--- /dev/null
+++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/PacketUtils.java
@@ -0,0 +1,467 @@
+/*
+ * 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
new file mode 100644
index 0000000..e0d3be0
--- /dev/null
+++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java
@@ -0,0 +1,256 @@
+/*
+ * 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
new file mode 100644
index 0000000..5b08cdc
--- /dev/null
+++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TestNetworkUtils.java
@@ -0,0 +1,87 @@
+/*
+ * 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
new file mode 100644
index 0000000..cb1d826
--- /dev/null
+++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TunUtils.java
@@ -0,0 +1,264 @@
+/*
+ * 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 = 100;
+
+    static final int IP4_PROTO_OFFSET = 9;
+    static final int IP6_PROTO_OFFSET = 6;
+
+    static final int IP4_ADDR_OFFSET = 12;
+    static final int IP4_ADDR_LEN = 4;
+    static final int IP6_ADDR_OFFSET = 8;
+    static final int IP6_ADDR_LEN = 16;
+
+    final List<byte[]> mPackets = new ArrayList<>();
+    private final ParcelFileDescriptor mTunFd;
+    private final Thread mReaderThread;
+
+    public TunUtils(ParcelFileDescriptor tunFd) {
+        mTunFd = tunFd;
+
+        // Start background reader thread
+        mReaderThread =
+                new Thread(
+                        () -> {
+                            try {
+                                // Loop will exit and thread will quit when tunFd is closed.
+                                // Receiving either EOF or an exception will exit this reader loop.
+                                // FileInputStream in uninterruptable, so there's no good way to
+                                // ensure that this thread shuts down except upon FD closure.
+                                while (true) {
+                                    byte[] intercepted = receiveFromTun();
+                                    if (intercepted == null) {
+                                        // Exit once we've hit EOF
+                                        return;
+                                    } else if (intercepted.length > 0) {
+                                        // Only save packet if we've received any bytes.
+                                        synchronized (mPackets) {
+                                            mPackets.add(intercepted);
+                                            mPackets.notifyAll();
+                                        }
+                                    }
+                                }
+                            } catch (IOException ignored) {
+                                // Simply exit this reader thread
+                                return;
+                            }
+                        });
+        mReaderThread.start();
+    }
+
+    private byte[] receiveFromTun() throws IOException {
+        FileInputStream in = new FileInputStream(mTunFd.getFileDescriptor());
+        byte[] inBytes = new byte[DATA_BUFFER_LEN];
+        int bytesRead = in.read(inBytes);
+
+        if (bytesRead < 0) {
+            return null; // return null for EOF
+        } else if (bytesRead >= DATA_BUFFER_LEN) {
+            throw new IllegalStateException("Too big packet. Fragmentation unsupported");
+        }
+        return Arrays.copyOf(inBytes, bytesRead);
+    }
+
+    byte[] getFirstMatchingPacket(Predicate<byte[]> verifier, int startIndex) {
+        synchronized (mPackets) {
+            for (int i = startIndex; i < mPackets.size(); i++) {
+                byte[] pkt = mPackets.get(i);
+                if (verifier.test(pkt)) {
+                    return pkt;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Checks if the specified bytes were ever sent in plaintext.
+     *
+     * <p>Only checks for known plaintext bytes to prevent triggering on ICMP/RA packets or the like
+     *
+     * @param plaintext the plaintext bytes to check for
+     * @param startIndex the index in the list to check for
+     */
+    public boolean hasPlaintextPacket(byte[] plaintext, int startIndex) {
+        Predicate<byte[]> verifier =
+                (pkt) -> {
+                    return Collections.indexOfSubList(Arrays.asList(pkt), Arrays.asList(plaintext))
+                            != -1;
+                };
+        return getFirstMatchingPacket(verifier, startIndex) != null;
+    }
+
+    public byte[] getEspPacket(int spi, boolean encap, int startIndex) {
+        return getFirstMatchingPacket(
+                (pkt) -> {
+                    return isEsp(pkt, spi, encap);
+                },
+                startIndex);
+    }
+
+    public byte[] awaitEspPacketNoPlaintext(
+            int spi, byte[] plaintext, boolean useEncap, int expectedPacketSize) throws Exception {
+        long endTime = System.currentTimeMillis() + TIMEOUT;
+        int startIndex = 0;
+
+        synchronized (mPackets) {
+            while (System.currentTimeMillis() < endTime) {
+                byte[] espPkt = getEspPacket(spi, useEncap, startIndex);
+                if (espPkt != null) {
+                    // Validate packet size
+                    assertEquals(expectedPacketSize, espPkt.length);
+
+                    // Always check plaintext from start
+                    assertFalse(hasPlaintextPacket(plaintext, 0));
+                    return espPkt; // We've found the packet we're looking for.
+                }
+
+                startIndex = mPackets.size();
+
+                // Try to prevent waiting too long. If waitTimeout <= 0, we've already hit timeout
+                long waitTimeout = endTime - System.currentTimeMillis();
+                if (waitTimeout > 0) {
+                    mPackets.wait(waitTimeout);
+                }
+            }
+
+            fail("No such ESP packet found with SPI " + spi);
+        }
+        return null;
+    }
+
+    private static boolean isSpiEqual(byte[] pkt, int espOffset, int spi) {
+        // Check SPI byte by byte.
+        return pkt[espOffset] == (byte) ((spi >>> 24) & 0xff)
+                && pkt[espOffset + 1] == (byte) ((spi >>> 16) & 0xff)
+                && pkt[espOffset + 2] == (byte) ((spi >>> 8) & 0xff)
+                && pkt[espOffset + 3] == (byte) (spi & 0xff);
+    }
+
+    private static boolean isEsp(byte[] pkt, int spi, boolean encap) {
+        if (isIpv6(pkt)) {
+            // IPv6 UDP encap not supported by kernels; assume non-encap.
+            return pkt[IP6_PROTO_OFFSET] == IPPROTO_ESP && isSpiEqual(pkt, IP6_HDRLEN, spi);
+        } else {
+            // Use default IPv4 header length (assuming no options)
+            if (encap) {
+                return pkt[IP4_PROTO_OFFSET] == IPPROTO_UDP
+                        && isSpiEqual(pkt, IP4_HDRLEN + UDP_HDRLEN, spi);
+            } else {
+                return pkt[IP4_PROTO_OFFSET] == IPPROTO_ESP && isSpiEqual(pkt, IP4_HDRLEN, spi);
+            }
+        }
+    }
+
+    static boolean isIpv6(byte[] pkt) {
+        // First nibble shows IP version. 0x60 for IPv6
+        return (pkt[0] & (byte) 0xF0) == (byte) 0x60;
+    }
+
+    private static byte[] getReflectedPacket(byte[] pkt) {
+        byte[] reflected = Arrays.copyOf(pkt, pkt.length);
+
+        if (isIpv6(pkt)) {
+            // Set reflected packet's dst to that of the original's src
+            System.arraycopy(
+                    pkt, // src
+                    IP6_ADDR_OFFSET + IP6_ADDR_LEN, // src offset
+                    reflected, // dst
+                    IP6_ADDR_OFFSET, // dst offset
+                    IP6_ADDR_LEN); // len
+            // Set reflected packet's src IP to that of the original's dst IP
+            System.arraycopy(
+                    pkt, // src
+                    IP6_ADDR_OFFSET, // src offset
+                    reflected, // dst
+                    IP6_ADDR_OFFSET + IP6_ADDR_LEN, // dst offset
+                    IP6_ADDR_LEN); // len
+        } else {
+            // Set reflected packet's dst to that of the original's src
+            System.arraycopy(
+                    pkt, // src
+                    IP4_ADDR_OFFSET + IP4_ADDR_LEN, // src offset
+                    reflected, // dst
+                    IP4_ADDR_OFFSET, // dst offset
+                    IP4_ADDR_LEN); // len
+            // Set reflected packet's src IP to that of the original's dst IP
+            System.arraycopy(
+                    pkt, // src
+                    IP4_ADDR_OFFSET, // src offset
+                    reflected, // dst
+                    IP4_ADDR_OFFSET + IP4_ADDR_LEN, // dst offset
+                    IP4_ADDR_LEN); // len
+        }
+        return reflected;
+    }
+
+    /** Takes all captured packets, flips the src/dst, and re-injects them. */
+    public void reflectPackets() throws IOException {
+        synchronized (mPackets) {
+            for (byte[] pkt : mPackets) {
+                injectPacket(getReflectedPacket(pkt));
+            }
+        }
+    }
+
+    public void injectPacket(byte[] pkt) throws IOException {
+        FileOutputStream out = new FileOutputStream(mTunFd.getFileDescriptor());
+        out.write(pkt);
+        out.flush();
+    }
+
+    /** Resets the intercepted packets. */
+    public void reset() throws IOException {
+        synchronized (mPackets) {
+            mPackets.clear();
+        }
+    }
+}
diff --git a/tests/cts/net/jni/Android.bp b/tests/cts/net/jni/Android.bp
index baed48d..3953aeb 100644
--- a/tests/cts/net/jni/Android.bp
+++ b/tests/cts/net/jni/Android.bp
@@ -16,6 +16,7 @@
     name: "libnativedns_jni",
 
     srcs: ["NativeDnsJni.c"],
+    sdk_version: "current",
 
     shared_libs: [
         "libnativehelper_compat_libc++",
@@ -35,6 +36,7 @@
     name: "libnativemultinetwork_jni",
 
     srcs: ["NativeMultinetworkJni.cpp"],
+    sdk_version: "current",
     cflags: [
         "-Wall",
         "-Werror",
diff --git a/tests/cts/net/jni/NativeDnsJni.c b/tests/cts/net/jni/NativeDnsJni.c
index 6d3d1c3..4ec800e 100644
--- a/tests/cts/net/jni/NativeDnsJni.c
+++ b/tests/cts/net/jni/NativeDnsJni.c
@@ -19,7 +19,12 @@
 #include <netdb.h>
 #include <stdio.h>
 #include <string.h>
-#include <utils/Log.h>
+
+#include <android/log.h>
+
+#define LOG_TAG "NativeDns-JNI"
+#define LOGD(fmt, ...) \
+        __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, fmt, ##__VA_ARGS__)
 
 const char *GoogleDNSIpV4Address="8.8.8.8";
 const char *GoogleDNSIpV4Address2="8.8.4.4";
@@ -33,7 +38,7 @@
     struct addrinfo *answer;
 
     int res = getaddrinfo(node, service, NULL, &answer);
-    ALOGD("getaddrinfo(www.google.com) gave res=%d (%s)", res, gai_strerror(res));
+    LOGD("getaddrinfo(www.google.com) gave res=%d (%s)", res, gai_strerror(res));
     if (res != 0) return JNI_FALSE;
 
     // check for v4 & v6
@@ -47,12 +52,12 @@
                 inet_ntop(current->ai_family, &((struct sockaddr_in *)current->ai_addr)->sin_addr,
                         buf, sizeof(buf));
                 foundv4 = 1;
-                ALOGD("  %s", buf);
+                LOGD("  %s", buf);
             } else if (current->ai_addr->sa_family == AF_INET6) {
                 inet_ntop(current->ai_family, &((struct sockaddr_in6 *)current->ai_addr)->sin6_addr,
                         buf, sizeof(buf));
                 foundv6 = 1;
-                ALOGD("  %s", buf);
+                LOGD("  %s", buf);
             }
             current = current->ai_next;
         }
@@ -60,14 +65,14 @@
         freeaddrinfo(answer);
         answer = NULL;
         if (foundv4 != 1 && foundv6 != 1) {
-            ALOGD("getaddrinfo(www.google.com) didn't find either v4 or v6 address");
+            LOGD("getaddrinfo(www.google.com) didn't find either v4 or v6 address");
             return JNI_FALSE;
         }
     }
 
     node = "ipv6.google.com";
     res = getaddrinfo(node, service, NULL, &answer);
-    ALOGD("getaddrinfo(ipv6.google.com) gave res=%d", res);
+    LOGD("getaddrinfo(ipv6.google.com) gave res=%d", res);
     if (res != 0) return JNI_FALSE;
 
     {
@@ -79,12 +84,12 @@
             if (current->ai_addr->sa_family == AF_INET) {
                 inet_ntop(current->ai_family, &((struct sockaddr_in *)current->ai_addr)->sin_addr,
                         buf, sizeof(buf));
-                ALOGD("  %s", buf);
+                LOGD("  %s", buf);
                 foundv4 = 1;
             } else if (current->ai_addr->sa_family == AF_INET6) {
                 inet_ntop(current->ai_family, &((struct sockaddr_in6 *)current->ai_addr)->sin6_addr,
                         buf, sizeof(buf));
-                ALOGD("  %s", buf);
+                LOGD("  %s", buf);
                 foundv6 = 1;
             }
             current = current->ai_next;
@@ -93,7 +98,7 @@
         freeaddrinfo(answer);
         answer = NULL;
         if (foundv4 == 1 || foundv6 != 1) {
-            ALOGD("getaddrinfo(ipv6.google.com) didn't find only v6");
+            LOGD("getaddrinfo(ipv6.google.com) didn't find only v6");
             return JNI_FALSE;
         }
     }
@@ -116,12 +121,12 @@
 
     res = getnameinfo((const struct sockaddr*)&sa4, sizeof(sa4), buf, sizeof(buf), NULL, 0, flags);
     if (res != 0) {
-        ALOGD("getnameinfo(%s (GoogleDNS) ) gave error %d (%s)", GoogleDNSIpV4Address, res,
+        LOGD("getnameinfo(%s (GoogleDNS) ) gave error %d (%s)", GoogleDNSIpV4Address, res,
             gai_strerror(res));
         return JNI_FALSE;
     }
     if (strstr(buf, "google.com") == NULL && strstr(buf, "dns.google") == NULL) {
-        ALOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com or dns.google: %s",
+        LOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com or dns.google: %s",
             GoogleDNSIpV4Address, buf);
         return JNI_FALSE;
     }
@@ -129,12 +134,12 @@
     memset(buf, 0, sizeof(buf));
     res = getnameinfo((const struct sockaddr*)&sa6, sizeof(sa6), buf, sizeof(buf), NULL, 0, flags);
     if (res != 0) {
-        ALOGD("getnameinfo(%s (GoogleDNS) ) gave error %d (%s)", GoogleDNSIpV6Address2,
+        LOGD("getnameinfo(%s (GoogleDNS) ) gave error %d (%s)", GoogleDNSIpV6Address2,
             res, gai_strerror(res));
         return JNI_FALSE;
     }
     if (strstr(buf, "google.com") == NULL && strstr(buf, "dns.google") == NULL) {
-        ALOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com or dns.google: %s",
+        LOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com or dns.google: %s",
             GoogleDNSIpV6Address2, buf);
         return JNI_FALSE;
     }
@@ -142,11 +147,11 @@
     // gethostbyname
     struct hostent *my_hostent = gethostbyname("www.youtube.com");
     if (my_hostent == NULL) {
-        ALOGD("gethostbyname(www.youtube.com) gave null response");
+        LOGD("gethostbyname(www.youtube.com) gave null response");
         return JNI_FALSE;
     }
     if ((my_hostent->h_addr_list == NULL) || (*my_hostent->h_addr_list == NULL)) {
-        ALOGD("gethostbyname(www.youtube.com) gave 0 addresses");
+        LOGD("gethostbyname(www.youtube.com) gave 0 addresses");
         return JNI_FALSE;
     }
     {
@@ -154,7 +159,7 @@
         while (*current != NULL) {
             char buf[256];
             inet_ntop(my_hostent->h_addrtype, *current, buf, sizeof(buf));
-            ALOGD("gethostbyname(www.youtube.com) gave %s", buf);
+            LOGD("gethostbyname(www.youtube.com) gave %s", buf);
             current++;
         }
     }
@@ -164,11 +169,11 @@
     inet_pton(AF_INET6, GoogleDNSIpV6Address, addr6);
     my_hostent = gethostbyaddr(addr6, sizeof(addr6), AF_INET6);
     if (my_hostent == NULL) {
-        ALOGD("gethostbyaddr(%s (GoogleDNS) ) gave null response", GoogleDNSIpV6Address);
+        LOGD("gethostbyaddr(%s (GoogleDNS) ) gave null response", GoogleDNSIpV6Address);
         return JNI_FALSE;
     }
 
-    ALOGD("gethostbyaddr(%s (GoogleDNS) ) gave %s for name", GoogleDNSIpV6Address,
+    LOGD("gethostbyaddr(%s (GoogleDNS) ) gave %s for name", GoogleDNSIpV6Address,
         my_hostent->h_name ? my_hostent->h_name : "null");
 
     if (my_hostent->h_name == NULL) return JNI_FALSE;
diff --git a/tests/cts/net/jni/NativeMultinetworkJni.cpp b/tests/cts/net/jni/NativeMultinetworkJni.cpp
index 2832c3d..cd94709 100644
--- a/tests/cts/net/jni/NativeMultinetworkJni.cpp
+++ b/tests/cts/net/jni/NativeMultinetworkJni.cpp
@@ -16,7 +16,6 @@
 
 
 #define LOG_TAG "MultinetworkApiTest"
-#include <utils/Log.h>
 
 #include <arpa/inet.h>
 #include <arpa/nameser.h>
@@ -34,9 +33,13 @@
 
 #include <string>
 
+#include <android/log.h>
 #include <android/multinetwork.h>
 #include <nativehelper/JNIHelp.h>
 
+#define LOGD(fmt, ...) \
+        __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, fmt, ##__VA_ARGS__)
+
 #define EXPECT_GE(env, actual, expected, msg)                        \
     do {                                                             \
         if (actual < expected) {                                     \
@@ -138,7 +141,7 @@
     uint8_t buf[MAXPACKET] = {};
     int res = getAsyncResponse(env, fd, TIMEOUT_MS, &rcode, buf, MAXPACKET);
     if (res != expectedErrno) {
-        ALOGD("res:%d, expectedErrno = %d", res, expectedErrno);
+        LOGD("res:%d, expectedErrno = %d", res, expectedErrno);
         return (res > 0) ? -EREMOTEIO : res;
     }
     return 0;
@@ -326,7 +329,7 @@
     const int saved_errno = errno;
     freeaddrinfo(res);
 
-    ALOGD("android_getaddrinfofornetwork(%" PRIu64 ", %s) returned rval=%d errno=%d",
+    LOGD("android_getaddrinfofornetwork(%" PRIu64 ", %s) returned rval=%d errno=%d",
           handle, kHostname, rval, saved_errno);
     return rval == 0 ? 0 : -saved_errno;
 }
@@ -339,7 +342,7 @@
     errno = 0;
     int rval = android_setprocnetwork(handle);
     const int saved_errno = errno;
-    ALOGD("android_setprocnetwork(%" PRIu64 ") returned rval=%d errno=%d",
+    LOGD("android_setprocnetwork(%" PRIu64 ") returned rval=%d errno=%d",
           handle, rval, saved_errno);
     return rval == 0 ? 0 : -saved_errno;
 }
@@ -352,14 +355,14 @@
     errno = 0;
     int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
     if (fd < 0) {
-        ALOGD("socket() failed, errno=%d", errno);
+        LOGD("socket() failed, errno=%d", errno);
         return -errno;
     }
 
     errno = 0;
     int rval = android_setsocknetwork(handle, fd);
     const int saved_errno = errno;
-    ALOGD("android_setprocnetwork(%" PRIu64 ", %d) returned rval=%d errno=%d",
+    LOGD("android_setprocnetwork(%" PRIu64 ", %d) returned rval=%d errno=%d",
           handle, fd, rval, saved_errno);
     close(fd);
     return rval == 0 ? 0 : -saved_errno;
@@ -404,7 +407,7 @@
     static const char kPort[] = "443";
     int rval = android_getaddrinfofornetwork(handle, kHostname, kPort, &kHints, &res);
     if (rval != 0) {
-        ALOGD("android_getaddrinfofornetwork(%llu, %s) returned rval=%d errno=%d",
+        LOGD("android_getaddrinfofornetwork(%llu, %s) returned rval=%d errno=%d",
               handle, kHostname, rval, errno);
         freeaddrinfo(res);
         return -errno;
@@ -413,14 +416,14 @@
     // Rely upon getaddrinfo sorting the best destination to the front.
     int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
     if (fd < 0) {
-        ALOGD("socket(%d, %d, %d) failed, errno=%d",
+        LOGD("socket(%d, %d, %d) failed, errno=%d",
               res->ai_family, res->ai_socktype, res->ai_protocol, errno);
         freeaddrinfo(res);
         return -errno;
     }
 
     rval = android_setsocknetwork(handle, fd);
-    ALOGD("android_setprocnetwork(%llu, %d) returned rval=%d errno=%d",
+    LOGD("android_setprocnetwork(%llu, %d) returned rval=%d errno=%d",
           handle, fd, rval, errno);
     if (rval != 0) {
         close(fd);
@@ -430,7 +433,7 @@
 
     char addrstr[kSockaddrStrLen+1];
     sockaddr_ntop(res->ai_addr, res->ai_addrlen, addrstr, sizeof(addrstr));
-    ALOGD("Attempting connect() to %s ...", addrstr);
+    LOGD("Attempting connect() to %s ...", addrstr);
 
     rval = connect(fd, res->ai_addr, res->ai_addrlen);
     if (rval != 0) {
@@ -447,7 +450,7 @@
         return -errno;
     }
     sockaddr_ntop((const struct sockaddr *)&src_addr, sizeof(src_addr), addrstr, sizeof(addrstr));
-    ALOGD("... from %s", addrstr);
+    LOGD("... from %s", addrstr);
 
     // Don't let reads or writes block indefinitely.
     const struct timeval timeo = { 2, 0 };  // 2 seconds
@@ -479,7 +482,7 @@
         sent = send(fd, quic_packet, sizeof(quic_packet), 0);
         if (sent < (ssize_t)sizeof(quic_packet)) {
             errnum = errno;
-            ALOGD("send(QUIC packet) returned sent=%zd, errno=%d", sent, errnum);
+            LOGD("send(QUIC packet) returned sent=%zd, errno=%d", sent, errnum);
             close(fd);
             return -errnum;
         }
@@ -489,14 +492,14 @@
             break;
         } else {
             errnum = errno;
-            ALOGD("[%d/%d] recv(QUIC response) returned rcvd=%zd, errno=%d",
+            LOGD("[%d/%d] recv(QUIC response) returned rcvd=%zd, errno=%d",
                   i + 1, MAX_RETRIES, rcvd, errnum);
         }
     }
     if (rcvd < 9) {
-        ALOGD("QUIC UDP %s: sent=%zd but rcvd=%zd, errno=%d", kPort, sent, rcvd, errnum);
+        LOGD("QUIC UDP %s: sent=%zd but rcvd=%zd, errno=%d", kPort, sent, rcvd, errnum);
         if (rcvd <= 0) {
-            ALOGD("Does this network block UDP port %s?", kPort);
+            LOGD("Does this network block UDP port %s?", kPort);
         }
         close(fd);
         return -EPROTO;
@@ -504,7 +507,7 @@
 
     int conn_id_cmp = memcmp(quic_packet + 1, response + 1, 8);
     if (conn_id_cmp != 0) {
-        ALOGD("sent and received connection IDs do not match");
+        LOGD("sent and received connection IDs do not match");
         close(fd);
         return -EPROTO;
     }
diff --git a/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt b/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt
new file mode 100644
index 0000000..4418e17
--- /dev/null
+++ b/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt
@@ -0,0 +1,254 @@
+/*
+ * 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
+
+import android.Manifest.permission.NETWORK_SETTINGS
+import android.Manifest.permission.READ_DEVICE_CONFIG
+import android.Manifest.permission.WRITE_DEVICE_CONFIG
+import android.content.pm.PackageManager.FEATURE_TELEPHONY
+import android.content.pm.PackageManager.FEATURE_WIFI
+import android.net.ConnectivityManager
+import android.net.ConnectivityManager.NetworkCallback
+import android.net.Network
+import android.net.NetworkCapabilities
+import android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL
+import android.net.NetworkCapabilities.TRANSPORT_WIFI
+import android.net.NetworkRequest
+import android.net.Uri
+import android.net.cts.util.CtsNetUtils
+import android.net.wifi.WifiManager
+import android.os.ConditionVariable
+import android.platform.test.annotations.AppModeFull
+import android.provider.DeviceConfig
+import android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY
+import android.text.TextUtils
+import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
+import androidx.test.runner.AndroidJUnit4
+import com.android.compatibility.common.util.SystemUtil
+import fi.iki.elonen.NanoHTTPD
+import fi.iki.elonen.NanoHTTPD.Response.IStatus
+import fi.iki.elonen.NanoHTTPD.Response.Status
+import junit.framework.AssertionFailedError
+import org.junit.After
+import org.junit.Assume.assumeTrue
+import org.junit.Before
+import org.junit.runner.RunWith
+import java.util.concurrent.CompletableFuture
+import java.util.concurrent.TimeUnit
+import java.util.concurrent.TimeoutException
+import kotlin.test.Test
+import kotlin.test.assertNotEquals
+import kotlin.test.assertTrue
+
+private const val TEST_CAPTIVE_PORTAL_HTTPS_URL_SETTING = "test_captive_portal_https_url"
+private const val TEST_CAPTIVE_PORTAL_HTTP_URL_SETTING = "test_captive_portal_http_url"
+private const val TEST_URL_EXPIRATION_TIME = "test_url_expiration_time"
+
+private const val TEST_HTTPS_URL_PATH = "https_path"
+private const val TEST_HTTP_URL_PATH = "http_path"
+private const val TEST_PORTAL_URL_PATH = "portal_path"
+
+private const val LOCALHOST_HOSTNAME = "localhost"
+
+// Re-connecting to the AP, obtaining an IP address, revalidating can take a long time
+private const val WIFI_CONNECT_TIMEOUT_MS = 120_000L
+private const val TEST_TIMEOUT_MS = 10_000L
+
+private fun <T> CompletableFuture<T>.assertGet(timeoutMs: Long, message: String): T {
+    try {
+        return get(timeoutMs, TimeUnit.MILLISECONDS)
+    } catch (e: TimeoutException) {
+        throw AssertionFailedError(message)
+    }
+}
+
+@AppModeFull(reason = "WRITE_DEVICE_CONFIG permission can't be granted to instant apps")
+@RunWith(AndroidJUnit4::class)
+class CaptivePortalTest {
+    private val context: android.content.Context by lazy { getInstrumentation().context }
+    private val wm by lazy { context.getSystemService(WifiManager::class.java) }
+    private val cm by lazy { context.getSystemService(ConnectivityManager::class.java) }
+    private val pm by lazy { context.packageManager }
+    private val utils by lazy { CtsNetUtils(context) }
+
+    private val server = HttpServer()
+
+    @Before
+    fun setUp() {
+        doAsShell(READ_DEVICE_CONFIG) {
+            // Verify that the test URLs are not normally set on the device, but do not fail if the
+            // test URLs are set to what this test uses (URLs on localhost), in case the test was
+            // interrupted manually and rerun.
+            assertEmptyOrLocalhostUrl(TEST_CAPTIVE_PORTAL_HTTPS_URL_SETTING)
+            assertEmptyOrLocalhostUrl(TEST_CAPTIVE_PORTAL_HTTP_URL_SETTING)
+        }
+        clearTestUrls()
+        server.start()
+    }
+
+    @After
+    fun tearDown() {
+        clearTestUrls()
+        server.stop()
+    }
+
+    private fun assertEmptyOrLocalhostUrl(urlKey: String) {
+        val url = DeviceConfig.getProperty(NAMESPACE_CONNECTIVITY, urlKey)
+        assertTrue(TextUtils.isEmpty(url) || LOCALHOST_HOSTNAME == Uri.parse(url).host,
+                "$urlKey must not be set in production scenarios (current value: $url)")
+    }
+
+    private fun clearTestUrls() {
+        setHttpsUrl(null)
+        setHttpUrl(null)
+        setUrlExpiration(null)
+    }
+
+    @Test
+    fun testCaptivePortalIsNotDefaultNetwork() {
+        assumeTrue(pm.hasSystemFeature(FEATURE_TELEPHONY))
+        assumeTrue(pm.hasSystemFeature(FEATURE_WIFI))
+        utils.connectToWifi()
+        utils.connectToCell()
+
+        // Have network validation use a local server that serves a HTTPS error / HTTP redirect
+        server.addResponse(TEST_PORTAL_URL_PATH, Status.OK,
+                content = "Test captive portal content")
+        server.addResponse(TEST_HTTPS_URL_PATH, Status.INTERNAL_ERROR)
+        server.addResponse(TEST_HTTP_URL_PATH, Status.REDIRECT,
+                locationHeader = server.makeUrl(TEST_PORTAL_URL_PATH))
+        setHttpsUrl(server.makeUrl(TEST_HTTPS_URL_PATH))
+        setHttpUrl(server.makeUrl(TEST_HTTP_URL_PATH))
+        // URL expiration needs to be in the next 10 minutes
+        setUrlExpiration(System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(9))
+
+        // Expect the portal content to be fetched at some point after detecting the portal.
+        // Some implementations may fetch the URL before startCaptivePortalApp is called.
+        val portalContentRequestCv = server.addExpectRequestCv(TEST_PORTAL_URL_PATH)
+
+        // Wait for a captive portal to be detected on the network
+        val wifiNetworkFuture = CompletableFuture<Network>()
+        val wifiCb = object : NetworkCallback() {
+            override fun onCapabilitiesChanged(
+                network: Network,
+                nc: NetworkCapabilities
+            ) {
+                if (nc.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) {
+                    wifiNetworkFuture.complete(network)
+                }
+            }
+        }
+        cm.requestNetwork(NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(), wifiCb)
+
+        try {
+            reconnectWifi()
+            val network = wifiNetworkFuture.assertGet(WIFI_CONNECT_TIMEOUT_MS,
+                    "Captive portal not detected after ${WIFI_CONNECT_TIMEOUT_MS}ms")
+
+            val wifiDefaultMessage = "Wifi should not be the default network when a captive " +
+                    "portal was detected and another network (mobile data) can provide internet " +
+                    "access."
+            assertNotEquals(network, cm.activeNetwork, wifiDefaultMessage)
+
+            doAsShell(NETWORK_SETTINGS) { cm.startCaptivePortalApp(network) }
+            assertTrue(portalContentRequestCv.block(TEST_TIMEOUT_MS), "The captive portal login " +
+                    "page was still not fetched ${TEST_TIMEOUT_MS}ms after startCaptivePortalApp.")
+
+            assertNotEquals(network, cm.activeNetwork, wifiDefaultMessage)
+        } finally {
+            cm.unregisterNetworkCallback(wifiCb)
+            server.stop()
+            // disconnectFromCell should be called after connectToCell
+            utils.disconnectFromCell()
+        }
+
+        clearTestUrls()
+        reconnectWifi()
+    }
+
+    private fun setHttpsUrl(url: String?) = setConfig(TEST_CAPTIVE_PORTAL_HTTPS_URL_SETTING, url)
+    private fun setHttpUrl(url: String?) = setConfig(TEST_CAPTIVE_PORTAL_HTTP_URL_SETTING, url)
+    private fun setUrlExpiration(timestamp: Long?) = setConfig(TEST_URL_EXPIRATION_TIME,
+            timestamp?.toString())
+
+    private fun setConfig(configKey: String, value: String?) {
+        doAsShell(WRITE_DEVICE_CONFIG) {
+            DeviceConfig.setProperty(
+                    NAMESPACE_CONNECTIVITY, configKey, value, false /* makeDefault */)
+        }
+    }
+
+    private fun doAsShell(vararg permissions: String, action: () -> Unit) {
+        // Wrap the below call to allow for more kotlin-like syntax
+        SystemUtil.runWithShellPermissionIdentity(action, permissions)
+    }
+
+    private fun reconnectWifi() {
+        doAsShell(NETWORK_SETTINGS) {
+            assertTrue(wm.disconnect())
+            assertTrue(wm.reconnect())
+        }
+    }
+
+    /**
+     * A minimal HTTP server running on localhost (loopback), on a random available port.
+     */
+    private class HttpServer : NanoHTTPD("localhost", 0 /* auto-select the port */) {
+        // Map of URL path -> HTTP response code
+        private val responses = HashMap<String, Response>()
+
+        // Map of path -> CV to open as soon as a request to the path is received
+        private val waitForRequestCv = HashMap<String, ConditionVariable>()
+
+        /**
+         * Create a URL string that, when fetched, will hit this server with the given URL [path].
+         */
+        fun makeUrl(path: String): String {
+            return Uri.Builder()
+                    .scheme("http")
+                    .encodedAuthority("localhost:$listeningPort")
+                    .query(path)
+                    .build()
+                    .toString()
+        }
+
+        fun addResponse(
+            path: String,
+            statusCode: IStatus,
+            locationHeader: String? = null,
+            content: String = ""
+        ) {
+            val response = newFixedLengthResponse(statusCode, "text/plain", content)
+            locationHeader?.let { response.addHeader("Location", it) }
+            responses[path] = response
+        }
+
+        /**
+         * Create a [ConditionVariable] that will open when a request to [path] is received.
+         */
+        fun addExpectRequestCv(path: String): ConditionVariable {
+            return ConditionVariable().apply { waitForRequestCv[path] = this }
+        }
+
+        override fun serve(session: IHTTPSession): Response {
+            waitForRequestCv[session.queryParameterString]?.open()
+            return responses[session.queryParameterString]
+                    // Default response is a 404
+                    ?: super.serve(session)
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
index 0a80047..9d35705 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
@@ -18,15 +18,17 @@
 
 import static android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback;
 
-import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
 
 import android.content.Context;
 import android.net.ConnectivityDiagnosticsManager;
 import android.net.NetworkRequest;
+import android.os.Build;
 
 import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+import com.android.testutils.DevSdkIgnoreRunner;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -34,7 +36,8 @@
 
 import java.util.concurrent.Executor;
 
-@RunWith(AndroidJUnit4.class)
+@RunWith(DevSdkIgnoreRunner.class)
+@IgnoreUpTo(Build.VERSION_CODES.Q) // ConnectivityDiagnosticsManager did not exist in Q
 public class ConnectivityDiagnosticsManagerTest {
     private static final Executor INLINE_EXECUTOR = x -> x.run();
     private static final NetworkRequest DEFAULT_REQUEST = new NetworkRequest.Builder().build();
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index fa7e138..1ee08ff 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -639,11 +639,14 @@
         }
     }
 
-    private void waitForActiveNetworkMetered(boolean requestedMeteredness) throws Exception {
+    private void waitForActiveNetworkMetered(int targetTransportType, boolean requestedMeteredness)
+            throws Exception {
         final CountDownLatch latch = new CountDownLatch(1);
         final NetworkCallback networkCallback = new NetworkCallback() {
             @Override
             public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) {
+                if (!nc.hasTransport(targetTransportType)) return;
+
                 final boolean metered = !nc.hasCapability(NET_CAPABILITY_NOT_METERED);
                 if (metered == requestedMeteredness) {
                     latch.countDown();
@@ -709,7 +712,7 @@
     @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
     public void testGetMultipathPreference() throws Exception {
         final ContentResolver resolver = mContext.getContentResolver();
-        final Network network = ensureWifiConnected();
+        ensureWifiConnected();
         final String ssid = unquoteSSID(mWifiManager.getConnectionInfo().getSSID());
         final String oldMeteredSetting = getWifiMeteredStatus(ssid);
         final String oldMeteredMultipathPreference = Settings.Global.getString(
@@ -720,7 +723,11 @@
             Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE,
                     Integer.toString(newMeteredPreference));
             setWifiMeteredStatus(ssid, "true");
-            waitForActiveNetworkMetered(true);
+            waitForActiveNetworkMetered(TRANSPORT_WIFI, true);
+            // Wifi meterness changes from unmetered to metered will disconnect and reconnect since
+            // R.
+            final Network network = ensureWifiConnected();
+            assertEquals(ssid, unquoteSSID(mWifiManager.getConnectionInfo().getSSID()));
             assertEquals(mCm.getNetworkCapabilities(network).hasCapability(
                     NET_CAPABILITY_NOT_METERED), false);
             assertMultipathPreferenceIsEventually(network, initialMeteredPreference,
@@ -736,7 +743,8 @@
                     oldMeteredPreference, newMeteredPreference);
 
             setWifiMeteredStatus(ssid, "false");
-            waitForActiveNetworkMetered(false);
+            // No disconnect from unmetered to metered.
+            waitForActiveNetworkMetered(TRANSPORT_WIFI, false);
             assertEquals(mCm.getNetworkCapabilities(network).hasCapability(
                     NET_CAPABILITY_NOT_METERED), true);
             assertMultipathPreferenceIsEventually(network, newMeteredPreference,
diff --git a/tests/cts/net/src/android/net/cts/DhcpInfoTest.java b/tests/cts/net/src/android/net/cts/DhcpInfoTest.java
deleted file mode 100644
index 085fdd9..0000000
--- a/tests/cts/net/src/android/net/cts/DhcpInfoTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2009 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;
-
-import android.net.DhcpInfo;
-import android.test.AndroidTestCase;
-
-public class DhcpInfoTest extends AndroidTestCase {
-
-    public void testConstructor() {
-        new DhcpInfo();
-    }
-
-    public void testToString() {
-        String expectedDefault = "ipaddr 0.0.0.0 gateway 0.0.0.0 netmask 0.0.0.0 dns1 0.0.0.0 "
-                + "dns2 0.0.0.0 DHCP server 0.0.0.0 lease 0 seconds";
-        String STR_ADDR1 = "255.255.255.255";
-        String STR_ADDR2 = "127.0.0.1";
-        String STR_ADDR3 = "192.168.1.1";
-        String STR_ADDR4 = "192.168.1.0";
-        int leaseTime = 9999;
-        String expected = "ipaddr " + STR_ADDR1 + " gateway " + STR_ADDR2 + " netmask "
-                + STR_ADDR3 + " dns1 " + STR_ADDR4 + " dns2 " + STR_ADDR4 + " DHCP server "
-                + STR_ADDR2 + " lease " + leaseTime + " seconds";
-
-        DhcpInfo dhcpInfo = new DhcpInfo();
-
-        // Test default string.
-        assertEquals(expectedDefault, dhcpInfo.toString());
-
-        dhcpInfo.ipAddress = ipToInteger(STR_ADDR1);
-        dhcpInfo.gateway = ipToInteger(STR_ADDR2);
-        dhcpInfo.netmask = ipToInteger(STR_ADDR3);
-        dhcpInfo.dns1 = ipToInteger(STR_ADDR4);
-        dhcpInfo.dns2 = ipToInteger(STR_ADDR4);
-        dhcpInfo.serverAddress = ipToInteger(STR_ADDR2);
-        dhcpInfo.leaseDuration = leaseTime;
-
-        // Test with new values
-        assertEquals(expected, dhcpInfo.toString());
-    }
-
-    private int ipToInteger(String ipString) {
-        String ipSegs[] = ipString.split("[.]");
-        int tmp = Integer.parseInt(ipSegs[3]) << 24 | Integer.parseInt(ipSegs[2]) << 16 |
-            Integer.parseInt(ipSegs[1]) << 8 | Integer.parseInt(ipSegs[0]);
-        return tmp;
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java
index 999d2f1..1d83dda 100644
--- a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java
+++ b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java
@@ -192,9 +192,8 @@
         // Build a network request
         NetworkRequest nr =
                 new NetworkRequest.Builder()
+                        .clearCapabilities()
                         .addTransportType(TRANSPORT_TEST)
-                        .removeCapability(NET_CAPABILITY_TRUSTED)
-                        .removeCapability(NET_CAPABILITY_NOT_VPN)
                         .setNetworkSpecifier(ifname)
                         .build();
 
diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
new file mode 100644
index 0000000..03b961b
--- /dev/null
+++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
@@ -0,0 +1,595 @@
+/*
+ * 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
+
+import android.app.Instrumentation
+import android.content.Context
+import android.net.ConnectivityManager
+import android.net.KeepalivePacketData
+import android.net.LinkAddress
+import android.net.LinkProperties
+import android.net.Network
+import android.net.NetworkAgent
+import android.net.NetworkAgent.CMD_ADD_KEEPALIVE_PACKET_FILTER
+import android.net.NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT
+import android.net.NetworkAgent.CMD_REMOVE_KEEPALIVE_PACKET_FILTER
+import android.net.NetworkAgent.CMD_REPORT_NETWORK_STATUS
+import android.net.NetworkAgent.CMD_SAVE_ACCEPT_UNVALIDATED
+import android.net.NetworkAgent.CMD_START_SOCKET_KEEPALIVE
+import android.net.NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE
+import android.net.NetworkAgent.INVALID_NETWORK
+import android.net.NetworkAgent.VALID_NETWORK
+import android.net.NetworkAgentConfig
+import android.net.NetworkCapabilities
+import android.net.NetworkProvider
+import android.net.NetworkRequest
+import android.net.SocketKeepalive
+import android.net.StringNetworkSpecifier
+import android.net.Uri
+import android.os.Build
+import android.os.Bundle
+import android.os.Handler
+import android.os.HandlerThread
+import android.os.Looper
+import android.os.Message
+import android.os.Messenger
+import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnAddKeepalivePacketFilter
+import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnAutomaticReconnectDisabled
+import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnBandwidthUpdateRequested
+import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnNetworkUnwanted
+import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnRemoveKeepalivePacketFilter
+import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnSaveAcceptUnvalidated
+import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnSignalStrengthThresholdsUpdated
+import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStartSocketKeepalive
+import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStopSocketKeepalive
+import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnValidationStatus
+import androidx.test.InstrumentationRegistry
+import androidx.test.runner.AndroidJUnit4
+import com.android.internal.util.AsyncChannel
+import com.android.testutils.ArrayTrackRecord
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.RecorderCallback.CallbackEntry.Available
+import com.android.testutils.RecorderCallback.CallbackEntry.Lost
+import com.android.testutils.TestableNetworkCallback
+import java.util.UUID
+import org.junit.After
+import org.junit.Assert.assertArrayEquals
+import org.junit.Assert.fail
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import java.net.InetAddress
+import java.time.Duration
+import kotlin.test.assertEquals
+import kotlin.test.assertFalse
+import kotlin.test.assertFailsWith
+import kotlin.test.assertNotNull
+import kotlin.test.assertNull
+import kotlin.test.assertTrue
+
+// This test doesn't really have a constraint on how fast the methods should return. If it's
+// going to fail, it will simply wait forever, so setting a high timeout lowers the flake ratio
+// without affecting the run time of successful runs. Thus, set a very high timeout.
+private const val DEFAULT_TIMEOUT_MS = 5000L
+// When waiting for a NetworkCallback to determine there was no timeout, waiting is the
+// only possible thing (the relevant handler is the one in the real ConnectivityService,
+// and then there is the Binder call), so have a short timeout for this as it will be
+// exhausted every time.
+private const val NO_CALLBACK_TIMEOUT = 200L
+// Any legal score (0~99) for the test network would do, as it is going to be kept up by the
+// requests filed by the test and should never match normal internet requests. 70 is the default
+// score of Ethernet networks, it's as good a value as any other.
+private const val TEST_NETWORK_SCORE = 70
+private const val BETTER_NETWORK_SCORE = 75
+private const val FAKE_NET_ID = 1098
+private val instrumentation: Instrumentation
+    get() = InstrumentationRegistry.getInstrumentation()
+private val context: Context
+    get() = InstrumentationRegistry.getContext()
+private fun Message(what: Int, arg1: Int, arg2: Int, obj: Any?) = Message.obtain().also {
+    it.what = what
+    it.arg1 = arg1
+    it.arg2 = arg2
+    it.obj = obj
+}
+
+@RunWith(AndroidJUnit4::class)
+class NetworkAgentTest {
+    @Rule @JvmField
+    val ignoreRule = DevSdkIgnoreRule(ignoreClassUpTo = Build.VERSION_CODES.Q)
+
+    private val LOCAL_IPV4_ADDRESS = InetAddress.parseNumericAddress("192.0.2.1")
+    private val REMOTE_IPV4_ADDRESS = InetAddress.parseNumericAddress("192.0.2.2")
+
+    private val mCM = context.getSystemService(ConnectivityManager::class.java)
+    private val mHandlerThread = HandlerThread("${javaClass.simpleName} handler thread")
+    private val mFakeConnectivityService by lazy { FakeConnectivityService(mHandlerThread.looper) }
+
+    private class Provider(context: Context, looper: Looper) :
+            NetworkProvider(context, looper, "NetworkAgentTest NetworkProvider")
+
+    private val agentsToCleanUp = mutableListOf<NetworkAgent>()
+    private val callbacksToCleanUp = mutableListOf<TestableNetworkCallback>()
+
+    @Before
+    fun setUp() {
+        instrumentation.getUiAutomation().adoptShellPermissionIdentity()
+        mHandlerThread.start()
+    }
+
+    @After
+    fun tearDown() {
+        agentsToCleanUp.forEach { it.unregister() }
+        callbacksToCleanUp.forEach { mCM.unregisterNetworkCallback(it) }
+        mHandlerThread.quitSafely()
+        instrumentation.getUiAutomation().dropShellPermissionIdentity()
+    }
+
+    /**
+     * A fake that helps simulating ConnectivityService talking to a harnessed agent.
+     * This fake only supports speaking to one harnessed agent at a time because it
+     * only keeps track of one async channel.
+     */
+    private class FakeConnectivityService(looper: Looper) {
+        private val CMD_EXPECT_DISCONNECT = 1
+        private var disconnectExpected = false
+        private val msgHistory = ArrayTrackRecord<Message>().newReadHead()
+        private val asyncChannel = AsyncChannel()
+        private val handler = object : Handler(looper) {
+            override fun handleMessage(msg: Message) {
+                msgHistory.add(Message.obtain(msg)) // make a copy as the original will be recycled
+                when (msg.what) {
+                    CMD_EXPECT_DISCONNECT -> disconnectExpected = true
+                    AsyncChannel.CMD_CHANNEL_HALF_CONNECTED ->
+                        asyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION)
+                    AsyncChannel.CMD_CHANNEL_DISCONNECTED ->
+                        if (!disconnectExpected) {
+                            fail("Agent unexpectedly disconnected")
+                        } else {
+                            disconnectExpected = false
+                        }
+                }
+            }
+        }
+
+        fun connect(agentMsngr: Messenger) = asyncChannel.connect(context, handler, agentMsngr)
+
+        fun disconnect() = asyncChannel.disconnect()
+
+        fun sendMessage(what: Int, arg1: Int = 0, arg2: Int = 0, obj: Any? = null) =
+            asyncChannel.sendMessage(Message(what, arg1, arg2, obj))
+
+        fun expectMessage(what: Int) =
+            assertNotNull(msgHistory.poll(DEFAULT_TIMEOUT_MS) { it.what == what })
+
+        fun willExpectDisconnectOnce() = handler.sendEmptyMessage(CMD_EXPECT_DISCONNECT)
+    }
+
+    private open class TestableNetworkAgent(
+        looper: Looper,
+        val nc: NetworkCapabilities,
+        val lp: LinkProperties,
+        conf: NetworkAgentConfig
+    ) : NetworkAgent(context, looper, TestableNetworkAgent::class.java.simpleName /* tag */,
+            nc, lp, TEST_NETWORK_SCORE, conf, Provider(context, looper)) {
+        private val history = ArrayTrackRecord<CallbackEntry>().newReadHead()
+
+        sealed class CallbackEntry {
+            object OnBandwidthUpdateRequested : CallbackEntry()
+            object OnNetworkUnwanted : CallbackEntry()
+            data class OnAddKeepalivePacketFilter(
+                val slot: Int,
+                val packet: KeepalivePacketData
+            ) : CallbackEntry()
+            data class OnRemoveKeepalivePacketFilter(val slot: Int) : CallbackEntry()
+            data class OnStartSocketKeepalive(
+                val slot: Int,
+                val interval: Int,
+                val packet: KeepalivePacketData
+            ) : CallbackEntry()
+            data class OnStopSocketKeepalive(val slot: Int) : CallbackEntry()
+            data class OnSaveAcceptUnvalidated(val accept: Boolean) : CallbackEntry()
+            object OnAutomaticReconnectDisabled : CallbackEntry()
+            data class OnValidationStatus(val status: Int, val uri: Uri?) : CallbackEntry()
+            data class OnSignalStrengthThresholdsUpdated(val thresholds: IntArray) : CallbackEntry()
+        }
+
+        fun getName(): String? = (nc.getNetworkSpecifier() as? StringNetworkSpecifier)?.specifier
+
+        override fun onBandwidthUpdateRequested() {
+            history.add(OnBandwidthUpdateRequested)
+        }
+
+        override fun onNetworkUnwanted() {
+            history.add(OnNetworkUnwanted)
+        }
+
+        override fun onAddKeepalivePacketFilter(slot: Int, packet: KeepalivePacketData) {
+            history.add(OnAddKeepalivePacketFilter(slot, packet))
+        }
+
+        override fun onRemoveKeepalivePacketFilter(slot: Int) {
+            history.add(OnRemoveKeepalivePacketFilter(slot))
+        }
+
+        override fun onStartSocketKeepalive(
+            slot: Int,
+            interval: Duration,
+            packet: KeepalivePacketData
+        ) {
+            history.add(OnStartSocketKeepalive(slot, interval.seconds.toInt(), packet))
+        }
+
+        override fun onStopSocketKeepalive(slot: Int) {
+            history.add(OnStopSocketKeepalive(slot))
+        }
+
+        override fun onSaveAcceptUnvalidated(accept: Boolean) {
+            history.add(OnSaveAcceptUnvalidated(accept))
+        }
+
+        override fun onAutomaticReconnectDisabled() {
+            history.add(OnAutomaticReconnectDisabled)
+        }
+
+        override fun onSignalStrengthThresholdsUpdated(thresholds: IntArray) {
+            history.add(OnSignalStrengthThresholdsUpdated(thresholds))
+        }
+
+        fun expectEmptySignalStrengths() {
+            expectCallback<OnSignalStrengthThresholdsUpdated>().let {
+                // intArrayOf() without arguments makes an empty array
+                assertArrayEquals(intArrayOf(), it.thresholds)
+            }
+        }
+
+        override fun onValidationStatus(status: Int, uri: Uri?) {
+            history.add(OnValidationStatus(status, uri))
+        }
+
+        // Expects the initial validation event that always occurs immediately after registering
+        // a NetworkAgent whose network does not require validation (which test networks do
+        // not, since they lack the INTERNET capability). It always contains the default argument
+        // for the URI.
+        fun expectNoInternetValidationStatus() = expectCallback<OnValidationStatus>().let {
+            assertEquals(it.status, VALID_NETWORK)
+            // The returned Uri is parsed from the empty string, which means it's an
+            // instance of the (private) Uri.StringUri. There are no real good ways
+            // to check this, the least bad is to just convert it to a string and
+            // make sure it's empty.
+            assertEquals("", it.uri.toString())
+        }
+
+        inline fun <reified T : CallbackEntry> expectCallback(): T {
+            val foundCallback = history.poll(DEFAULT_TIMEOUT_MS)
+            assertTrue(foundCallback is T, "Expected ${T::class} but found $foundCallback")
+            return foundCallback
+        }
+
+        fun assertNoCallback() {
+            assertTrue(waitForIdle(DEFAULT_TIMEOUT_MS),
+                    "Handler didn't became idle after ${DEFAULT_TIMEOUT_MS}ms")
+            assertNull(history.peek())
+        }
+    }
+
+    private fun requestNetwork(request: NetworkRequest, callback: TestableNetworkCallback) {
+        mCM.requestNetwork(request, callback)
+        callbacksToCleanUp.add(callback)
+    }
+
+    private fun registerNetworkCallback(
+        request: NetworkRequest,
+        callback: TestableNetworkCallback
+    ) {
+        mCM.registerNetworkCallback(request, callback)
+        callbacksToCleanUp.add(callback)
+    }
+
+    private fun createNetworkAgent(name: String? = null): TestableNetworkAgent {
+        val nc = NetworkCapabilities().apply {
+            addTransportType(NetworkCapabilities.TRANSPORT_TEST)
+            removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
+            removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+            addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)
+            addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)
+            addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
+            if (null != name) {
+                setNetworkSpecifier(StringNetworkSpecifier(name))
+            }
+        }
+        val lp = LinkProperties().apply {
+            addLinkAddress(LinkAddress(LOCAL_IPV4_ADDRESS, 0))
+        }
+        val config = NetworkAgentConfig.Builder().build()
+        return TestableNetworkAgent(mHandlerThread.looper, nc, lp, config).also {
+            agentsToCleanUp.add(it)
+        }
+    }
+
+    private fun createConnectedNetworkAgent(name: String? = null):
+            Pair<TestableNetworkAgent, TestableNetworkCallback> {
+        val request: NetworkRequest = NetworkRequest.Builder()
+                .clearCapabilities()
+                .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
+                .build()
+        val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
+        requestNetwork(request, callback)
+        val agent = createNetworkAgent(name)
+        agent.register()
+        agent.markConnected()
+        return agent to callback
+    }
+
+    private fun createNetworkAgentWithFakeCS() = createNetworkAgent().also {
+        mFakeConnectivityService.connect(it.registerForTest(Network(FAKE_NET_ID)))
+    }
+
+    @Test
+    fun testConnectAndUnregister() {
+        val (agent, callback) = createConnectedNetworkAgent()
+        callback.expectAvailableThenValidatedCallbacks(agent.network)
+        agent.expectEmptySignalStrengths()
+        agent.expectNoInternetValidationStatus()
+        agent.unregister()
+        callback.expectCallback<Lost>(agent.network)
+        agent.expectCallback<OnNetworkUnwanted>()
+        assertFailsWith<IllegalStateException>("Must not be able to register an agent twice") {
+            agent.register()
+        }
+    }
+
+    @Test
+    fun testOnBandwidthUpdateRequested() {
+        val (agent, callback) = createConnectedNetworkAgent()
+        callback.expectAvailableThenValidatedCallbacks(agent.network)
+        agent.expectEmptySignalStrengths()
+        agent.expectNoInternetValidationStatus()
+        mCM.requestBandwidthUpdate(agent.network)
+        agent.expectCallback<OnBandwidthUpdateRequested>()
+        agent.unregister()
+    }
+
+    @Test
+    fun testSignalStrengthThresholds() {
+        val thresholds = intArrayOf(30, 50, 65)
+        val callbacks = thresholds.map { strength ->
+            val request = NetworkRequest.Builder()
+                    .clearCapabilities()
+                    .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
+                    .setSignalStrength(strength)
+                    .build()
+            TestableNetworkCallback(DEFAULT_TIMEOUT_MS).also {
+                registerNetworkCallback(request, it)
+            }
+        }
+        createConnectedNetworkAgent().let { (agent, callback) ->
+            callback.expectAvailableThenValidatedCallbacks(agent.network)
+            agent.expectCallback<OnSignalStrengthThresholdsUpdated>().let {
+                assertArrayEquals(it.thresholds, thresholds)
+            }
+            agent.expectNoInternetValidationStatus()
+
+            // Send signal strength and check that the callbacks are called appropriately.
+            val nc = NetworkCapabilities(agent.nc)
+            nc.setSignalStrength(20)
+            agent.sendNetworkCapabilities(nc)
+            callbacks.forEach { it.assertNoCallback(NO_CALLBACK_TIMEOUT) }
+
+            nc.setSignalStrength(40)
+            agent.sendNetworkCapabilities(nc)
+            callbacks[0].expectAvailableCallbacks(agent.network)
+            callbacks[1].assertNoCallback(NO_CALLBACK_TIMEOUT)
+            callbacks[2].assertNoCallback(NO_CALLBACK_TIMEOUT)
+
+            nc.setSignalStrength(80)
+            agent.sendNetworkCapabilities(nc)
+            callbacks[0].expectCapabilitiesThat(agent.network) { it.signalStrength == 80 }
+            callbacks[1].expectAvailableCallbacks(agent.network)
+            callbacks[2].expectAvailableCallbacks(agent.network)
+
+            nc.setSignalStrength(55)
+            agent.sendNetworkCapabilities(nc)
+            callbacks[0].expectCapabilitiesThat(agent.network) { it.signalStrength == 55 }
+            callbacks[1].expectCapabilitiesThat(agent.network) { it.signalStrength == 55 }
+            callbacks[2].expectCallback<Lost>(agent.network)
+        }
+        callbacks.forEach {
+            mCM.unregisterNetworkCallback(it)
+        }
+    }
+
+    @Test
+    fun testSocketKeepalive(): Unit = createNetworkAgentWithFakeCS().let { agent ->
+        val packet = object : KeepalivePacketData(
+                LOCAL_IPV4_ADDRESS /* srcAddress */, 1234 /* srcPort */,
+                REMOTE_IPV4_ADDRESS /* dstAddress */, 4567 /* dstPort */,
+                ByteArray(100 /* size */) { it.toByte() /* init */ }) {}
+        val slot = 4
+        val interval = 37
+
+        mFakeConnectivityService.sendMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER,
+                arg1 = slot, obj = packet)
+        mFakeConnectivityService.sendMessage(CMD_START_SOCKET_KEEPALIVE,
+                arg1 = slot, arg2 = interval, obj = packet)
+
+        agent.expectCallback<OnAddKeepalivePacketFilter>().let {
+            assertEquals(it.slot, slot)
+            assertEquals(it.packet, packet)
+        }
+        agent.expectCallback<OnStartSocketKeepalive>().let {
+            assertEquals(it.slot, slot)
+            assertEquals(it.interval, interval)
+            assertEquals(it.packet, packet)
+        }
+
+        agent.assertNoCallback()
+
+        // Check that when the agent sends a keepalive event, ConnectivityService receives the
+        // expected message.
+        agent.sendSocketKeepaliveEvent(slot, SocketKeepalive.ERROR_UNSUPPORTED)
+        mFakeConnectivityService.expectMessage(NetworkAgent.EVENT_SOCKET_KEEPALIVE).let() {
+            assertEquals(slot, it.arg1)
+            assertEquals(SocketKeepalive.ERROR_UNSUPPORTED, it.arg2)
+        }
+
+        mFakeConnectivityService.sendMessage(CMD_STOP_SOCKET_KEEPALIVE, arg1 = slot)
+        mFakeConnectivityService.sendMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER, arg1 = slot)
+        agent.expectCallback<OnStopSocketKeepalive>().let {
+            assertEquals(it.slot, slot)
+        }
+        agent.expectCallback<OnRemoveKeepalivePacketFilter>().let {
+            assertEquals(it.slot, slot)
+        }
+    }
+
+    @Test
+    fun testSendUpdates(): Unit = createConnectedNetworkAgent().let { (agent, callback) ->
+        callback.expectAvailableThenValidatedCallbacks(agent.network)
+        agent.expectEmptySignalStrengths()
+        agent.expectNoInternetValidationStatus()
+        val ifaceName = "adhocIface"
+        val lp = LinkProperties(agent.lp)
+        lp.setInterfaceName(ifaceName)
+        agent.sendLinkProperties(lp)
+        callback.expectLinkPropertiesThat(agent.network) {
+            it.getInterfaceName() == ifaceName
+        }
+        val nc = NetworkCapabilities(agent.nc)
+        nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
+        agent.sendNetworkCapabilities(nc)
+        callback.expectCapabilitiesThat(agent.network) {
+            it.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
+        }
+    }
+
+    @Test
+    fun testSendScore() {
+        // This test will create two networks and check that the one with the stronger
+        // score wins out for a request that matches them both.
+        // First create requests to make sure both networks are kept up, using the
+        // specifier so they are specific to each network
+        val name1 = UUID.randomUUID().toString()
+        val name2 = UUID.randomUUID().toString()
+        val request1 = NetworkRequest.Builder()
+                .clearCapabilities()
+                .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
+                .setNetworkSpecifier(StringNetworkSpecifier(name1))
+                .build()
+        val request2 = NetworkRequest.Builder()
+                .clearCapabilities()
+                .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
+                .setNetworkSpecifier(StringNetworkSpecifier(name2))
+                .build()
+        val callback1 = TestableNetworkCallback()
+        val callback2 = TestableNetworkCallback()
+        requestNetwork(request1, callback1)
+        requestNetwork(request2, callback2)
+
+        // Then file the interesting request
+        val request = NetworkRequest.Builder()
+                .clearCapabilities()
+                .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
+                .build()
+        val callback = TestableNetworkCallback()
+        requestNetwork(request, callback)
+
+        // Connect the first Network
+        createConnectedNetworkAgent(name1).let { (agent1, _) ->
+            callback.expectAvailableThenValidatedCallbacks(agent1.network)
+            // Upgrade agent1 to a better score so that there is no ambiguity when
+            // agent2 connects that agent1 is still better
+            agent1.sendNetworkScore(BETTER_NETWORK_SCORE - 1)
+            // Connect the second agent
+            createConnectedNetworkAgent(name2).let { (agent2, _) ->
+                agent2.markConnected()
+                // The callback should not see anything yet
+                callback.assertNoCallback(NO_CALLBACK_TIMEOUT)
+                // Now update the score and expect the callback now prefers agent2
+                agent2.sendNetworkScore(BETTER_NETWORK_SCORE)
+                callback.expectCallback<Available>(agent2.network)
+            }
+        }
+
+        // tearDown() will unregister the requests and agents
+    }
+
+    @Test
+    fun testSetAcceptUnvalidated() {
+        createNetworkAgentWithFakeCS().let { agent ->
+            mFakeConnectivityService.sendMessage(CMD_SAVE_ACCEPT_UNVALIDATED, 1)
+            agent.expectCallback<OnSaveAcceptUnvalidated>().let {
+                assertTrue(it.accept)
+            }
+            agent.assertNoCallback()
+        }
+    }
+
+    @Test
+    fun testSetAcceptUnvalidatedPreventAutomaticReconnect() {
+        createNetworkAgentWithFakeCS().let { agent ->
+            mFakeConnectivityService.sendMessage(CMD_SAVE_ACCEPT_UNVALIDATED, 0)
+            mFakeConnectivityService.sendMessage(CMD_PREVENT_AUTOMATIC_RECONNECT)
+            agent.expectCallback<OnSaveAcceptUnvalidated>().let {
+                assertFalse(it.accept)
+            }
+            agent.expectCallback<OnAutomaticReconnectDisabled>()
+            agent.assertNoCallback()
+            // When automatic reconnect is turned off, the network is torn down and
+            // ConnectivityService sends a disconnect. This in turn causes the agent
+            // to send a DISCONNECTED message to CS.
+            mFakeConnectivityService.willExpectDisconnectOnce()
+            mFakeConnectivityService.disconnect()
+            mFakeConnectivityService.expectMessage(AsyncChannel.CMD_CHANNEL_DISCONNECTED)
+            agent.expectCallback<OnNetworkUnwanted>()
+        }
+    }
+
+    @Test
+    fun testPreventAutomaticReconnect() {
+        createNetworkAgentWithFakeCS().let { agent ->
+            mFakeConnectivityService.sendMessage(CMD_PREVENT_AUTOMATIC_RECONNECT)
+            agent.expectCallback<OnAutomaticReconnectDisabled>()
+            agent.assertNoCallback()
+            mFakeConnectivityService.willExpectDisconnectOnce()
+            mFakeConnectivityService.disconnect()
+            mFakeConnectivityService.expectMessage(AsyncChannel.CMD_CHANNEL_DISCONNECTED)
+            agent.expectCallback<OnNetworkUnwanted>()
+        }
+    }
+
+    @Test
+    fun testValidationStatus() = createNetworkAgentWithFakeCS().let { agent ->
+        val uri = Uri.parse("http://www.google.com")
+        val bundle = Bundle().apply {
+            putString(NetworkAgent.REDIRECT_URL_KEY, uri.toString())
+        }
+        mFakeConnectivityService.sendMessage(CMD_REPORT_NETWORK_STATUS,
+                arg1 = VALID_NETWORK, obj = bundle)
+        agent.expectCallback<OnValidationStatus>().let {
+            assertEquals(it.status, VALID_NETWORK)
+            assertEquals(it.uri, uri)
+        }
+
+        mFakeConnectivityService.sendMessage(CMD_REPORT_NETWORK_STATUS,
+                arg1 = INVALID_NETWORK, obj = Bundle())
+        agent.expectCallback<OnValidationStatus>().let {
+            assertEquals(it.status, INVALID_NETWORK)
+            assertNull(it.uri)
+        }
+    }
+}
diff --git a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java
index c862c77..5e92b41 100644
--- a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java
+++ b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java
@@ -16,24 +16,181 @@
 
 package android.net.cts;
 
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;
 import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_VPN;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.net.MacAddress;
+import android.net.MatchAllNetworkSpecifier;
+import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
-import android.test.AndroidTestCase;
+import android.net.NetworkSpecifier;
+import android.net.TelephonyNetworkSpecifier;
+import android.net.wifi.WifiNetworkSpecifier;
+import android.os.Build;
+import android.os.Process;
+import android.os.PatternMatcher;
 
-public class NetworkRequestTest extends AndroidTestCase {
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class NetworkRequestTest {
+    @Rule
+    public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
+
+    private static final String TEST_SSID = "TestSSID";
+    private static final String OTHER_SSID = "OtherSSID";
+    private static final int TEST_UID = 2097;
+    private static final String TEST_PACKAGE_NAME = "test.package.name";
+    private static final MacAddress ARBITRARY_ADDRESS = MacAddress.fromString("3:5:8:12:9:2");
+
+    @Test
     public void testCapabilities() {
         assertTrue(new NetworkRequest.Builder().addCapability(NET_CAPABILITY_MMS).build()
                 .hasCapability(NET_CAPABILITY_MMS));
         assertFalse(new NetworkRequest.Builder().removeCapability(NET_CAPABILITY_MMS).build()
                 .hasCapability(NET_CAPABILITY_MMS));
+
+        final NetworkRequest nr = new NetworkRequest.Builder().clearCapabilities().build();
+        // Verify request has no capabilities
+        verifyNoCapabilities(nr);
     }
 
+    private void verifyNoCapabilities(NetworkRequest nr) {
+        // NetworkCapabilities.mNetworkCapabilities is defined as type long
+        final int MAX_POSSIBLE_CAPABILITY = Long.SIZE;
+        for(int bit = 0; bit < MAX_POSSIBLE_CAPABILITY; bit++) {
+            assertFalse(nr.hasCapability(bit));
+        }
+    }
+
+    @Test
     public void testTransports() {
         assertTrue(new NetworkRequest.Builder().addTransportType(TRANSPORT_BLUETOOTH).build()
                 .hasTransport(TRANSPORT_BLUETOOTH));
         assertFalse(new NetworkRequest.Builder().removeTransportType(TRANSPORT_BLUETOOTH).build()
                 .hasTransport(TRANSPORT_BLUETOOTH));
     }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.Q)
+    public void testSpecifier() {
+        assertNull(new NetworkRequest.Builder().build().getNetworkSpecifier());
+        final WifiNetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
+                .setSsidPattern(new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL))
+                .setBssidPattern(ARBITRARY_ADDRESS, ARBITRARY_ADDRESS)
+                .build();
+        final NetworkSpecifier obtainedSpecifier = new NetworkRequest.Builder()
+                .addTransportType(TRANSPORT_WIFI)
+                .setNetworkSpecifier(specifier)
+                .build()
+                .getNetworkSpecifier();
+        assertEquals(obtainedSpecifier, specifier);
+
+        assertNull(new NetworkRequest.Builder()
+                .clearCapabilities()
+                .build()
+                .getNetworkSpecifier());
+    }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.Q)
+    public void testRequestorPackageName() {
+        assertNull(new NetworkRequest.Builder().build().getRequestorPackageName());
+        final String pkgName = "android.net.test";
+        final NetworkCapabilities nc = new NetworkCapabilities.Builder()
+                .setRequestorPackageName(pkgName)
+                .build();
+        final NetworkRequest nr = new NetworkRequest.Builder()
+                .setCapabilities(nc)
+                .build();
+        assertEquals(pkgName, nr.getRequestorPackageName());
+        assertNull(new NetworkRequest.Builder()
+                .clearCapabilities()
+                .build()
+                .getRequestorPackageName());
+    }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.Q)
+    public void testCanBeSatisfiedBy() {
+        final TelephonyNetworkSpecifier specifier1 = new TelephonyNetworkSpecifier.Builder()
+                .setSubscriptionId(1234 /* subId */)
+                .build();
+        final TelephonyNetworkSpecifier specifier2 = new TelephonyNetworkSpecifier.Builder()
+                .setSubscriptionId(5678 /* subId */)
+                .build();
+        final NetworkCapabilities cap = new NetworkCapabilities()
+                .addTransportType(TRANSPORT_CELLULAR)
+                .addCapability(NET_CAPABILITY_MMS)
+                .addCapability(NET_CAPABILITY_INTERNET);
+        final NetworkCapabilities capDualTransport = new NetworkCapabilities(cap)
+                .addTransportType(TRANSPORT_VPN);
+        final NetworkCapabilities capWithSpecifier1 =
+                new NetworkCapabilities(cap).setNetworkSpecifier(specifier1);
+        final NetworkCapabilities capDiffTransportWithSpecifier1 = new NetworkCapabilities()
+                .addCapability(NET_CAPABILITY_INTERNET)
+                .addTransportType(TRANSPORT_VPN)
+                .setNetworkSpecifier(specifier1);
+
+        final NetworkRequest requestWithSpecifier1 = new NetworkRequest.Builder()
+                .addTransportType(TRANSPORT_CELLULAR)
+                .addCapability(NET_CAPABILITY_INTERNET)
+                .setNetworkSpecifier(specifier1)
+                .build();
+        assertFalse(requestWithSpecifier1.canBeSatisfiedBy(null));
+        assertFalse(requestWithSpecifier1.canBeSatisfiedBy(new NetworkCapabilities()));
+        assertTrue(requestWithSpecifier1.canBeSatisfiedBy(new NetworkCapabilities(cap)
+                .setNetworkSpecifier(new MatchAllNetworkSpecifier())));
+        assertTrue(requestWithSpecifier1.canBeSatisfiedBy(cap));
+        assertTrue(requestWithSpecifier1.canBeSatisfiedBy(capWithSpecifier1));
+        assertTrue(requestWithSpecifier1.canBeSatisfiedBy(capDualTransport));
+        assertFalse(requestWithSpecifier1.canBeSatisfiedBy(
+                new NetworkCapabilities(cap).setNetworkSpecifier(specifier2)));
+
+        final NetworkRequest request = new NetworkRequest.Builder()
+                .addTransportType(TRANSPORT_CELLULAR)
+                .addCapability(NET_CAPABILITY_INTERNET)
+                .build();
+        assertTrue(request.canBeSatisfiedBy(cap));
+        assertTrue(request.canBeSatisfiedBy(capWithSpecifier1));
+        assertTrue(request.canBeSatisfiedBy(
+                new NetworkCapabilities(cap).setNetworkSpecifier(specifier2)));
+        assertFalse(request.canBeSatisfiedBy(capDiffTransportWithSpecifier1));
+        assertTrue(request.canBeSatisfiedBy(capDualTransport));
+
+        assertEquals(requestWithSpecifier1.canBeSatisfiedBy(capWithSpecifier1),
+                new NetworkCapabilities(capWithSpecifier1)
+                    .satisfiedByNetworkCapabilities(capWithSpecifier1));
+    }
+
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+    public void testRequestorUid() {
+        final NetworkCapabilities nc = new NetworkCapabilities();
+        // Verify default value is INVALID_UID
+        assertEquals(Process.INVALID_UID, new NetworkRequest.Builder()
+                 .setCapabilities(nc).build().getRequestorUid());
+
+        nc.setRequestorUid(1314);
+        final NetworkRequest nr = new NetworkRequest.Builder().setCapabilities(nc).build();
+        assertEquals(1314, nr.getRequestorUid());
+
+        assertEquals(Process.INVALID_UID, new NetworkRequest.Builder()
+                .clearCapabilities().build().getRequestorUid());
+    }
 }
diff --git a/tests/cts/net/src/android/net/cts/NetworkStatsBinderTest.java b/tests/cts/net/src/android/net/cts/NetworkStatsBinderTest.java
new file mode 100644
index 0000000..1f3162f
--- /dev/null
+++ b/tests/cts/net/src/android/net/cts/NetworkStatsBinderTest.java
@@ -0,0 +1,130 @@
+/*
+ * 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;
+
+import static android.os.Process.INVALID_UID;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.net.INetworkStatsService;
+import android.net.TrafficStats;
+import android.os.IBinder;
+import android.os.Process;
+import android.os.RemoteException;
+import android.test.AndroidTestCase;
+import android.util.SparseArray;
+
+import androidx.test.InstrumentationRegistry;
+
+import com.android.internal.util.CollectionUtils;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+public class NetworkStatsBinderTest extends AndroidTestCase {
+    // NOTE: These are shamelessly copied from TrafficStats.
+    private static final int TYPE_RX_BYTES = 0;
+    private static final int TYPE_RX_PACKETS = 1;
+    private static final int TYPE_TX_BYTES = 2;
+    private static final int TYPE_TX_PACKETS = 3;
+
+    private final SparseArray<Function<Integer, Long>> mUidStatsQueryOpArray = new SparseArray<>();
+
+    @Override
+    protected void setUp() throws Exception {
+        mUidStatsQueryOpArray.put(TYPE_RX_BYTES, uid -> TrafficStats.getUidRxBytes(uid));
+        mUidStatsQueryOpArray.put(TYPE_RX_PACKETS, uid -> TrafficStats.getUidRxPackets(uid));
+        mUidStatsQueryOpArray.put(TYPE_TX_BYTES, uid -> TrafficStats.getUidTxBytes(uid));
+        mUidStatsQueryOpArray.put(TYPE_TX_PACKETS, uid -> TrafficStats.getUidTxPackets(uid));
+    }
+
+    private long getUidStatsFromBinder(int uid, int type) throws Exception {
+        Method getServiceMethod = Class.forName("android.os.ServiceManager")
+                .getDeclaredMethod("getService", new Class[]{String.class});
+        IBinder binder = (IBinder) getServiceMethod.invoke(null, Context.NETWORK_STATS_SERVICE);
+        INetworkStatsService nss = INetworkStatsService.Stub.asInterface(binder);
+        return nss.getUidStats(uid, type);
+    }
+
+    private int getFirstAppUidThat(@NonNull Predicate<Integer> predicate) {
+        PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
+        List<PackageInfo> apps = pm.getInstalledPackages(0 /* flags */);
+        final PackageInfo match = CollectionUtils.find(apps,
+                it -> it.applicationInfo != null && predicate.test(it.applicationInfo.uid));
+        if (match != null) return match.applicationInfo.uid;
+        return INVALID_UID;
+    }
+
+    public void testAccessUidStatsFromBinder() throws Exception {
+        final int myUid = Process.myUid();
+        final List<Integer> testUidList = new ArrayList<>();
+
+        // Prepare uid list for testing.
+        testUidList.add(INVALID_UID);
+        testUidList.add(Process.ROOT_UID);
+        testUidList.add(Process.SYSTEM_UID);
+        testUidList.add(myUid);
+        testUidList.add(Process.LAST_APPLICATION_UID);
+        testUidList.add(Process.LAST_APPLICATION_UID + 1);
+        // If available, pick another existing uid for testing that is not already contained
+        // in the list above.
+        final int notMyUid = getFirstAppUidThat(uid -> uid >= 0 && !testUidList.contains(uid));
+        if (notMyUid != INVALID_UID) testUidList.add(notMyUid);
+
+        for (final int uid : testUidList) {
+            for (int i = 0; i < mUidStatsQueryOpArray.size(); i++) {
+                final int type = mUidStatsQueryOpArray.keyAt(i);
+                try {
+                    final long uidStatsFromBinder = getUidStatsFromBinder(uid, type);
+                    final long uidTrafficStats = mUidStatsQueryOpArray.get(type).apply(uid);
+
+                    // Verify that UNSUPPORTED is returned if the uid is not current app uid.
+                    if (uid != myUid) {
+                        assertEquals(uidStatsFromBinder, TrafficStats.UNSUPPORTED);
+                    }
+                    // Verify that returned result is the same with the result get from
+                    // TrafficStats.
+                    // TODO: If the test is flaky then it should instead assert that the values
+                    //  are approximately similar.
+                    assertEquals("uidStats is not matched for query type " + type
+                                    + ", uid=" + uid + ", myUid=" + myUid, uidTrafficStats,
+                            uidStatsFromBinder);
+                } catch (IllegalAccessException e) {
+                    /* Java language access prevents exploitation. */
+                    return;
+                } catch (InvocationTargetException e) {
+                    /* Underlying method has been changed. */
+                    return;
+                } catch (ClassNotFoundException e) {
+                    /* not vulnerable if hidden API no longer available */
+                    return;
+                } catch (NoSuchMethodException e) {
+                    /* not vulnerable if hidden API no longer available */
+                    return;
+                } catch (RemoteException e) {
+                    return;
+                }
+            }
+        }
+    }
+}
diff --git a/tests/cts/net/src/android/net/cts/ProxyInfoTest.java b/tests/cts/net/src/android/net/cts/ProxyInfoTest.java
new file mode 100644
index 0000000..1c5624c
--- /dev/null
+++ b/tests/cts/net/src/android/net/cts/ProxyInfoTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.cts;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.net.ProxyInfo;
+import android.net.Uri;
+import android.os.Build;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+@RunWith(AndroidJUnit4.class)
+public final class ProxyInfoTest {
+    private static final String TEST_HOST = "test.example.com";
+    private static final int TEST_PORT = 5566;
+    private static final Uri TEST_URI = Uri.parse("https://test.example.com");
+    // This matches android.net.ProxyInfo#LOCAL_EXCL_LIST
+    private static final String LOCAL_EXCL_LIST = "";
+    // This matches android.net.ProxyInfo#LOCAL_HOST
+    private static final String LOCAL_HOST = "localhost";
+    // This matches android.net.ProxyInfo#LOCAL_PORT
+    private static final int LOCAL_PORT = -1;
+
+    @Rule
+    public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
+
+    @Test
+    public void testConstructor() {
+        final ProxyInfo proxy = new ProxyInfo((ProxyInfo) null);
+        checkEmpty(proxy);
+
+        assertEquals(proxy, new ProxyInfo(proxy));
+    }
+
+    @Test
+    public void testBuildDirectProxy() {
+        final ProxyInfo proxy1 = ProxyInfo.buildDirectProxy(TEST_HOST, TEST_PORT);
+
+        assertEquals(TEST_HOST, proxy1.getHost());
+        assertEquals(TEST_PORT, proxy1.getPort());
+        assertArrayEquals(new String[0], proxy1.getExclusionList());
+        assertEquals(Uri.EMPTY, proxy1.getPacFileUrl());
+
+        final List<String> exclList = new ArrayList<>();
+        exclList.add("localhost");
+        exclList.add("*.exclusion.com");
+        final ProxyInfo proxy2 = ProxyInfo.buildDirectProxy(TEST_HOST, TEST_PORT, exclList);
+
+        assertEquals(TEST_HOST, proxy2.getHost());
+        assertEquals(TEST_PORT, proxy2.getPort());
+        assertArrayEquals(exclList.toArray(new String[0]), proxy2.getExclusionList());
+        assertEquals(Uri.EMPTY, proxy2.getPacFileUrl());
+    }
+
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+    public void testBuildPacProxy() {
+        final ProxyInfo proxy1 = ProxyInfo.buildPacProxy(TEST_URI);
+
+        assertEquals(LOCAL_HOST, proxy1.getHost());
+        assertEquals(LOCAL_PORT, proxy1.getPort());
+        assertArrayEquals(LOCAL_EXCL_LIST.toLowerCase(Locale.ROOT).split(","),
+                proxy1.getExclusionList());
+        assertEquals(TEST_URI, proxy1.getPacFileUrl());
+
+        final ProxyInfo proxy2 = ProxyInfo.buildPacProxy(TEST_URI, TEST_PORT);
+
+        assertEquals(LOCAL_HOST, proxy2.getHost());
+        assertEquals(TEST_PORT, proxy2.getPort());
+        assertArrayEquals(LOCAL_EXCL_LIST.toLowerCase(Locale.ROOT).split(","),
+                proxy2.getExclusionList());
+        assertEquals(TEST_URI, proxy2.getPacFileUrl());
+    }
+
+    @Test
+    public void testIsValid() {
+        final ProxyInfo proxy1 = ProxyInfo.buildDirectProxy(TEST_HOST, TEST_PORT);
+        assertTrue(proxy1.isValid());
+
+        // Given empty host
+        final ProxyInfo proxy2 = ProxyInfo.buildDirectProxy("", TEST_PORT);
+        assertFalse(proxy2.isValid());
+        // Given invalid host
+        final ProxyInfo proxy3 = ProxyInfo.buildDirectProxy(".invalid.com", TEST_PORT);
+        assertFalse(proxy3.isValid());
+        // Given invalid port.
+        final ProxyInfo proxy4 = ProxyInfo.buildDirectProxy(TEST_HOST, 0);
+        assertFalse(proxy4.isValid());
+        // Given another invalid port
+        final ProxyInfo proxy5 = ProxyInfo.buildDirectProxy(TEST_HOST, 65536);
+        assertFalse(proxy5.isValid());
+        // Given invalid exclusion list
+        final List<String> exclList = new ArrayList<>();
+        exclList.add(".invalid.com");
+        exclList.add("%.test.net");
+        final ProxyInfo proxy6 = ProxyInfo.buildDirectProxy(TEST_HOST, TEST_PORT, exclList);
+        assertFalse(proxy6.isValid());
+    }
+
+    private void checkEmpty(ProxyInfo proxy) {
+        assertNull(proxy.getHost());
+        assertEquals(0, proxy.getPort());
+        assertNull(proxy.getExclusionList());
+        assertEquals(Uri.EMPTY, proxy.getPacFileUrl());
+    }
+}
diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java
index 5bd1e20..37bdd44 100755
--- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java
+++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java
@@ -16,14 +16,13 @@
 
 package android.net.cts;
 
-import android.content.pm.PackageManager;
 import android.net.NetworkStats;
 import android.net.TrafficStats;
 import android.os.Process;
-import android.os.SystemProperties;
 import android.platform.test.annotations.AppModeFull;
 import android.test.AndroidTestCase;
 import android.util.Log;
+import android.util.Range;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -36,6 +35,13 @@
 public class TrafficStatsTest extends AndroidTestCase {
     private static final String LOG_TAG = "TrafficStatsTest";
 
+    /** Verify the given value is in range [lower, upper] */
+    private void assertInRange(String tag, long value, long lower, long upper) {
+        final Range range = new Range(lower, upper);
+        assertTrue(tag + ": " + value + " is not within range [" + lower + ", " + upper + "]",
+                range.contains(value));
+    }
+
     public void testValidMobileStats() {
         // We can't assume a mobile network is even present in this test, so
         // we simply assert that a valid value is returned.
@@ -53,6 +59,11 @@
         assertTrue(TrafficStats.getTotalRxBytes() >= 0);
     }
 
+    public void testValidPacketStats() {
+        assertTrue(TrafficStats.getTxPackets("lo") >= 0);
+        assertTrue(TrafficStats.getRxPackets("lo") >= 0);
+    }
+
     public void testThreadStatsTag() throws Exception {
         TrafficStats.setThreadStatsTag(0xf00d);
         assertTrue("Tag didn't stick", TrafficStats.getThreadStatsTag() == 0xf00d);
@@ -96,6 +107,8 @@
         final long uidRxBytesBefore = TrafficStats.getUidRxBytes(Process.myUid());
         final long uidTxPacketsBefore = TrafficStats.getUidTxPackets(Process.myUid());
         final long uidRxPacketsBefore = TrafficStats.getUidRxPackets(Process.myUid());
+        final long ifaceTxPacketsBefore = TrafficStats.getTxPackets("lo");
+        final long ifaceRxPacketsBefore = TrafficStats.getRxPackets("lo");
 
         // Transfer 1MB of data across an explicitly localhost socket.
         final int byteCount = 1024;
@@ -107,12 +120,12 @@
             @Override
             public void run() {
                 try {
-                    Socket socket = new Socket("localhost", server.getLocalPort());
+                    final Socket socket = new Socket("localhost", server.getLocalPort());
                     // Make sure that each write()+flush() turns into a packet:
                     // disable Nagle.
                     socket.setTcpNoDelay(true);
-                    OutputStream out = socket.getOutputStream();
-                    byte[] buf = new byte[byteCount];
+                    final OutputStream out = socket.getOutputStream();
+                    final byte[] buf = new byte[byteCount];
                     TrafficStats.setThreadStatsTag(0x42);
                     TrafficStats.tagSocket(socket);
                     for (int i = 0; i < packetCount; i++) {
@@ -135,12 +148,12 @@
 
         int read = 0;
         try {
-            Socket socket = server.accept();
+            final Socket socket = server.accept();
             socket.setTcpNoDelay(true);
             TrafficStats.setThreadStatsTag(0x43);
             TrafficStats.tagSocket(socket);
-            InputStream in = socket.getInputStream();
-            byte[] buf = new byte[byteCount];
+            final InputStream in = socket.getInputStream();
+            final byte[] buf = new byte[byteCount];
             while (read < byteCount * packetCount) {
                 int n = in.read(buf);
                 assertTrue("Unexpected EOF", n > 0);
@@ -156,24 +169,28 @@
             Thread.sleep(1000);
         } catch (InterruptedException e) {
         }
-        NetworkStats testStats = TrafficStats.stopDataProfiling(null);
+        final NetworkStats testStats = TrafficStats.stopDataProfiling(null);
 
-        long mobileTxPacketsAfter = TrafficStats.getMobileTxPackets();
-        long mobileRxPacketsAfter = TrafficStats.getMobileRxPackets();
-        long mobileTxBytesAfter = TrafficStats.getMobileTxBytes();
-        long mobileRxBytesAfter = TrafficStats.getMobileRxBytes();
-        long totalTxPacketsAfter = TrafficStats.getTotalTxPackets();
-        long totalRxPacketsAfter = TrafficStats.getTotalRxPackets();
-        long totalTxBytesAfter = TrafficStats.getTotalTxBytes();
-        long totalRxBytesAfter = TrafficStats.getTotalRxBytes();
-        long uidTxBytesAfter = TrafficStats.getUidTxBytes(Process.myUid());
-        long uidRxBytesAfter = TrafficStats.getUidRxBytes(Process.myUid());
-        long uidTxPacketsAfter = TrafficStats.getUidTxPackets(Process.myUid());
-        long uidRxPacketsAfter = TrafficStats.getUidRxPackets(Process.myUid());
-        long uidTxDeltaBytes = uidTxBytesAfter - uidTxBytesBefore;
-        long uidTxDeltaPackets = uidTxPacketsAfter - uidTxPacketsBefore;
-        long uidRxDeltaBytes = uidRxBytesAfter - uidRxBytesBefore;
-        long uidRxDeltaPackets = uidRxPacketsAfter - uidRxPacketsBefore;
+        final long mobileTxPacketsAfter = TrafficStats.getMobileTxPackets();
+        final long mobileRxPacketsAfter = TrafficStats.getMobileRxPackets();
+        final long mobileTxBytesAfter = TrafficStats.getMobileTxBytes();
+        final long mobileRxBytesAfter = TrafficStats.getMobileRxBytes();
+        final long totalTxPacketsAfter = TrafficStats.getTotalTxPackets();
+        final long totalRxPacketsAfter = TrafficStats.getTotalRxPackets();
+        final long totalTxBytesAfter = TrafficStats.getTotalTxBytes();
+        final long totalRxBytesAfter = TrafficStats.getTotalRxBytes();
+        final long uidTxBytesAfter = TrafficStats.getUidTxBytes(Process.myUid());
+        final long uidRxBytesAfter = TrafficStats.getUidRxBytes(Process.myUid());
+        final long uidTxPacketsAfter = TrafficStats.getUidTxPackets(Process.myUid());
+        final long uidRxPacketsAfter = TrafficStats.getUidRxPackets(Process.myUid());
+        final long uidTxDeltaBytes = uidTxBytesAfter - uidTxBytesBefore;
+        final long uidTxDeltaPackets = uidTxPacketsAfter - uidTxPacketsBefore;
+        final long uidRxDeltaBytes = uidRxBytesAfter - uidRxBytesBefore;
+        final long uidRxDeltaPackets = uidRxPacketsAfter - uidRxPacketsBefore;
+        final long ifaceTxPacketsAfter = TrafficStats.getTxPackets("lo");
+        final long ifaceRxPacketsAfter = TrafficStats.getRxPackets("lo");
+        final long ifaceTxDeltaPackets = ifaceTxPacketsAfter - ifaceTxPacketsBefore;
+        final long ifaceRxDeltaPackets = ifaceRxPacketsAfter - ifaceRxPacketsBefore;
 
         // Localhost traffic *does* count against per-UID stats.
         /*
@@ -192,50 +209,46 @@
         // Some other tests don't cleanup connections correctly.
         // They have the same UID, so we discount their lingering traffic
         // which happens only on non-localhost, such as TCP FIN retranmission packets
-        long deltaTxOtherPackets = (totalTxPacketsAfter - totalTxPacketsBefore) - uidTxDeltaPackets;
-        long deltaRxOtherPackets = (totalRxPacketsAfter - totalRxPacketsBefore) - uidRxDeltaPackets;
+        final long deltaTxOtherPackets = (totalTxPacketsAfter - totalTxPacketsBefore)
+                - uidTxDeltaPackets;
+        final long deltaRxOtherPackets = (totalRxPacketsAfter - totalRxPacketsBefore)
+                - uidRxDeltaPackets;
         if (deltaTxOtherPackets > 0 || deltaRxOtherPackets > 0) {
-            Log.i(LOG_TAG, "lingering traffic data: " + deltaTxOtherPackets + "/" + deltaRxOtherPackets);
+            Log.i(LOG_TAG, "lingering traffic data: " + deltaTxOtherPackets + "/"
+                    + deltaRxOtherPackets);
         }
 
-        // Check the per uid stats read from data profiling have the stats expected. The data
-        // profiling snapshot is generated from readNetworkStatsDetail() method in
-        // networkStatsService and in this way we can verify the detail networkStats of a given uid
-        // is correct.
-        NetworkStats.Entry entry = testStats.getTotal(null, Process.myUid());
-        assertTrue("txPackets detail: " + entry.txPackets + " uidTxPackets: " + uidTxDeltaPackets,
-            entry.txPackets >= packetCount + minExpectedExtraPackets
-            && entry.txPackets <= uidTxDeltaPackets);
-        assertTrue("rxPackets detail: " + entry.rxPackets + " uidRxPackets: " + uidRxDeltaPackets,
-            entry.rxPackets >= packetCount + minExpectedExtraPackets
-            && entry.rxPackets <= uidRxDeltaPackets);
-        assertTrue("txBytes detail: " + entry.txBytes + " uidTxDeltaBytes: " + uidTxDeltaBytes,
-            entry.txBytes >= tcpPacketToIpBytes(packetCount, byteCount)
-            + tcpPacketToIpBytes(minExpectedExtraPackets, 0) && entry.txBytes <= uidTxDeltaBytes);
-        assertTrue("rxBytes detail: " + entry.rxBytes + " uidRxDeltaBytes: " + uidRxDeltaBytes,
-            entry.rxBytes >= tcpPacketToIpBytes(packetCount, byteCount)
-            + tcpPacketToIpBytes(minExpectedExtraPackets, 0) && entry.rxBytes <= uidRxDeltaBytes);
-
-        assertTrue("uidtxp: " + uidTxPacketsBefore + " -> " + uidTxPacketsAfter + " delta=" + uidTxDeltaPackets +
-            " Wanted: " + uidTxDeltaPackets + ">=" + packetCount + "+" + minExpectedExtraPackets + " && " +
-            uidTxDeltaPackets + "<=" + packetCount + "+" + packetCount + "+" + maxExpectedExtraPackets + "+" + deltaTxOtherPackets,
-            uidTxDeltaPackets >= packetCount + minExpectedExtraPackets &&
-            uidTxDeltaPackets <= packetCount + packetCount + maxExpectedExtraPackets + deltaTxOtherPackets);
-        assertTrue("uidrxp: " + uidRxPacketsBefore + " -> " + uidRxPacketsAfter + " delta=" + uidRxDeltaPackets +
-            " Wanted: " + uidRxDeltaPackets + ">=" + packetCount + "+" + minExpectedExtraPackets + " && " +
-            uidRxDeltaPackets + "<=" + packetCount + "+" + packetCount + "+" + maxExpectedExtraPackets,
-            uidRxDeltaPackets >= packetCount + minExpectedExtraPackets &&
-            uidRxDeltaPackets <= packetCount + packetCount + maxExpectedExtraPackets + deltaRxOtherPackets);
-        assertTrue("uidtxb: " + uidTxBytesBefore + " -> " + uidTxBytesAfter + " delta=" + uidTxDeltaBytes +
-            " Wanted: " + uidTxDeltaBytes + ">=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(minExpectedExtraPackets, 0) + " && " +
-            uidTxDeltaBytes + "<=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets, 0),
-            uidTxDeltaBytes >= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(minExpectedExtraPackets, 0) &&
-            uidTxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets + deltaTxOtherPackets, 0));
-        assertTrue("uidrxb: " + uidRxBytesBefore + " -> " + uidRxBytesAfter + " delta=" + uidRxDeltaBytes +
-            " Wanted: " + uidRxDeltaBytes + ">=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(minExpectedExtraPackets, 0) + " && " +
-            uidRxDeltaBytes + "<=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets, 0),
-            uidRxDeltaBytes >= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(minExpectedExtraPackets, 0) &&
-            uidRxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets + deltaRxOtherPackets, 0));
+        // Check that the per-uid stats obtained from data profiling contain the expected values.
+        // The data profiling snapshot is generated from the readNetworkStatsDetail() method in
+        // networkStatsService, so it's possible to verify that the detailed stats for a given
+        // uid are correct.
+        final NetworkStats.Entry entry = testStats.getTotal(null, Process.myUid());
+        final long pktBytes = tcpPacketToIpBytes(packetCount, byteCount);
+        final long pktWithNoDataBytes = tcpPacketToIpBytes(packetCount, 0);
+        final long minExpExtraPktBytes = tcpPacketToIpBytes(minExpectedExtraPackets, 0);
+        final long maxExpExtraPktBytes = tcpPacketToIpBytes(maxExpectedExtraPackets, 0);
+        final long deltaTxOtherPktBytes = tcpPacketToIpBytes(deltaTxOtherPackets, 0);
+        final long deltaRxOtherPktBytes  = tcpPacketToIpBytes(deltaRxOtherPackets, 0);
+        assertInRange("txPackets detail", entry.txPackets, packetCount + minExpectedExtraPackets,
+                uidTxDeltaPackets);
+        assertInRange("rxPackets detail", entry.rxPackets, packetCount + minExpectedExtraPackets,
+                uidRxDeltaPackets);
+        assertInRange("txBytes detail", entry.txBytes, pktBytes + minExpExtraPktBytes,
+                uidTxDeltaBytes);
+        assertInRange("rxBytes detail", entry.rxBytes, pktBytes + minExpExtraPktBytes,
+                uidRxDeltaBytes);
+        assertInRange("uidtxp", uidTxDeltaPackets, packetCount + minExpectedExtraPackets,
+                packetCount + packetCount + maxExpectedExtraPackets + deltaTxOtherPackets);
+        assertInRange("uidrxp", uidRxDeltaPackets, packetCount + minExpectedExtraPackets,
+                packetCount + packetCount + maxExpectedExtraPackets + deltaRxOtherPackets);
+        assertInRange("uidtxb", uidTxDeltaBytes, pktBytes + minExpExtraPktBytes,
+                pktBytes + pktWithNoDataBytes + maxExpExtraPktBytes + deltaTxOtherPktBytes);
+        assertInRange("uidrxb", uidRxDeltaBytes, pktBytes + minExpExtraPktBytes,
+                pktBytes + pktWithNoDataBytes + maxExpExtraPktBytes + deltaRxOtherPktBytes);
+        assertInRange("iftxp", ifaceTxDeltaPackets, packetCount + minExpectedExtraPackets,
+                packetCount + packetCount + maxExpectedExtraPackets + deltaTxOtherPackets);
+        assertInRange("ifrxp", ifaceRxDeltaPackets, packetCount + minExpectedExtraPackets,
+                packetCount + packetCount + maxExpectedExtraPackets + deltaRxOtherPackets);
 
         // Localhost traffic *does* count against total stats.
         // Check the total stats increased after test data transfer over localhost has been made.
@@ -247,42 +260,20 @@
                 totalTxBytesAfter >= totalTxBytesBefore + uidTxDeltaBytes);
         assertTrue("trxb: " + totalRxBytesBefore + " -> " + totalRxBytesAfter,
                 totalRxBytesAfter >= totalRxBytesBefore + uidRxDeltaBytes);
-
-        // If the adb TCP port is opened, this test may be run by adb over network.
-        // Huge amount of data traffic might go through the network and accounted into total packets
-        // stats. The upper bound check would be meaningless.
-        // TODO: Consider precisely calculate the traffic accounted due to adb over network and
-        //       subtract it when checking upper bound instead of skip checking.
-        final PackageManager pm = mContext.getPackageManager();
-        if (SystemProperties.getInt("persist.adb.tcp.port", -1) > -1
-                || SystemProperties.getInt("service.adb.tcp.port", -1) > -1
-                || !pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY)) {
-            Log.i(LOG_TAG, "adb is running over the network, skip the upper bound check");
-        } else {
-            // Fudge by 132 packets of 1500 bytes not related to the test.
-            assertTrue("ttxp: " + totalTxPacketsBefore + " -> " + totalTxPacketsAfter,
-                    totalTxPacketsAfter <= totalTxPacketsBefore + uidTxDeltaPackets + 132);
-            assertTrue("trxp: " + totalRxPacketsBefore + " -> " + totalRxPacketsAfter,
-                    totalRxPacketsAfter <= totalRxPacketsBefore + uidRxDeltaPackets + 132);
-            assertTrue("ttxb: " + totalTxBytesBefore + " -> " + totalTxBytesAfter,
-                    totalTxBytesAfter <= totalTxBytesBefore + uidTxDeltaBytes + 132 * 1500);
-            assertTrue("trxb: " + totalRxBytesBefore + " -> " + totalRxBytesAfter,
-                    totalRxBytesAfter <= totalRxBytesBefore + uidRxDeltaBytes + 132 * 1500);
-        }
+        assertTrue("iftxp: " + ifaceTxPacketsBefore + " -> " + ifaceTxPacketsAfter,
+                totalTxPacketsAfter >= totalTxPacketsBefore + ifaceTxDeltaPackets);
+        assertTrue("ifrxp: " + ifaceRxPacketsBefore + " -> " + ifaceRxPacketsAfter,
+                totalRxPacketsAfter >= totalRxPacketsBefore + ifaceRxDeltaPackets);
 
         // Localhost traffic should *not* count against mobile stats,
         // There might be some other traffic, but nowhere near 1MB.
-        assertTrue("mtxp: " + mobileTxPacketsBefore + " -> " + mobileTxPacketsAfter,
-            mobileTxPacketsAfter >= mobileTxPacketsBefore &&
-            mobileTxPacketsAfter <= mobileTxPacketsBefore + 500);
-        assertTrue("mrxp: " + mobileRxPacketsBefore + " -> " + mobileRxPacketsAfter,
-            mobileRxPacketsAfter >= mobileRxPacketsBefore &&
-            mobileRxPacketsAfter <= mobileRxPacketsBefore + 500);
-        assertTrue("mtxb: " + mobileTxBytesBefore + " -> " + mobileTxBytesAfter,
-            mobileTxBytesAfter >= mobileTxBytesBefore &&
-            mobileTxBytesAfter <= mobileTxBytesBefore + 200000);
-        assertTrue("mrxb: " + mobileRxBytesBefore + " -> " + mobileRxBytesAfter,
-            mobileRxBytesAfter >= mobileRxBytesBefore &&
-            mobileRxBytesAfter <= mobileRxBytesBefore + 200000);
+        assertInRange("mtxp", mobileTxPacketsAfter, mobileTxPacketsBefore,
+                mobileTxPacketsBefore + 500);
+        assertInRange("mrxp", mobileRxPacketsAfter, mobileRxPacketsBefore,
+                mobileRxPacketsBefore + 500);
+        assertInRange("mtxb", mobileTxBytesAfter, mobileTxBytesBefore,
+                mobileTxBytesBefore + 200000);
+        assertInRange("mrxb", mobileRxBytesAfter, mobileRxBytesBefore,
+                mobileRxBytesBefore + 200000);
     }
 }
diff --git a/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java b/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java
index 2d615bb..5a70928 100644
--- a/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java
+++ b/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java
@@ -16,15 +16,38 @@
 
 package android.net.cts;
 
-import java.util.List;
-import java.util.Set;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
 import android.net.UrlQuerySanitizer;
 import android.net.UrlQuerySanitizer.IllegalCharacterValueSanitizer;
 import android.net.UrlQuerySanitizer.ParameterValuePair;
 import android.net.UrlQuerySanitizer.ValueSanitizer;
-import android.test.AndroidTestCase;
+import android.os.Build;
 
-public class UrlQuerySanitizerTest extends AndroidTestCase {
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+import java.util.Set;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class UrlQuerySanitizerTest {
+    @Rule
+    public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule();
+
     private static final int ALL_OK = IllegalCharacterValueSanitizer.ALL_OK;
 
     // URL for test.
@@ -41,6 +64,7 @@
     private static final String AGE = "age";
     private static final String HEIGHT = "height";
 
+    @Test
     public void testUrlQuerySanitizer() {
         MockUrlQuerySanitizer uqs = new MockUrlQuerySanitizer();
         assertFalse(uqs.getAllowUnregisteredParamaters());
@@ -209,6 +233,19 @@
 
     }
 
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q) // Only fixed in R
+    public void testScriptUrlOk_73822755() {
+        ValueSanitizer sanitizer = new UrlQuerySanitizer.IllegalCharacterValueSanitizer(
+                UrlQuerySanitizer.IllegalCharacterValueSanitizer.SCRIPT_URL_OK);
+        assertEquals("javascript:alert()", sanitizer.sanitize("javascript:alert()"));
+    }
+
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q) // Only fixed in R
+    public void testScriptUrlBlocked_73822755() {
+        ValueSanitizer sanitizer = UrlQuerySanitizer.getUrlAndSpaceLegal();
+        assertEquals("", sanitizer.sanitize("javascript:alert()"));
+    }
+
     private static class MockValueSanitizer implements ValueSanitizer{
 
         public String sanitize(String value) {
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 6214f89..824146f 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
@@ -16,6 +16,7 @@
 
 package android.net.cts.util;
 
+import static android.Manifest.permission.NETWORK_SETTINGS;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 
@@ -107,6 +108,8 @@
         boolean connected = false;
         try {
             SystemUtil.runShellCommand("svc wifi enable");
+            SystemUtil.runWithShellPermissionIdentity(() -> mWifiManager.reconnect(),
+                    NETWORK_SETTINGS);
             // Ensure we get both an onAvailable callback and a CONNECTIVITY_ACTION.
             wifiNetwork = callback.waitForAvailable();
             assertNotNull(wifiNetwork);
diff --git a/tests/cts/tethering/Android.bp b/tests/cts/tethering/Android.bp
index 0f98125..85bb0e0 100644
--- a/tests/cts/tethering/Android.bp
+++ b/tests/cts/tethering/Android.bp
@@ -25,12 +25,22 @@
     ],
 
     static_libs: [
+        "TetheringCommonTests",
+        "TetheringIntegrationTestsLib",
         "compatibility-device-util-axt",
+        "cts-net-utils",
+        "net-tests-utils",
         "ctstestrunner-axt",
         "junit",
         "junit-params",
     ],
 
+    jni_libs: [
+        // For mockito extended
+        "libdexmakerjvmtiagent",
+        "libstaticjvmtiagent",
+    ],
+
     // Change to system current when TetheringManager move to bootclass path.
     platform_apis: true,
 
@@ -41,4 +51,6 @@
         "mts",
     ],
 
+    // Include both the 32 and 64 bit versions
+    compile_multilib: "both",
 }
diff --git a/tests/cts/tethering/OWNERS b/tests/cts/tethering/OWNERS
new file mode 100644
index 0000000..cd6abeb
--- /dev/null
+++ b/tests/cts/tethering/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 31808
+lorenzo@google.com
+satk@google.com
+
diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
index 4d72eae..bbb9403 100644
--- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
+++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
@@ -15,21 +15,59 @@
  */
 package android.tethering.test;
 
+import static android.content.pm.PackageManager.FEATURE_TELEPHONY;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
+import static android.net.TetheringManager.TETHERING_USB;
 import static android.net.TetheringManager.TETHERING_WIFI;
+import static android.net.TetheringManager.TETHERING_WIFI_P2P;
+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_ERROR_TETHER_IFACE_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.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
 
+import android.app.UiAutomation;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
+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.os.ConditionVariable;
+import android.net.cts.util.CtsNetUtils;
+import android.net.wifi.WifiManager;
+import android.os.Bundle;
+import android.os.ResultReceiver;
+import android.telephony.TelephonyManager;
 
+import androidx.annotation.NonNull;
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.testutils.ArrayTrackRecord;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -37,31 +75,49 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Iterator;
-import java.util.concurrent.Executor;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
 
 @RunWith(AndroidJUnit4.class)
 public class TetheringManagerTest {
 
     private Context mContext;
 
+    private ConnectivityManager mCm;
     private TetheringManager mTM;
+    private WifiManager mWm;
+    private PackageManager mPm;
 
     private TetherChangeReceiver mTetherChangeReceiver;
-
-    private String[] mTetheredList;
+    private CtsNetUtils mCtsNetUtils;
 
     private static final int DEFAULT_TIMEOUT_MS = 60_000;
 
+    private void adoptShellPermissionIdentity() {
+        final UiAutomation uiAutomation =
+                InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        uiAutomation.adoptShellPermissionIdentity();
+    }
+
+    private void dropShellPermissionIdentity() {
+        final UiAutomation uiAutomation =
+                InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        uiAutomation.dropShellPermissionIdentity();
+    }
+
     @Before
     public void setUp() throws Exception {
-        InstrumentationRegistry.getInstrumentation()
-                .getUiAutomation()
-                .adoptShellPermissionIdentity();
+        adoptShellPermissionIdentity();
         mContext = InstrumentationRegistry.getContext();
+        mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
         mTM = (TetheringManager) mContext.getSystemService(Context.TETHERING_SERVICE);
+        mWm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+        mPm = mContext.getPackageManager();
+        mCtsNetUtils = new CtsNetUtils(mContext);
         mTetherChangeReceiver = new TetherChangeReceiver();
         final IntentFilter filter = new IntentFilter(
                 TetheringManager.ACTION_TETHER_STATE_CHANGED);
@@ -71,10 +127,9 @@
 
     @After
     public void tearDown() throws Exception {
+        mTM.stopAllTethering();
         mContext.unregisterReceiver(mTetherChangeReceiver);
-        InstrumentationRegistry.getInstrumentation()
-                .getUiAutomation()
-                .dropShellPermissionIdentity();
+        dropShellPermissionIdentity();
     }
 
     private class TetherChangeReceiver extends BroadcastReceiver {
@@ -103,28 +158,24 @@
 
         public final LinkedBlockingQueue<TetherState> mResult = new LinkedBlockingQueue<>();
 
-        // This method expects either an event where one of the interfaces is active, or events
-        // where the interfaces are available followed by one event where one of the interfaces is
-        // active. Here is a typical example for wifi tethering:
-        // AVAILABLE(wlan0) -> AVAILABLE(wlan1) -> ACTIVATE(wlan1).
-        public void expectActiveTethering(String[] ifaceRegexs) {
-            TetherState state = null;
+        // Expects that tethering reaches the desired state.
+        // - If active is true, expects that tethering is enabled on at least one interface
+        //   matching ifaceRegexs.
+        // - If active is false, expects that tethering is disabled on all the interfaces matching
+        //   ifaceRegexs.
+        // Fails if any interface matching ifaceRegexs becomes errored.
+        public void expectTethering(final boolean active, final String[] ifaceRegexs) {
             while (true) {
-                state = pollAndAssertNoError(DEFAULT_TIMEOUT_MS);
-                if (state == null) fail("Do not receive active state change broadcast");
+                final TetherState state = pollAndAssertNoError(DEFAULT_TIMEOUT_MS, ifaceRegexs);
+                assertNotNull("Did not receive expected state change, active: " + active, state);
 
-                if (isIfaceActive(ifaceRegexs, state)) return;
-
-                if (!isIfaceAvailable(ifaceRegexs, state)) break;
+                if (isIfaceActive(ifaceRegexs, state) == active) return;
             }
-
-            fail("Tethering is not actived, available ifaces: " + state.mAvailable.toString()
-                    + ", active ifaces: " + state.mActive.toString());
         }
 
-        private TetherState pollAndAssertNoError(final int timeout) {
+        private TetherState pollAndAssertNoError(final int timeout, final String[] ifaceRegexs) {
             final TetherState state = pollTetherState(timeout);
-            assertNoErroredIfaces(state);
+            assertNoErroredIfaces(state, ifaceRegexs);
             return state;
         }
 
@@ -141,59 +192,72 @@
             return isIfaceMatch(ifaceRegexs, state.mActive);
         }
 
-        private boolean isIfaceAvailable(final String[] ifaceRegexs, final TetherState state) {
-            return isIfaceMatch(ifaceRegexs, state.mAvailable);
-        }
-
-        // This method requires a broadcast to have been recorded iff the timeout is non-zero.
-        public void expectNoActiveTethering(final int timeout) {
-            final TetherState state = pollAndAssertNoError(timeout);
-
-            if (state == null) {
-                if (timeout != 0) {
-                    fail("Do not receive tethering state change broadcast");
-                }
-                return;
-            }
-
-            assertNoActiveIfaces(state);
-
-            for (final TetherState ts : mResult) {
-                assertNoErroredIfaces(ts);
-
-                assertNoActiveIfaces(ts);
-            }
-        }
-
-        private void assertNoErroredIfaces(final TetherState state) {
+        private void assertNoErroredIfaces(final TetherState state, final String[] ifaceRegexs) {
             if (state == null || state.mErrored == null) return;
 
-            if (state.mErrored.size() > 0) {
+            if (isIfaceMatch(ifaceRegexs, state.mErrored)) {
                 fail("Found failed tethering interfaces: " + Arrays.toString(state.mErrored.toArray()));
             }
         }
-
-        private void assertNoActiveIfaces(final TetherState state) {
-            if (state.mActive != null && state.mActive.size() > 0) {
-                fail("Found active tethering interface: " + Arrays.toString(state.mActive.toArray()));
-            }
-        }
     }
 
-    private class StartTetheringCallback implements TetheringManager.StartTetheringCallback {
+    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() {
-            // Do nothing, TetherChangeReceiver will wait until it receives the broadcast.
+            mHistory.add(new CallbackValue.OnTetheringStarted());
         }
 
         @Override
         public void onTetheringFailed(final int error) {
-            fail("startTethering fail: " + 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 String[] ifaceRegexs,
-            final ArrayList<String> ifaces) {
+    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;
@@ -215,14 +279,446 @@
         final String[] wifiRegexs = mTM.getTetherableWifiRegexs();
         if (wifiRegexs.length == 0) return;
 
-        mTetherChangeReceiver.expectNoActiveTethering(0 /** timeout */);
+        final String[] tetheredIfaces = mTM.getTetheredIfaces();
+        assertTrue(tetheredIfaces.length == 0);
 
         final StartTetheringCallback startTetheringCallback = new StartTetheringCallback();
-        mTM.startTethering(new TetheringRequest.Builder(TETHERING_WIFI).build(), c -> c.run(),
-                startTetheringCallback);
-        mTetherChangeReceiver.expectActiveTethering(wifiRegexs);
+        mTM.startTethering(new TetheringRequest.Builder(TETHERING_WIFI).build(),
+                c -> c.run() /* executor */, startTetheringCallback);
+        startTetheringCallback.verifyTetheringStarted();
+
+        mTetherChangeReceiver.expectTethering(true /* active */, wifiRegexs);
 
         mTM.stopTethering(TETHERING_WIFI);
-        mTetherChangeReceiver.expectNoActiveTethering(DEFAULT_TIMEOUT_MS);
+        mTetherChangeReceiver.expectTethering(false /* active */, wifiRegexs);
+    }
+
+    @Test
+    public void testTetheringRequest() {
+        final TetheringRequest tr = new TetheringRequest.Builder(TETHERING_WIFI).build();
+        assertEquals(TETHERING_WIFI, tr.getTetheringType());
+        assertNull(tr.getLocalIpv4Address());
+        assertNull(tr.getClientStaticIpv4Address());
+        assertFalse(tr.isExemptFromEntitlementCheck());
+        assertTrue(tr.getShouldShowEntitlementUi());
+
+        final LinkAddress localAddr = new LinkAddress("192.168.24.5/24");
+        final LinkAddress clientAddr = new LinkAddress("192.168.24.100/24");
+        final TetheringRequest tr2 = new TetheringRequest.Builder(TETHERING_USB)
+                .setStaticIpv4Addresses(localAddr, clientAddr)
+                .setExemptFromEntitlementCheck(true)
+                .setShouldShowEntitlementUi(false).build();
+
+        assertEquals(localAddr, tr2.getLocalIpv4Address());
+        assertEquals(clientAddr, tr2.getClientStaticIpv4Address());
+        assertEquals(TETHERING_USB, tr2.getTetheringType());
+        assertTrue(tr2.isExemptFromEntitlementCheck());
+        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();
+        mTM.startTethering(new TetheringRequest.Builder(TETHERING_WIFI).build(),
+                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);
+        callback.expectTetheredInterfacesChanged(null);
+        callback.expectOneOfOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
+    }
+
+    @Test
+    public void testRegisterTetheringEventCallback() throws Exception {
+        final TestTetheringEventCallback tetherEventCallback = registerTetheringEventCallback();
+        tetherEventCallback.assumeTetheringSupported();
+
+        if (!isWifiTetheringSupported(tetherEventCallback)) {
+            unregisterTetheringEventCallback(tetherEventCallback);
+            return;
+        }
+
+        startWifiTethering(tetherEventCallback);
+
+        final List<String> tetheredIfaces = tetherEventCallback.getTetheredInterfaces();
+        assertEquals(1, tetheredIfaces.size());
+        final String wifiTetheringIface = tetheredIfaces.get(0);
+
+        stopWifiTethering(tetherEventCallback);
+
+        try {
+            final int ret = mTM.tether(wifiTetheringIface);
+
+            // There is no guarantee that the wifi interface will be available after disabling
+            // the hotspot, so don't fail the test if the call to tether() fails.
+            assumeTrue(ret == TETHER_ERROR_NO_ERROR);
+
+            // If calling #tether successful, there is a callback to tell the result of tethering
+            // setup.
+            tetherEventCallback.expectErrorOrTethered(wifiTetheringIface);
+        } finally {
+            mTM.untether(wifiTetheringIface);
+            unregisterTetheringEventCallback(tetherEventCallback);
+        }
+    }
+
+    @Test
+    public void testGetTetherableInterfaceRegexps() {
+        final TestTetheringEventCallback tetherEventCallback = registerTetheringEventCallback();
+        tetherEventCallback.assumeTetheringSupported();
+
+        final TetheringInterfaceRegexps tetherableRegexs =
+                tetherEventCallback.getTetheringInterfaceRegexps();
+        final List<String> wifiRegexs = tetherableRegexs.getTetherableWifiRegexs();
+        final List<String> usbRegexs = tetherableRegexs.getTetherableUsbRegexs();
+        final List<String> btRegexs = tetherableRegexs.getTetherableBluetoothRegexs();
+
+        assertEquals(wifiRegexs, Arrays.asList(mTM.getTetherableWifiRegexs()));
+        assertEquals(usbRegexs, Arrays.asList(mTM.getTetherableUsbRegexs()));
+        assertEquals(btRegexs, Arrays.asList(mTM.getTetherableBluetoothRegexs()));
+
+        //Verify that any regex name should only contain in one array.
+        wifiRegexs.forEach(s -> assertFalse(usbRegexs.contains(s)));
+        wifiRegexs.forEach(s -> assertFalse(btRegexs.contains(s)));
+        usbRegexs.forEach(s -> assertFalse(btRegexs.contains(s)));
+
+        unregisterTetheringEventCallback(tetherEventCallback);
+    }
+
+    @Test
+    public void testStopAllTethering() throws Exception {
+        final TestTetheringEventCallback tetherEventCallback = registerTetheringEventCallback();
+        tetherEventCallback.assumeTetheringSupported();
+
+        try {
+            if (!isWifiTetheringSupported(tetherEventCallback)) return;
+
+            // TODO: start ethernet tethering here when TetheringManagerTest is moved to
+            // TetheringIntegrationTest.
+
+            startWifiTethering(tetherEventCallback);
+
+            mTM.stopAllTethering();
+            tetherEventCallback.expectTetheredInterfacesChanged(null);
+        } finally {
+            unregisterTetheringEventCallback(tetherEventCallback);
+        }
+    }
+
+    @Test
+    public void testEnableTetheringPermission() throws Exception {
+        dropShellPermissionIdentity();
+        final StartTetheringCallback startTetheringCallback = new StartTetheringCallback();
+        mTM.startTethering(new TetheringRequest.Builder(TETHERING_WIFI).build(),
+                c -> c.run() /* executor */, startTetheringCallback);
+        startTetheringCallback.expectTetheringFailed(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
+    }
+
+    private class EntitlementResultListener implements OnTetheringEntitlementResultListener {
+        private final CompletableFuture<Integer> future = new CompletableFuture<>();
+
+        @Override
+        public void onTetheringEntitlementResult(int result) {
+            future.complete(result);
+        }
+
+        public int get(long timeout, TimeUnit unit) throws Exception {
+            return future.get(timeout, unit);
+        }
+
+    }
+
+    private void assertEntitlementResult(final Consumer<EntitlementResultListener> functor,
+            final int expect) throws Exception {
+        final EntitlementResultListener listener = new EntitlementResultListener();
+        functor.accept(listener);
+
+        assertEquals(expect, listener.get(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS));
+    }
+
+    @Test
+    public void testRequestLatestEntitlementResult() throws Exception {
+        // Verify that requestLatestTetheringEntitlementResult() can get entitlement
+        // result(TETHER_ERROR_ENTITLEMENT_UNKNOWN due to invalid downstream type) via listener.
+        assertEntitlementResult(listener -> mTM.requestLatestTetheringEntitlementResult(
+                TETHERING_WIFI_P2P, false, c -> c.run(), listener),
+                TETHER_ERROR_ENTITLEMENT_UNKNOWN);
+
+        // Verify that requestLatestTetheringEntitlementResult() can get entitlement
+        // result(TETHER_ERROR_ENTITLEMENT_UNKNOWN due to invalid downstream type) via receiver.
+        assertEntitlementResult(listener -> mTM.requestLatestTetheringEntitlementResult(
+                TETHERING_WIFI_P2P,
+                new ResultReceiver(null /* handler */) {
+                    @Override
+                    public void onReceiveResult(int resultCode, Bundle resultData) {
+                        listener.onTetheringEntitlementResult(resultCode);
+                    }
+                }, false),
+                TETHER_ERROR_ENTITLEMENT_UNKNOWN);
+
+        // Verify that null listener will cause IllegalArgumentException.
+        try {
+            mTM.requestLatestTetheringEntitlementResult(
+                    TETHERING_WIFI, false, c -> c.run(), null);
+        } catch (IllegalArgumentException expect) { }
+    }
+
+    @Test
+    public void testTetheringUpstream() throws Exception {
+        assumeTrue(mPm.hasSystemFeature(FEATURE_TELEPHONY));
+        final TestTetheringEventCallback tetherEventCallback = registerTetheringEventCallback();
+        tetherEventCallback.assumeTetheringSupported();
+        final boolean previousWifiEnabledState = mWm.isWifiEnabled();
+
+        try {
+            if (!isWifiTetheringSupported(tetherEventCallback)) return;
+
+            if (previousWifiEnabledState) {
+                mCtsNetUtils.disconnectFromWifi(null);
+            }
+
+            final Network activeNetwork = mCm.getActiveNetwork();
+            assertNotNull("No active network. Please ensure the device has working mobile data.",
+                    activeNetwork);
+            final NetworkCapabilities activeNetCap = mCm.getNetworkCapabilities(activeNetwork);
+
+            // If active nework is ETHERNET, tethering may not use cell network as upstream.
+            assumeFalse(activeNetCap.hasTransport(TRANSPORT_ETHERNET));
+
+            assertTrue(activeNetCap.hasTransport(TRANSPORT_CELLULAR));
+
+            startWifiTethering(tetherEventCallback);
+
+            final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
+                    Context.TELEPHONY_SERVICE);
+            final boolean dunRequired = telephonyManager.isTetheringApnRequired();
+            final int expectedCap = dunRequired ? NET_CAPABILITY_DUN : NET_CAPABILITY_INTERNET;
+            final Network network = tetherEventCallback.getCurrentValidUpstream();
+            final NetworkCapabilities netCap = mCm.getNetworkCapabilities(network);
+            assertTrue(netCap.hasTransport(TRANSPORT_CELLULAR));
+            assertTrue(netCap.hasCapability(expectedCap));
+
+            stopWifiTethering(tetherEventCallback);
+        } finally {
+            unregisterTetheringEventCallback(tetherEventCallback);
+            if (previousWifiEnabledState) {
+                mCtsNetUtils.connectToWifi();
+            }
+        }
     }
 }
