diff --git a/tests/cts/hostside/AndroidTest.xml b/tests/cts/hostside/AndroidTest.xml
index 4a2e2e3..0656cae 100644
--- a/tests/cts/hostside/AndroidTest.xml
+++ b/tests/cts/hostside/AndroidTest.xml
@@ -14,8 +14,15 @@
      limitations under the License.
 -->
 <configuration description="Config for CTS net host test cases">
+    <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="networking" />
     <target_preparer class="com.android.cts.net.NetPolicyTestsPreparer" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="teardown-command" value="cmd power set-mode 0" />
+        <option name="teardown-command" value="cmd battery reset" />
+    </target_preparer>
+
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
         <option name="jar" value="CtsHostsideNetworkTests.jar" />
         <option name="runtime-hint" value="3m56s" />
diff --git a/tests/cts/hostside/app/Android.mk b/tests/cts/hostside/app/Android.mk
index f094f3f..c03e70b 100644
--- a/tests/cts/hostside/app/Android.mk
+++ b/tests/cts/hostside/app/Android.mk
@@ -23,6 +23,8 @@
 LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util ctstestrunner ub-uiautomator \
         CtsHostsideNetworkTestsAidl
 
+LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := CtsHostsideNetworkTestsApp
diff --git a/tests/cts/hostside/app/AndroidManifest.xml b/tests/cts/hostside/app/AndroidManifest.xml
index 7466cb8..2553f47 100644
--- a/tests/cts/hostside/app/AndroidManifest.xml
+++ b/tests/cts/hostside/app/AndroidManifest.xml
@@ -20,6 +20,7 @@
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
+    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
     <uses-permission android:name="android.permission.INTERNET"/>
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java
index d2c0873..0e141c0 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java
@@ -34,7 +34,7 @@
         removePowerSaveModeWhitelist(TEST_APP2_PKG);
         removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
         setAppIdle(false);
-        turnBatteryOff();
+        turnBatteryOn();
 
         registerBroadcastReceiver();
     }
@@ -48,7 +48,7 @@
         try {
             tearDownMeteredNetwork();
         } finally {
-            turnBatteryOn();
+            turnBatteryOff();
             setAppIdle(false);
         }
     }
@@ -127,6 +127,19 @@
         assertBackgroundNetworkAccess(false);
     }
 
+    public void testBackgroundNetworkAccess_tempWhitelisted() throws Exception {
+        if (!isSupported()) return;
+
+        setAppIdle(true);
+        assertBackgroundNetworkAccess(false);
+
+        addTempPowerSaveModeWhitelist(TEST_APP2_PKG, TEMP_POWERSAVE_WHITELIST_DURATION_MS);
+        assertBackgroundNetworkAccess(true);
+        // Wait until the whitelist duration is expired.
+        SystemClock.sleep(TEMP_POWERSAVE_WHITELIST_DURATION_MS);
+        assertBackgroundNetworkAccess(false);
+    }
+
     public void testBackgroundNetworkAccess_disabled() throws Exception {
         if (!isSupported()) return;
 
@@ -142,9 +155,9 @@
         // Check that app is paroled when charging
         setAppIdle(true);
         assertBackgroundNetworkAccess(false);
-        turnBatteryOn();
-        assertBackgroundNetworkAccess(true);
         turnBatteryOff();
+        assertBackgroundNetworkAccess(true);
+        turnBatteryOn();
         assertBackgroundNetworkAccess(false);
 
         // Check that app is restricted when not idle but power-save is on
@@ -154,11 +167,11 @@
         assertBackgroundNetworkAccess(false);
         // Use setBatterySaverMode API to leave power-save mode instead of plugging in charger
         setBatterySaverMode(false);
-        turnBatteryOn();
+        turnBatteryOff();
         assertBackgroundNetworkAccess(true);
 
         // And when no longer charging, it still has network access, since it's not idle
-        turnBatteryOff();
+        turnBatteryOn();
         assertBackgroundNetworkAccess(true);
     }
 
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 ce56d25..03659dc 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
@@ -49,8 +49,6 @@
 import android.text.TextUtils;
 import android.util.Log;
 
-import com.android.cts.net.hostside.INetworkStateObserver;
-
 /**
  * Superclass for tests related to background network restrictions.
  */
@@ -87,7 +85,7 @@
     private static final String NETWORK_STATUS_SEPARATOR = "\\|";
     private static final int SECOND_IN_MS = 1000;
     static final int NETWORK_TIMEOUT_MS = 15 * SECOND_IN_MS;
-    private static final int PROCESS_STATE_FOREGROUND_SERVICE = 4;
+    private static final int PROCESS_STATE_FOREGROUND_SERVICE = 3;
     private static final int PROCESS_STATE_TOP = 2;
 
     private static final String KEY_NETWORK_STATE_OBSERVER = TEST_PKG + ".observer";
@@ -108,6 +106,8 @@
 
     private static final String APP_NOT_FOREGROUND_ERROR = "app_not_fg";
 
+    protected static final long TEMP_POWERSAVE_WHITELIST_DURATION_MS = 5_000; // 5 sec
+
     protected Context mContext;
     protected Instrumentation mInstrumentation;
     protected ConnectivityManager mCm;
@@ -138,6 +138,7 @@
             enableLocation();
         }
         mSupported = setUpActiveNetworkMeteringState();
+        setAppIdle(false);
 
         Log.i(TAG, "Apps status on " + getName() + ":\n"
                 + "\ttest app: uid=" + mMyUid + ", state=" + getProcessStateByUid(mMyUid) + "\n"
@@ -258,17 +259,21 @@
 
     protected void assertBackgroundNetworkAccess(boolean expectAllowed) throws Exception {
         assertBackgroundState(); // Sanity check.
-        assertNetworkAccess(expectAllowed);
+        assertNetworkAccess(expectAllowed /* expectAvailable */, false /* needScreenOn */);
     }
 
     protected void assertForegroundNetworkAccess() throws Exception {
         assertForegroundState(); // Sanity check.
-        assertNetworkAccess(true);
+        // We verified that app is in foreground state but if the screen turns-off while
+        // verifying for network access, the app will go into background state (in case app's
+        // foreground status was due to top activity). So, turn the screen on when verifying
+        // network connectivity.
+        assertNetworkAccess(true /* expectAvailable */, true /* needScreenOn */);
     }
 
     protected void assertForegroundServiceNetworkAccess() throws Exception {
         assertForegroundServiceState(); // Sanity check.
-        assertNetworkAccess(true);
+        assertNetworkAccess(true /* expectAvailable */, false /* needScreenOn */);
     }
 
     /**
@@ -367,7 +372,8 @@
     /**
      * Asserts whether the active network is available or not.
      */
-    private void assertNetworkAccess(boolean expectAvailable) throws Exception {
+    private void assertNetworkAccess(boolean expectAvailable, boolean needScreenOn)
+            throws Exception {
         final int maxTries = 5;
         String error = null;
         int timeoutMs = 500;
@@ -385,6 +391,9 @@
             Log.w(TAG, "Network status didn't match for expectAvailable=" + expectAvailable
                     + " on attempt #" + i + ": " + error + "\n"
                     + "Sleeping " + timeoutMs + "ms before trying again");
+            if (needScreenOn) {
+                turnScreenOn();
+            }
             // No sleep after the last turn
             if (i < maxTries) {
                 SystemClock.sleep(timeoutMs);
@@ -751,6 +760,12 @@
                 + ". Full list: " + uids);
     }
 
+    protected void addTempPowerSaveModeWhitelist(String packageName, long duration)
+            throws Exception {
+        Log.i(TAG, "Adding pkg " + packageName + " to temp-power-save-mode whitelist");
+        executeShellCommand("dumpsys deviceidle tempwhitelist -d " + duration + " " + packageName);
+    }
+
     protected void assertPowerSaveModeWhitelist(String packageName, boolean expected)
             throws Exception {
         // TODO: currently the power-save mode is behaving like idle, but once it changes, we'll
@@ -800,15 +815,14 @@
         assertPowerSaveModeExceptIdleWhitelist(packageName, false); // Sanity check
     }
 
-    protected void turnBatteryOff() throws Exception {
+    protected void turnBatteryOn() throws Exception {
         executeSilentShellCommand("cmd battery unplug");
         assertBatteryState(false);
     }
 
-    protected void turnBatteryOn() throws Exception {
+    protected void turnBatteryOff() throws Exception {
         executeSilentShellCommand("cmd battery reset");
         assertBatteryState(true);
-
     }
 
     private void assertBatteryState(boolean pluggedIn) throws Exception {
@@ -839,11 +853,11 @@
     protected void setBatterySaverMode(boolean enabled) throws Exception {
         Log.i(TAG, "Setting Battery Saver Mode to " + enabled);
         if (enabled) {
-            turnBatteryOff();
+            turnBatteryOn();
             executeSilentShellCommand("cmd power set-mode 1");
         } else {
             executeSilentShellCommand("cmd power set-mode 0");
-            turnBatteryOn();
+            turnBatteryOff();
         }
     }
 
@@ -853,12 +867,12 @@
 
         Log.i(TAG, "Setting Doze Mode to " + enabled);
         if (enabled) {
-            turnBatteryOff();
+            turnBatteryOn();
             turnScreenOff();
             executeShellCommand("dumpsys deviceidle force-idle deep");
         } else {
             turnScreenOn();
-            turnBatteryOn();
+            turnBatteryOff();
             executeShellCommand("dumpsys deviceidle unforce");
         }
         // Sanity check.
@@ -1004,7 +1018,8 @@
     private Intent getIntentForComponent(int type) {
         final Intent intent = new Intent();
         if (type == TYPE_COMPONENT_ACTIVTIY) {
-            intent.setComponent(new ComponentName(TEST_APP2_PKG, TEST_APP2_ACTIVITY_CLASS));
+            intent.setComponent(new ComponentName(TEST_APP2_PKG, TEST_APP2_ACTIVITY_CLASS))
+                    .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         } else if (type == TYPE_COMPONENT_FOREGROUND_SERVICE) {
             intent.setComponent(new ComponentName(TEST_APP2_PKG, TEST_APP2_SERVICE_CLASS))
                     .setFlags(1);
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java
index 5248255..76332be 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java
@@ -15,6 +15,7 @@
  */
 package com.android.cts.net.hostside;
 
+import android.os.SystemClock;
 import android.util.Log;
 
 /**
@@ -271,4 +272,55 @@
             setDozeMode(false);
         }
     }
+
+    public void testAppIdleAndDoze_tempPowerSaveWhitelists() throws Exception {
+        if (!isSupported()) {
+            return;
+        }
+        if (!isDozeModeEnabled()) {
+            Log.i(TAG, "Skipping " + getClass() + "." + getName()
+                    + "() because device does not support Doze Mode");
+            return;
+        }
+
+        setDozeMode(true);
+        setAppIdle(true);
+
+        try {
+            assertBackgroundNetworkAccess(false);
+
+            addTempPowerSaveModeWhitelist(TEST_APP2_PKG, TEMP_POWERSAVE_WHITELIST_DURATION_MS);
+            assertBackgroundNetworkAccess(true);
+
+            // Wait until the whitelist duration is expired.
+            SystemClock.sleep(TEMP_POWERSAVE_WHITELIST_DURATION_MS);
+            assertBackgroundNetworkAccess(false);
+        } finally {
+            setAppIdle(false);
+            setDozeMode(false);
+        }
+    }
+
+    public void testAppIdleAndBatterySaver_tempPowerSaveWhitelists() throws Exception {
+        if (!isSupported()) {
+            return;
+        }
+
+        setBatterySaverMode(true);
+        setAppIdle(true);
+
+        try {
+            assertBackgroundNetworkAccess(false);
+
+            addTempPowerSaveModeWhitelist(TEST_APP2_PKG, TEMP_POWERSAVE_WHITELIST_DURATION_MS);
+            assertBackgroundNetworkAccess(true);
+
+            // Wait until the whitelist duration is expired.
+            SystemClock.sleep(TEMP_POWERSAVE_WHITELIST_DURATION_MS);
+            assertBackgroundNetworkAccess(false);
+        } finally {
+            setAppIdle(false);
+            setBatterySaverMode(false);
+        }
+    }
 }
diff --git a/tests/cts/hostside/app2/AndroidManifest.xml b/tests/cts/hostside/app2/AndroidManifest.xml
index adf0045..ad270b3 100644
--- a/tests/cts/hostside/app2/AndroidManifest.xml
+++ b/tests/cts/hostside/app2/AndroidManifest.xml
@@ -19,6 +19,7 @@
     package="com.android.cts.net.hostside.app2" >
 
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
     <uses-permission android:name="android.permission.INTERNET" />
 
     <!--
@@ -33,7 +34,7 @@
          This application also provides a service, RemoteSocketFactoryService, that the test app can
          use to open sockets to remote hosts as a different user ID.
     -->
-    <application>
+    <application android:usesCleartextTraffic="true">
         <activity android:name=".MyActivity" android:exported="true"/>
         <service android:name=".MyService" android:exported="true"/>
         <service android:name=".MyForegroundService" android:exported="true"/>
diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java
index c6df893..7c9ce8f 100644
--- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java
+++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java
@@ -19,13 +19,13 @@
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.TestIdentifier;
-import com.android.ddmlib.testrunner.TestResult;
 import com.android.ddmlib.testrunner.TestResult.TestStatus;
-import com.android.ddmlib.testrunner.TestRunResult;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.result.TestDescription;
+import com.android.tradefed.result.TestResult;
+import com.android.tradefed.result.TestRunResult;
 import com.android.tradefed.testtype.DeviceTestCase;
 import com.android.tradefed.testtype.IAbi;
 import com.android.tradefed.testtype.IAbiReceiver;
@@ -150,7 +150,7 @@
         if (result.hasFailedTests()) {
             // build a meaningful error message
             StringBuilder errorBuilder = new StringBuilder("on-device tests failed:\n");
-            for (Map.Entry<TestIdentifier, TestResult> resultEntry :
+            for (Map.Entry<TestDescription, TestResult> resultEntry :
                 result.getTestResults().entrySet()) {
                 if (!resultEntry.getValue().getStatus().equals(TestStatus.PASSED)) {
                     errorBuilder.append(resultEntry.getKey().toString());
diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
index bf3fc08..fe9d36c 100644
--- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
+++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
@@ -146,6 +146,11 @@
                 "testBackgroundNetworkAccess_whitelisted");
     }
 
+    public void testAppIdleMetered_tempWhitelisted() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleMeteredTest",
+                "testBackgroundNetworkAccess_tempWhitelisted");
+    }
+
     public void testAppIdleMetered_enabled() throws Exception {
         runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleMeteredTest",
                 "testBackgroundNetworkAccess_enabled");
@@ -166,6 +171,11 @@
                 "testBackgroundNetworkAccess_whitelisted");
     }
 
+    public void testAppIdleNonMetered_tempWhitelisted() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleNonMeteredTest",
+                "testBackgroundNetworkAccess_tempWhitelisted");
+    }
+
     public void testAppIdleNonMetered_enabled() throws Exception {
         runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleNonMeteredTest",
                 "testBackgroundNetworkAccess_enabled");
@@ -261,6 +271,16 @@
                 "testDozeAndAppIdle_powerSaveWhitelists");
     }
 
+    public void testAppIdleAndDoze_tempPowerSaveWhitelists() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".MixedModesTest",
+                "testAppIdleAndDoze_tempPowerSaveWhitelists");
+    }
+
+    public void testAppIdleAndBatterySaver_tempPowerSaveWhitelists() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".MixedModesTest",
+                "testAppIdleAndBatterySaver_tempPowerSaveWhitelists");
+    }
+
     /*******************
      * Helper methods. *
      *******************/
diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk
index 4aeab38..1430071 100644
--- a/tests/cts/net/Android.mk
+++ b/tests/cts/net/Android.mk
@@ -24,7 +24,12 @@
 # Include both the 32 and 64 bit versions
 LOCAL_MULTILIB := both
 
-LOCAL_JAVA_LIBRARIES := voip-common conscrypt org.apache.http.legacy
+LOCAL_JAVA_LIBRARIES := \
+    voip-common \
+    conscrypt \
+    org.apache.http.legacy \
+    android.test.base.stubs \
+
 
 LOCAL_JNI_SHARED_LIBRARIES := libcts_jni libnativedns_jni \
                               libnativemultinetwork_jni libnativehelper_compat_libc++
@@ -41,10 +46,11 @@
     ctstestserver \
     mockwebserver \
     junit \
-    legacy-android-test
+    truth-prebuilt
 
 # uncomment when b/13249961 is fixed
 #LOCAL_SDK_VERSION := current
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 # Tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml
index dd310a1..0bfb650 100644
--- a/tests/cts/net/AndroidManifest.xml
+++ b/tests/cts/net/AndroidManifest.xml
@@ -21,6 +21,7 @@
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
@@ -30,7 +31,7 @@
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
 
-    <application>
+    <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/AndroidTest.xml b/tests/cts/net/AndroidTest.xml
index 4a578ea..1326970 100644
--- a/tests/cts/net/AndroidTest.xml
+++ b/tests/cts/net/AndroidTest.xml
@@ -13,6 +13,7 @@
      limitations under the License.
 -->
 <configuration description="Config for CTS Net test cases">
+    <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="networking" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
@@ -22,5 +23,6 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.net.cts" />
         <option name="runtime-hint" value="9m4s" />
+        <option name="hidden-api-checks" value="false" />
     </test>
 </configuration>
diff --git a/tests/cts/net/OWNERS b/tests/cts/net/OWNERS
new file mode 100644
index 0000000..dc82bb0
--- /dev/null
+++ b/tests/cts/net/OWNERS
@@ -0,0 +1,2 @@
+lorenzo@google.com
+satk@google.com
\ No newline at end of file
diff --git a/tests/cts/net/assets/network_watchlist_config_empty_for_test.xml b/tests/cts/net/assets/network_watchlist_config_empty_for_test.xml
new file mode 100644
index 0000000..19628d1
--- /dev/null
+++ b/tests/cts/net/assets/network_watchlist_config_empty_for_test.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright (C) 2018 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.
+*/
+-->
+<!-- This test config file is for NetworkWatchlistTest tests -->
+<watchlist-config>
+    <sha256-domain>
+    </sha256-domain>
+    <sha256-ip>
+    </sha256-ip>
+    <crc32-domain>
+    </crc32-domain>
+    <crc32-ip>
+    </crc32-ip>
+</watchlist-config>
diff --git a/tests/cts/net/assets/network_watchlist_config_for_test.xml b/tests/cts/net/assets/network_watchlist_config_for_test.xml
new file mode 100644
index 0000000..835ae0f
--- /dev/null
+++ b/tests/cts/net/assets/network_watchlist_config_for_test.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright (C) 2018 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.
+*/
+-->
+<!-- This test config file just contains some random hashes for testing
+ConnectivityManager.getWatchlistConfigHash() -->
+<watchlist-config>
+    <sha256-domain>
+        <hash>F0905DA7549614957B449034C281EF7BDEFDBC2B6E050AD1E78D6DE18FBD0D5F</hash>
+    </sha256-domain>
+    <sha256-ip>
+        <hash>18DD41C9F2E8E4879A1575FB780514EF33CF6E1F66578C4AE7CCA31F49B9F2EC</hash>
+    </sha256-ip>
+    <crc32-domain>
+        <hash>AAAAAAAA</hash>
+    </crc32-domain>
+    <crc32-ip>
+        <hash>BBBBBBBB</hash>
+    </crc32-ip>
+</watchlist-config>
diff --git a/tests/cts/net/jni/Android.mk b/tests/cts/net/jni/Android.mk
index 887e95e..727a44d 100644
--- a/tests/cts/net/jni/Android.mk
+++ b/tests/cts/net/jni/Android.mk
@@ -28,7 +28,7 @@
 LOCAL_SHARED_LIBRARIES := libnativehelper_compat_libc++ liblog
 LOCAL_CXX_STL := libc++_static
 
-LOCAL_CFLAGS := -Wno-unused-parameter
+LOCAL_CFLAGS := -Wall -Werror -Wno-unused-parameter
 
 include $(BUILD_SHARED_LIBRARY)
 
@@ -37,6 +37,7 @@
 # Don't include this package in any configuration by default.
 LOCAL_MODULE_TAGS := optional
 LOCAL_SRC_FILES := NativeMultinetworkJni.c
+LOCAL_CFLAGS := -Wall -Werror -Wno-format
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
 LOCAL_SHARED_LIBRARIES := libandroid libnativehelper_compat_libc++ liblog
 LOCAL_CXX_STL := libc++_static
diff --git a/tests/cts/net/jni/NativeMultinetworkJni.c b/tests/cts/net/jni/NativeMultinetworkJni.c
index 9156504..2fa5291 100644
--- a/tests/cts/net/jni/NativeMultinetworkJni.c
+++ b/tests/cts/net/jni/NativeMultinetworkJni.c
@@ -47,7 +47,7 @@
     const int saved_errno = errno;
     freeaddrinfo(res);
 
-    ALOGD("android_getaddrinfofornetwork(%llu, %s) returned rval=%d errno=%d",
+    ALOGD("android_getaddrinfofornetwork(%" PRIu64 ", %s) returned rval=%d errno=%d",
           handle, kHostname, rval, saved_errno);
     return rval == 0 ? 0 : -saved_errno;
 }
@@ -61,7 +61,7 @@
     errno = 0;
     int rval = android_setprocnetwork(handle);
     const int saved_errno = errno;
-    ALOGD("android_setprocnetwork(%llu) returned rval=%d errno=%d",
+    ALOGD("android_setprocnetwork(%" PRIu64 ") returned rval=%d errno=%d",
           handle, rval, saved_errno);
     return rval == 0 ? 0 : -saved_errno;
 }
@@ -82,7 +82,7 @@
     errno = 0;
     int rval = android_setsocknetwork(handle, fd);
     const int saved_errno = errno;
-    ALOGD("android_setprocnetwork(%llu, %d) returned rval=%d errno=%d",
+    ALOGD("android_setprocnetwork(%" PRIu64 ", %d) returned rval=%d errno=%d",
           handle, fd, rval, saved_errno);
     close(fd);
     return rval == 0 ? 0 : -saved_errno;
diff --git a/tests/cts/net/native/qtaguid/AndroidTest.xml b/tests/cts/net/native/qtaguid/AndroidTest.xml
index 2eea82e..7591c87 100644
--- a/tests/cts/net/native/qtaguid/AndroidTest.xml
+++ b/tests/cts/net/native/qtaguid/AndroidTest.xml
@@ -14,6 +14,7 @@
      limitations under the License.
 -->
 <configuration description="Config for CTS Native Network xt_qtaguid test cases">
+    <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="networking" />
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
         <option name="cleanup" value="true" />
diff --git a/tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp b/tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp
index 9009c24..7f790fb 100644
--- a/tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp
+++ b/tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp
@@ -15,14 +15,39 @@
  */
 
 #include <arpa/inet.h>
+#include <error.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <string.h>
 #include <sys/socket.h>
+#include <sys/utsname.h>
 
 #include <gtest/gtest.h>
 #include <cutils/qtaguid.h>
 
+int hasQtaguidKernelSupport() {
+    struct utsname buf;
+    int kernel_version_major;
+    int kernel_version_minor;
+
+    int ret = uname(&buf);
+    if (ret) {
+        ret = -errno;
+        return ret;
+    }
+    char dummy;
+    ret = sscanf(buf.release, "%d.%d%c", &kernel_version_major, &kernel_version_minor, &dummy);
+    if (ret < 3)
+        return -EINVAL;
+
+    if ((kernel_version_major == 4 && kernel_version_minor < 9) ||
+        (kernel_version_major < 4)) {
+        return 1;
+    } else {
+        return access("/proc/net/xt_qtaguid/ctrl", F_OK) != -1;
+    }
+}
+
 int getCtrlSkInfo(int tag, uid_t uid, uint64_t* sk_addr, int* ref_cnt) {
     FILE *fp;
     fp = fopen("/proc/net/xt_qtaguid/ctrl", "r");
@@ -70,6 +95,12 @@
 }
 
 TEST (NativeQtaguidTest, close_socket_without_untag) {
+    int res = hasQtaguidKernelSupport();
+    ASSERT_LE(0, res);
+    if (!res) {
+          GTEST_LOG_(INFO) << "This test is skipped since kernel may not have the module\n";
+          return;
+    }
     int sockfd = socket(AF_INET, SOCK_STREAM, 0);
     uid_t uid = getuid();
     int tag = arc4random();
@@ -83,6 +114,12 @@
 }
 
 TEST (NativeQtaguidTest, close_socket_without_untag_ipv6) {
+    int res = hasQtaguidKernelSupport();
+    ASSERT_LE(0, res);
+    if (!res) {
+          GTEST_LOG_(INFO) << "This test is skipped since kernel may not have the module\n";
+          return;
+    }
     int sockfd = socket(AF_INET6, SOCK_STREAM, 0);
     uid_t uid = getuid();
     int tag = arc4random();
@@ -96,12 +133,17 @@
 }
 
 TEST (NativeQtaguidTest, no_socket_addr_leak) {
+    int res = hasQtaguidKernelSupport();
+    ASSERT_LE(0, res);
+    if (!res) {
+          GTEST_LOG_(INFO) << "This test is skipped since kernel may not have the module\n";
+          return;
+    }
   checkNoSocketPointerLeaks(AF_INET);
   checkNoSocketPointerLeaks(AF_INET6);
 }
 
 int main(int argc, char **argv) {
       testing::InitGoogleTest(&argc, argv);
-
       return RUN_ALL_TESTS();
 }
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index c885942..441bee3 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -16,19 +16,28 @@
 
 package android.net.cts;
 
+import static android.content.pm.PackageManager.FEATURE_TELEPHONY;
+import static android.content.pm.PackageManager.FEATURE_WIFI;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import static android.provider.Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE;
+import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
 
+import android.app.Instrumentation;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
+import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkConfig;
@@ -38,26 +47,43 @@
 import android.net.NetworkRequest;
 import android.net.wifi.WifiManager;
 import android.os.Looper;
+import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
 import android.system.Os;
 import android.system.OsConstants;
 import android.test.AndroidTestCase;
+import android.text.TextUtils;
 import android.util.Log;
 
+import com.android.internal.R;
 import com.android.internal.telephony.PhoneConstants;
 
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.InputStream;
 import java.io.IOException;
+import java.io.InputStreamReader;
 import java.io.OutputStream;
+import java.lang.NumberFormatException;
+import java.net.HttpURLConnection;
+import java.net.Inet6Address;
+import java.net.InetAddress;
 import java.net.Socket;
 import java.net.InetSocketAddress;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Scanner;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import libcore.io.Streams;
 
 public class ConnectivityManagerTest extends AndroidTestCase {
 
@@ -72,6 +98,9 @@
     private static final String TEST_HOST = "connectivitycheck.gstatic.com";
     private static final int SOCKET_TIMEOUT_MS = 2000;
     private static final int SEND_BROADCAST_TIMEOUT = 30000;
+    private static final int NETWORK_CHANGE_METEREDNESS_TIMEOUT = 5000;
+    private static final int NUM_TRIES_MULTIPATH_PREF_CHECK = 20;
+    private static final long INTERVAL_MULTIPATH_PREF_CHECK_MS = 500;
     private static final int HTTP_PORT = 80;
     private static final String HTTP_REQUEST =
             "GET /generate_204 HTTP/1.0\r\n" +
@@ -101,18 +130,22 @@
     private static final int MIN_NUM_NETWORK_TYPES = 1;
 
     private Context mContext;
+    private Instrumentation mInstrumentation;
     private ConnectivityManager mCm;
     private WifiManager mWifiManager;
     private PackageManager mPackageManager;
     private final HashMap<Integer, NetworkConfig> mNetworks =
             new HashMap<Integer, NetworkConfig>();
     boolean mWifiConnectAttempted;
+    private TestNetworkCallback mCellNetworkCallback;
+
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
         Looper.prepare();
         mContext = getContext();
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
         mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
         mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
         mPackageManager = mContext.getPackageManager();
@@ -140,6 +173,10 @@
         if (mWifiConnectAttempted) {
             disconnectFromWifi(null);
         }
+        if (cellConnectAttempted()) {
+            disconnectFromCell();
+        }
+        super.tearDown();
     }
 
     /**
@@ -246,6 +283,95 @@
         }
     }
 
+    /**
+     * Tests that connections can be opened on WiFi and cellphone networks,
+     * and that they are made from different IP addresses.
+     */
+    public void testOpenConnection() throws Exception {
+        boolean canRunTest = mPackageManager.hasSystemFeature(FEATURE_WIFI)
+                && mPackageManager.hasSystemFeature(FEATURE_TELEPHONY);
+        if (!canRunTest) {
+            Log.i(TAG,"testOpenConnection cannot execute unless device supports both WiFi "
+                    + "and a cellular connection");
+            return;
+        }
+
+        Network wifiNetwork = connectToWifi();
+        Network cellNetwork = connectToCell();
+        // This server returns the requestor's IP address as the response body.
+        URL url = new URL("http://google-ipv6test.appspot.com/ip.js?fmt=text");
+        String wifiAddressString = httpGet(wifiNetwork, url);
+        String cellAddressString = httpGet(cellNetwork, url);
+
+        assertFalse(String.format("Same address '%s' on two different networks (%s, %s)",
+                wifiAddressString, wifiNetwork, cellNetwork),
+                wifiAddressString.equals(cellAddressString));
+
+        // Sanity check that the IP addresses that the requests appeared to come from
+        // are actually on the respective networks.
+        assertOnNetwork(wifiAddressString, wifiNetwork);
+        assertOnNetwork(cellAddressString, cellNetwork);
+
+        assertFalse("Unexpectedly equal: " + wifiNetwork, wifiNetwork.equals(cellNetwork));
+    }
+
+    private Network connectToCell() throws InterruptedException {
+        if (cellConnectAttempted()) {
+            throw new IllegalStateException("Already connected");
+        }
+        NetworkRequest cellRequest = new NetworkRequest.Builder()
+                .addTransportType(TRANSPORT_CELLULAR)
+                .addCapability(NET_CAPABILITY_INTERNET)
+                .build();
+        mCellNetworkCallback = new TestNetworkCallback();
+        mCm.requestNetwork(cellRequest, mCellNetworkCallback);
+        final Network cellNetwork = mCellNetworkCallback.waitForAvailable();
+        assertNotNull("Cell network not available within timeout", cellNetwork);
+        return cellNetwork;
+    }
+
+    private boolean cellConnectAttempted() {
+        return mCellNetworkCallback != null;
+    }
+
+    private void disconnectFromCell() {
+        if (!cellConnectAttempted()) {
+            throw new IllegalStateException("Cell connection not attempted");
+        }
+        mCm.unregisterNetworkCallback(mCellNetworkCallback);
+        mCellNetworkCallback = null;
+    }
+
+    /**
+     * Performs a HTTP GET to the specified URL on the specified Network, and returns
+     * the response body decoded as UTF-8.
+     */
+    private static String httpGet(Network network, URL httpUrl) throws IOException {
+        HttpURLConnection connection = (HttpURLConnection) network.openConnection(httpUrl);
+        try {
+            InputStream inputStream = connection.getInputStream();
+            return Streams.readFully(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
+        } finally {
+            connection.disconnect();
+        }
+    }
+
+    private void assertOnNetwork(String adressString, Network network) throws UnknownHostException {
+        InetAddress address = InetAddress.getByName(adressString);
+        LinkProperties linkProperties = mCm.getLinkProperties(network);
+        // To make sure that the request went out on the right network, check that
+        // the IP address seen by the server is assigned to the expected network.
+        // We can only do this for IPv6 addresses, because in IPv4 we will likely
+        // have a private IPv4 address, and that won't match what the server sees.
+        if (address instanceof Inet6Address) {
+            assertContains(linkProperties.getAddresses(), address);
+        }
+    }
+
+    private static<T> void assertContains(Collection<T> collection, T element) {
+        assertTrue(element + " not found in " + collection, collection.contains(element));
+    }
+
     private void assertStartUsingNetworkFeatureUnsupported(int networkType, String feature) {
         try {
             mCm.startUsingNetworkFeature(networkType, feature);
@@ -324,7 +450,7 @@
      * that it would increase test coverage by much (how many devices have 3G radio but not Wifi?).
      */
     public void testRegisterNetworkCallback() {
-        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+        if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
             Log.i(TAG, "testRegisterNetworkCallback cannot execute unless device supports WiFi");
             return;
         }
@@ -364,7 +490,7 @@
      * of a {@code NetworkCallback}.
      */
     public void testRegisterNetworkCallback_withPendingIntent() {
-        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+        if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
             Log.i(TAG, "testRegisterNetworkCallback cannot execute unless device supports WiFi");
             return;
         }
@@ -458,7 +584,7 @@
      * Tests reporting of connectivity changed.
      */
     public void testConnectivityChanged_manifestRequestOnly_shouldNotReceiveIntent() {
-        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+        if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
             Log.i(TAG, "testConnectivityChanged_manifestRequestOnly_shouldNotReceiveIntent cannot execute unless device supports WiFi");
             return;
         }
@@ -475,7 +601,7 @@
     }
 
     public void testConnectivityChanged_whenRegistered_shouldReceiveIntent() {
-        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+        if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
             Log.i(TAG, "testConnectivityChanged_whenRegistered_shouldReceiveIntent cannot execute unless device supports WiFi");
             return;
         }
@@ -495,14 +621,14 @@
 
     public void testConnectivityChanged_manifestRequestOnlyPreN_shouldReceiveIntent()
             throws InterruptedException {
-        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+        if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
             Log.i(TAG, "testConnectivityChanged_manifestRequestOnlyPreN_shouldReceiveIntent cannot execute unless device supports WiFi");
             return;
         }
-        Intent startIntent = new Intent();
-        startIntent.setComponent(new ComponentName("android.net.cts.appForApi23",
-                "android.net.cts.appForApi23.ConnectivityListeningActivity"));
-        mContext.startActivity(startIntent);
+        mContext.startActivity(new Intent()
+                .setComponent(new ComponentName("android.net.cts.appForApi23",
+                        "android.net.cts.appForApi23.ConnectivityListeningActivity"))
+                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
         Thread.sleep(200);
 
         toggleWifi();
@@ -835,4 +961,146 @@
         assertTrue(lowerBoundSec <= interval);
         assertTrue(interval <= upperBoundSec);
     }
+
+    // Returns "true", "false" or "none"
+    private String getWifiMeteredStatus(String ssid) throws Exception {
+        // Interestingly giving the SSID as an argument to list wifi-networks
+        // only works iff the network in question has the "false" policy.
+        // Also unfortunately runShellCommand does not pass the command to the interpreter
+        // so it's not possible to | grep the ssid.
+        final String command = "cmd netpolicy list wifi-networks";
+        final String policyString = runShellCommand(mInstrumentation, command);
+
+        final Matcher m = Pattern.compile("^" + ssid + ";(true|false|none)$",
+                Pattern.MULTILINE | Pattern.UNIX_LINES).matcher(policyString);
+        if (!m.find()) {
+            fail("Unexpected format from cmd netpolicy");
+        }
+        return m.group(1);
+    }
+
+    // metered should be "true", "false" or "none"
+    private void setWifiMeteredStatus(String ssid, String metered) throws Exception {
+        final String setCommand = "cmd netpolicy set metered-network " + ssid + " " + metered;
+        runShellCommand(mInstrumentation, setCommand);
+        assertEquals(getWifiMeteredStatus(ssid), metered);
+    }
+
+    private String unquoteSSID(String ssid) {
+        // SSID is returned surrounded by quotes if it can be decoded as UTF-8.
+        // Otherwise it's guaranteed not to start with a quote.
+        if (ssid.charAt(0) == '"') {
+            return ssid.substring(1, ssid.length() - 1);
+        } else {
+            return ssid;
+        }
+    }
+
+    private void waitForActiveNetworkMetered(boolean requestedMeteredness) throws Exception {
+        final CountDownLatch latch = new CountDownLatch(1);
+        final NetworkCallback networkCallback = new NetworkCallback() {
+            @Override
+            public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) {
+                final boolean metered = !nc.hasCapability(NET_CAPABILITY_NOT_METERED);
+                if (metered == requestedMeteredness) {
+                    latch.countDown();
+                }
+            }
+        };
+        // Registering a callback here guarantees onCapabilitiesChanged is called immediately
+        // with the current setting. Therefore, if the setting has already been changed,
+        // this method will return right away, and if not it will wait for the setting to change.
+        mCm.registerDefaultNetworkCallback(networkCallback);
+        if (!latch.await(NETWORK_CHANGE_METEREDNESS_TIMEOUT, TimeUnit.MILLISECONDS)) {
+            fail("Timed out waiting for active network metered status to change to "
+                 + requestedMeteredness + " ; network = " + mCm.getActiveNetwork());
+        }
+        mCm.unregisterNetworkCallback(networkCallback);
+    }
+
+    private void assertMultipathPreferenceIsEventually(Network network, int oldValue,
+            int expectedValue) {
+        // Sanity check : if oldValue == expectedValue, there is no way to guarantee the test
+        // is not flaky.
+        assertNotSame(oldValue, expectedValue);
+
+        for (int i = 0; i < NUM_TRIES_MULTIPATH_PREF_CHECK; ++i) {
+            final int actualValue = mCm.getMultipathPreference(network);
+            if (actualValue == expectedValue) {
+                return;
+            }
+            if (actualValue != oldValue) {
+                fail("Multipath preference is neither previous (" + oldValue
+                        + ") nor expected (" + expectedValue + ")");
+            }
+            SystemClock.sleep(INTERVAL_MULTIPATH_PREF_CHECK_MS);
+        }
+        fail("Timed out waiting for multipath preference to change. expected = "
+                + expectedValue + " ; actual = " + mCm.getMultipathPreference(network));
+    }
+
+    private int getCurrentMeteredMultipathPreference(ContentResolver resolver) {
+        final String rawMeteredPref = Settings.Global.getString(resolver,
+                NETWORK_METERED_MULTIPATH_PREFERENCE);
+        return TextUtils.isEmpty(rawMeteredPref)
+            ? mContext.getResources().getInteger(R.integer.config_networkMeteredMultipathPreference)
+            : Integer.parseInt(rawMeteredPref);
+    }
+
+    private int findNextPrefValue(ContentResolver resolver) {
+        // A bit of a nuclear hammer, but race conditions in CTS are bad. To be able to
+        // detect a correct setting value without race conditions, the next pref must
+        // be a valid value (range 0..3) that is different from the old setting of the
+        // metered preference and from the unmetered preference.
+        final int meteredPref = getCurrentMeteredMultipathPreference(resolver);
+        final int unmeteredPref = ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED;
+        if (0 != meteredPref && 0 != unmeteredPref) return 0;
+        if (1 != meteredPref && 1 != unmeteredPref) return 1;
+        return 2;
+    }
+
+    /**
+     * Verify that getMultipathPreference does return appropriate values
+     * for metered and unmetered networks.
+     */
+    public void testGetMultipathPreference() throws Exception {
+        final ContentResolver resolver = mContext.getContentResolver();
+        final Network network = ensureWifiConnected();
+        final String ssid = unquoteSSID(mWifiManager.getConnectionInfo().getSSID());
+        final String oldMeteredSetting = getWifiMeteredStatus(ssid);
+        final String oldMeteredMultipathPreference = Settings.Global.getString(
+                resolver, NETWORK_METERED_MULTIPATH_PREFERENCE);
+        try {
+            final int initialMeteredPreference = getCurrentMeteredMultipathPreference(resolver);
+            int newMeteredPreference = findNextPrefValue(resolver);
+            Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE,
+                    Integer.toString(newMeteredPreference));
+            setWifiMeteredStatus(ssid, "true");
+            waitForActiveNetworkMetered(true);
+            assertEquals(mCm.getNetworkCapabilities(network).hasCapability(
+                    NET_CAPABILITY_NOT_METERED), false);
+            assertMultipathPreferenceIsEventually(network, initialMeteredPreference,
+                    newMeteredPreference);
+
+            final int oldMeteredPreference = newMeteredPreference;
+            newMeteredPreference = findNextPrefValue(resolver);
+            Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE,
+                    Integer.toString(newMeteredPreference));
+            assertEquals(mCm.getNetworkCapabilities(network).hasCapability(
+                    NET_CAPABILITY_NOT_METERED), false);
+            assertMultipathPreferenceIsEventually(network,
+                    oldMeteredPreference, newMeteredPreference);
+
+            setWifiMeteredStatus(ssid, "false");
+            waitForActiveNetworkMetered(false);
+            assertEquals(mCm.getNetworkCapabilities(network).hasCapability(
+                    NET_CAPABILITY_NOT_METERED), true);
+            assertMultipathPreferenceIsEventually(network, newMeteredPreference,
+                    ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED);
+        } finally {
+            Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE,
+                    oldMeteredMultipathPreference);
+            setWifiMeteredStatus(ssid, oldMeteredSetting);
+        }
+    }
 }
diff --git a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java
new file mode 100644
index 0000000..7132ecf
--- /dev/null
+++ b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java
@@ -0,0 +1,518 @@
+/*
+ * Copyright (C) 2018 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 android.content.Context;
+import android.net.IpSecAlgorithm;
+import android.net.IpSecManager;
+import android.net.IpSecTransform;
+import android.system.Os;
+import android.system.OsConstants;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class IpSecBaseTest extends AndroidTestCase {
+
+    private static final String TAG = IpSecBaseTest.class.getSimpleName();
+
+    protected static final String IPV4_LOOPBACK = "127.0.0.1";
+    protected static final String IPV6_LOOPBACK = "::1";
+    protected static final String[] LOOPBACK_ADDRS = new String[] {IPV4_LOOPBACK, IPV6_LOOPBACK};
+    protected static final int[] DIRECTIONS =
+            new int[] {IpSecManager.DIRECTION_IN, IpSecManager.DIRECTION_OUT};
+
+    protected static final byte[] TEST_DATA = "Best test data ever!".getBytes();
+    protected static final int DATA_BUFFER_LEN = 4096;
+    protected static final int SOCK_TIMEOUT = 500;
+
+    private static final byte[] KEY_DATA = {
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+        0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+        0x20, 0x21, 0x22, 0x23
+    };
+
+    protected static final byte[] AUTH_KEY = getKey(256);
+    protected static final byte[] CRYPT_KEY = getKey(256);
+
+    protected IpSecManager mISM;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        mISM = (IpSecManager) getContext().getSystemService(Context.IPSEC_SERVICE);
+    }
+
+    protected static byte[] getKey(int bitLength) {
+        return Arrays.copyOf(KEY_DATA, bitLength / 8);
+    }
+
+    protected static int getDomain(InetAddress address) {
+        int domain;
+        if (address instanceof Inet6Address) {
+            domain = OsConstants.AF_INET6;
+        } else {
+            domain = OsConstants.AF_INET;
+        }
+        return domain;
+    }
+
+    protected static int getPort(FileDescriptor sock) throws Exception {
+        return ((InetSocketAddress) Os.getsockname(sock)).getPort();
+    }
+
+    public static interface GenericSocket extends AutoCloseable {
+        void send(byte[] data) throws Exception;
+
+        byte[] receive() throws Exception;
+
+        int getPort() throws Exception;
+
+        void close() throws Exception;
+
+        void applyTransportModeTransform(
+                IpSecManager ism, int direction, IpSecTransform transform) throws Exception;
+
+        void removeTransportModeTransforms(IpSecManager ism) throws Exception;
+    }
+
+    public static interface GenericTcpSocket extends GenericSocket {}
+
+    public static interface GenericUdpSocket extends GenericSocket {
+        void sendTo(byte[] data, InetAddress dstAddr, int port) throws Exception;
+    }
+
+    public abstract static class NativeSocket implements GenericSocket {
+        public FileDescriptor mFd;
+
+        public NativeSocket(FileDescriptor fd) {
+            mFd = fd;
+        }
+
+        @Override
+        public void send(byte[] data) throws Exception {
+            Os.write(mFd, data, 0, data.length);
+        }
+
+        @Override
+        public byte[] receive() throws Exception {
+            byte[] in = new byte[DATA_BUFFER_LEN];
+            AtomicInteger bytesRead = new AtomicInteger(-1);
+
+            Thread readSockThread = new Thread(() -> {
+                long startTime = System.currentTimeMillis();
+                while (bytesRead.get() < 0 && System.currentTimeMillis() < startTime + SOCK_TIMEOUT) {
+                    try {
+                        bytesRead.set(Os.recvfrom(mFd, in, 0, DATA_BUFFER_LEN, 0, null));
+                    } catch (Exception e) {
+                        Log.e(TAG, "Error encountered reading from socket", e);
+                    }
+                }
+            });
+
+            readSockThread.start();
+            readSockThread.join(SOCK_TIMEOUT);
+
+            if (bytesRead.get() < 0) {
+                throw new IOException("No data received from socket");
+            }
+
+            return Arrays.copyOfRange(in, 0, bytesRead.get());
+        }
+
+        @Override
+        public int getPort() throws Exception {
+            return IpSecBaseTest.getPort(mFd);
+        }
+
+        @Override
+        public void close() throws Exception {
+            Os.close(mFd);
+        }
+
+        @Override
+        public void applyTransportModeTransform(
+                IpSecManager ism, int direction, IpSecTransform transform) throws Exception {
+            ism.applyTransportModeTransform(mFd, direction, transform);
+        }
+
+        @Override
+        public void removeTransportModeTransforms(IpSecManager ism) throws Exception {
+            ism.removeTransportModeTransforms(mFd);
+        }
+    }
+
+    public static class NativeTcpSocket extends NativeSocket implements GenericTcpSocket {
+        public NativeTcpSocket(FileDescriptor fd) {
+            super(fd);
+        }
+    }
+
+    public static class NativeUdpSocket extends NativeSocket implements GenericUdpSocket {
+        public NativeUdpSocket(FileDescriptor fd) {
+            super(fd);
+        }
+
+        @Override
+        public void sendTo(byte[] data, InetAddress dstAddr, int port) throws Exception {
+            Os.sendto(mFd, data, 0, data.length, 0, dstAddr, port);
+        }
+    }
+
+    public static class JavaUdpSocket implements GenericUdpSocket {
+        public final DatagramSocket mSocket;
+
+        public JavaUdpSocket(InetAddress localAddr) {
+            try {
+                mSocket = new DatagramSocket(0, localAddr);
+                mSocket.setSoTimeout(SOCK_TIMEOUT);
+            } catch (SocketException e) {
+                // Fail loudly if we can't set up sockets properly. And without the timeout, we
+                // could easily end up in an endless wait.
+                throw new RuntimeException(e);
+            }
+        }
+
+        @Override
+        public void send(byte[] data) throws Exception {
+            mSocket.send(new DatagramPacket(data, data.length));
+        }
+
+        @Override
+        public void sendTo(byte[] data, InetAddress dstAddr, int port) throws Exception {
+            mSocket.send(new DatagramPacket(data, data.length, dstAddr, port));
+        }
+
+        @Override
+        public int getPort() throws Exception {
+            return mSocket.getLocalPort();
+        }
+
+        @Override
+        public void close() throws Exception {
+            mSocket.close();
+        }
+
+        @Override
+        public byte[] receive() throws Exception {
+            DatagramPacket data = new DatagramPacket(new byte[DATA_BUFFER_LEN], DATA_BUFFER_LEN);
+            mSocket.receive(data);
+            return Arrays.copyOfRange(data.getData(), 0, data.getLength());
+        }
+
+        @Override
+        public void applyTransportModeTransform(
+                IpSecManager ism, int direction, IpSecTransform transform) throws Exception {
+            ism.applyTransportModeTransform(mSocket, direction, transform);
+        }
+
+        @Override
+        public void removeTransportModeTransforms(IpSecManager ism) throws Exception {
+            ism.removeTransportModeTransforms(mSocket);
+        }
+    }
+
+    public static class JavaTcpSocket implements GenericTcpSocket {
+        public final Socket mSocket;
+
+        public JavaTcpSocket(Socket socket) {
+            mSocket = socket;
+            try {
+                mSocket.setSoTimeout(SOCK_TIMEOUT);
+            } catch (SocketException e) {
+                // Fail loudly if we can't set up sockets properly. And without the timeout, we
+                // could easily end up in an endless wait.
+                throw new RuntimeException(e);
+            }
+        }
+
+        @Override
+        public void send(byte[] data) throws Exception {
+            mSocket.getOutputStream().write(data);
+        }
+
+        @Override
+        public byte[] receive() throws Exception {
+            byte[] in = new byte[DATA_BUFFER_LEN];
+            int bytesRead = mSocket.getInputStream().read(in);
+            return Arrays.copyOfRange(in, 0, bytesRead);
+        }
+
+        @Override
+        public int getPort() throws Exception {
+            return mSocket.getLocalPort();
+        }
+
+        @Override
+        public void close() throws Exception {
+            mSocket.close();
+        }
+
+        @Override
+        public void applyTransportModeTransform(
+                IpSecManager ism, int direction, IpSecTransform transform) throws Exception {
+            ism.applyTransportModeTransform(mSocket, direction, transform);
+        }
+
+        @Override
+        public void removeTransportModeTransforms(IpSecManager ism) throws Exception {
+            ism.removeTransportModeTransforms(mSocket);
+        }
+    }
+
+    public static class SocketPair<T> {
+        public final T mLeftSock;
+        public final T mRightSock;
+
+        public SocketPair(T leftSock, T rightSock) {
+            mLeftSock = leftSock;
+            mRightSock = rightSock;
+        }
+    }
+
+    protected static void applyTransformBidirectionally(
+            IpSecManager ism, IpSecTransform transform, GenericSocket socket) throws Exception {
+        for (int direction : DIRECTIONS) {
+            socket.applyTransportModeTransform(ism, direction, transform);
+        }
+    }
+
+    public static SocketPair<NativeUdpSocket> getNativeUdpSocketPair(
+            InetAddress localAddr, IpSecManager ism, IpSecTransform transform, boolean connected)
+            throws Exception {
+        int domain = getDomain(localAddr);
+
+        NativeUdpSocket leftSock = new NativeUdpSocket(
+            Os.socket(domain, OsConstants.SOCK_DGRAM, OsConstants.IPPROTO_UDP));
+        NativeUdpSocket rightSock = new NativeUdpSocket(
+            Os.socket(domain, OsConstants.SOCK_DGRAM, OsConstants.IPPROTO_UDP));
+
+        for (NativeUdpSocket sock : new NativeUdpSocket[] {leftSock, rightSock}) {
+            applyTransformBidirectionally(ism, transform, sock);
+            Os.bind(sock.mFd, localAddr, 0);
+        }
+
+        if (connected) {
+            Os.connect(leftSock.mFd, localAddr, rightSock.getPort());
+            Os.connect(rightSock.mFd, localAddr, leftSock.getPort());
+        }
+
+        return new SocketPair<>(leftSock, rightSock);
+    }
+
+    public static SocketPair<NativeTcpSocket> getNativeTcpSocketPair(
+            InetAddress localAddr, IpSecManager ism, IpSecTransform transform) throws Exception {
+        int domain = getDomain(localAddr);
+
+        NativeTcpSocket server = new NativeTcpSocket(
+                Os.socket(domain, OsConstants.SOCK_STREAM, OsConstants.IPPROTO_TCP));
+        NativeTcpSocket client = new NativeTcpSocket(
+                Os.socket(domain, OsConstants.SOCK_STREAM, OsConstants.IPPROTO_TCP));
+
+        Os.bind(server.mFd, localAddr, 0);
+
+        applyTransformBidirectionally(ism, transform, server);
+        applyTransformBidirectionally(ism, transform, client);
+
+        Os.listen(server.mFd, 10);
+        Os.connect(client.mFd, localAddr, server.getPort());
+        NativeTcpSocket accepted = new NativeTcpSocket(Os.accept(server.mFd, null));
+
+        applyTransformBidirectionally(ism, transform, accepted);
+        server.close();
+
+        return new SocketPair<>(client, accepted);
+    }
+
+    public static SocketPair<JavaUdpSocket> getJavaUdpSocketPair(
+            InetAddress localAddr, IpSecManager ism, IpSecTransform transform, boolean connected)
+            throws Exception {
+        JavaUdpSocket leftSock = new JavaUdpSocket(localAddr);
+        JavaUdpSocket rightSock = new JavaUdpSocket(localAddr);
+
+        applyTransformBidirectionally(ism, transform, leftSock);
+        applyTransformBidirectionally(ism, transform, rightSock);
+
+        if (connected) {
+            leftSock.mSocket.connect(localAddr, rightSock.mSocket.getLocalPort());
+            rightSock.mSocket.connect(localAddr, leftSock.mSocket.getLocalPort());
+        }
+
+        return new SocketPair<>(leftSock, rightSock);
+    }
+
+    public static SocketPair<JavaTcpSocket> getJavaTcpSocketPair(
+            InetAddress localAddr, IpSecManager ism, IpSecTransform transform) throws Exception {
+        JavaTcpSocket clientSock = new JavaTcpSocket(new Socket());
+        ServerSocket serverSocket = new ServerSocket();
+        serverSocket.bind(new InetSocketAddress(localAddr, 0));
+
+        // While technically the client socket does not need to be bound, the OpenJDK implementation
+        // of Socket only allocates an FD when bind() or connect() or other similar methods are
+        // called. So we call bind to force the FD creation, so that we can apply a transform to it
+        // prior to socket connect.
+        clientSock.mSocket.bind(new InetSocketAddress(localAddr, 0));
+
+        // IpSecService doesn't support serverSockets at the moment; workaround using FD
+        FileDescriptor serverFd = serverSocket.getImpl().getFD$();
+
+        applyTransformBidirectionally(ism, transform, new NativeTcpSocket(serverFd));
+        applyTransformBidirectionally(ism, transform, clientSock);
+
+        clientSock.mSocket.connect(new InetSocketAddress(localAddr, serverSocket.getLocalPort()));
+        JavaTcpSocket acceptedSock = new JavaTcpSocket(serverSocket.accept());
+
+        applyTransformBidirectionally(ism, transform, acceptedSock);
+        serverSocket.close();
+
+        return new SocketPair<>(clientSock, acceptedSock);
+    }
+
+    private void checkSocketPair(GenericSocket left, GenericSocket right) throws Exception {
+        left.send(TEST_DATA);
+        assertArrayEquals(TEST_DATA, right.receive());
+
+        right.send(TEST_DATA);
+        assertArrayEquals(TEST_DATA, left.receive());
+
+        left.close();
+        right.close();
+    }
+
+    private void checkUnconnectedUdpSocketPair(
+            GenericUdpSocket left, GenericUdpSocket right, InetAddress localAddr) throws Exception {
+        left.sendTo(TEST_DATA, localAddr, right.getPort());
+        assertArrayEquals(TEST_DATA, right.receive());
+
+        right.sendTo(TEST_DATA, localAddr, left.getPort());
+        assertArrayEquals(TEST_DATA, left.receive());
+
+        left.close();
+        right.close();
+    }
+
+    protected static IpSecTransform buildIpSecTransform(
+            Context mContext,
+            IpSecManager.SecurityParameterIndex spi,
+            IpSecManager.UdpEncapsulationSocket encapSocket,
+            InetAddress remoteAddr)
+            throws Exception {
+        String localAddr = (remoteAddr instanceof Inet4Address) ? IPV4_LOOPBACK : IPV6_LOOPBACK;
+        IpSecTransform.Builder builder =
+                new IpSecTransform.Builder(mContext)
+                .setEncryption(new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY))
+                .setAuthentication(
+                        new IpSecAlgorithm(
+                                IpSecAlgorithm.AUTH_HMAC_SHA256,
+                                AUTH_KEY,
+                                AUTH_KEY.length * 4));
+
+        if (encapSocket != null) {
+            builder.setIpv4Encapsulation(encapSocket, encapSocket.getPort());
+        }
+
+        return builder.buildTransportModeTransform(InetAddress.getByName(localAddr), spi);
+    }
+
+    private IpSecTransform buildDefaultTransform(InetAddress localAddr) throws Exception {
+        try (IpSecManager.SecurityParameterIndex spi =
+                mISM.allocateSecurityParameterIndex(localAddr)) {
+            return buildIpSecTransform(mContext, spi, null, localAddr);
+        }
+    }
+
+    public void testJavaTcpSocketPair() throws Exception {
+        for (String addr : LOOPBACK_ADDRS) {
+            InetAddress local = InetAddress.getByName(addr);
+            try (IpSecTransform transform = buildDefaultTransform(local)) {
+                SocketPair<JavaTcpSocket> sockets = getJavaTcpSocketPair(local, mISM, transform);
+                checkSocketPair(sockets.mLeftSock, sockets.mRightSock);
+            }
+        }
+    }
+
+    public void testJavaUdpSocketPair() throws Exception {
+        for (String addr : LOOPBACK_ADDRS) {
+            InetAddress local = InetAddress.getByName(addr);
+            try (IpSecTransform transform = buildDefaultTransform(local)) {
+                SocketPair<JavaUdpSocket> sockets =
+                        getJavaUdpSocketPair(local, mISM, transform, true);
+                checkSocketPair(sockets.mLeftSock, sockets.mRightSock);
+            }
+        }
+    }
+
+    public void testJavaUdpSocketPairUnconnected() throws Exception {
+        for (String addr : LOOPBACK_ADDRS) {
+            InetAddress local = InetAddress.getByName(addr);
+            try (IpSecTransform transform = buildDefaultTransform(local)) {
+                SocketPair<JavaUdpSocket> sockets =
+                        getJavaUdpSocketPair(local, mISM, transform, false);
+                checkUnconnectedUdpSocketPair(sockets.mLeftSock, sockets.mRightSock, local);
+            }
+        }
+    }
+
+    public void testNativeTcpSocketPair() throws Exception {
+        for (String addr : LOOPBACK_ADDRS) {
+            InetAddress local = InetAddress.getByName(addr);
+            try (IpSecTransform transform = buildDefaultTransform(local)) {
+                SocketPair<NativeTcpSocket> sockets =
+                        getNativeTcpSocketPair(local, mISM, transform);
+                checkSocketPair(sockets.mLeftSock, sockets.mRightSock);
+            }
+        }
+    }
+
+    public void testNativeUdpSocketPair() throws Exception {
+        for (String addr : LOOPBACK_ADDRS) {
+            InetAddress local = InetAddress.getByName(addr);
+            try (IpSecTransform transform = buildDefaultTransform(local)) {
+                SocketPair<NativeUdpSocket> sockets =
+                        getNativeUdpSocketPair(local, mISM, transform, true);
+                checkSocketPair(sockets.mLeftSock, sockets.mRightSock);
+            }
+        }
+    }
+
+    public void testNativeUdpSocketPairUnconnected() throws Exception {
+        for (String addr : LOOPBACK_ADDRS) {
+            InetAddress local = InetAddress.getByName(addr);
+            try (IpSecTransform transform = buildDefaultTransform(local)) {
+                SocketPair<NativeUdpSocket> sockets =
+                        getNativeUdpSocketPair(local, mISM, transform, false);
+                checkUnconnectedUdpSocketPair(sockets.mLeftSock, sockets.mRightSock, local);
+            }
+        }
+    }
+}
diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java
new file mode 100644
index 0000000..95d91a2
--- /dev/null
+++ b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java
@@ -0,0 +1,1133 @@
+/*
+ * Copyright (C) 2017 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.system.OsConstants.IPPROTO_TCP;
+import static android.system.OsConstants.IPPROTO_UDP;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.IpSecAlgorithm;
+import android.net.IpSecManager;
+import android.net.IpSecTransform;
+import android.net.TrafficStats;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+
+public class IpSecManagerTest extends IpSecBaseTest {
+
+    private static final String TAG = IpSecManagerTest.class.getSimpleName();
+
+    private ConnectivityManager mCM;
+
+    private static InetAddress IpAddress(String addrString) {
+        try {
+            return InetAddress.getByName(addrString);
+        } catch (UnknownHostException e) {
+            throw new IllegalArgumentException("Invalid IP address: " + e);
+        }
+    }
+
+    private static final InetAddress GOOGLE_DNS_4 = IpAddress("8.8.8.8");
+    private static final InetAddress GOOGLE_DNS_6 = IpAddress("2001:4860:4860::8888");
+
+    private static final InetAddress[] GOOGLE_DNS_LIST =
+            new InetAddress[] {GOOGLE_DNS_4, GOOGLE_DNS_6};
+
+    private static final int DROID_SPI = 0xD1201D;
+    private static final int MAX_PORT_BIND_ATTEMPTS = 10;
+
+    private static final byte[] AEAD_KEY = getKey(288);
+
+    private static final int TCP_HDRLEN_WITH_OPTIONS = 32;
+    private static final int UDP_HDRLEN = 8;
+    private static final int IP4_HDRLEN = 20;
+    private static final int IP6_HDRLEN = 40;
+
+    // Encryption parameters
+    private static final int AES_GCM_IV_LEN = 8;
+    private static final int AES_CBC_IV_LEN = 16;
+    private static final int AES_GCM_BLK_SIZE = 4;
+    private static final int AES_CBC_BLK_SIZE = 16;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+    }
+
+    /*
+     * Allocate a random SPI
+     * Allocate a specific SPI using previous randomly created SPI value
+     * Realloc the same SPI that was specifically created (expect SpiUnavailable)
+     * Close SPIs
+     */
+    public void testAllocSpi() throws Exception {
+        for (InetAddress addr : GOOGLE_DNS_LIST) {
+            IpSecManager.SecurityParameterIndex randomSpi = null, droidSpi = null;
+            randomSpi = mISM.allocateSecurityParameterIndex(addr);
+            assertTrue(
+                    "Failed to receive a valid SPI",
+                    randomSpi.getSpi() != IpSecManager.INVALID_SECURITY_PARAMETER_INDEX);
+
+            droidSpi = mISM.allocateSecurityParameterIndex(addr, DROID_SPI);
+            assertTrue("Failed to allocate specified SPI, " + DROID_SPI,
+                    droidSpi.getSpi() == DROID_SPI);
+
+            try {
+                mISM.allocateSecurityParameterIndex(addr, DROID_SPI);
+                fail("Duplicate SPI was allowed to be created");
+            } catch (IpSecManager.SpiUnavailableException expected) {
+                // This is a success case because we expect a dupe SPI to throw
+            }
+
+            randomSpi.close();
+            droidSpi.close();
+        }
+    }
+
+    /** This function finds an available port */
+    private static int findUnusedPort() throws Exception {
+        // Get an available port.
+        DatagramSocket s = new DatagramSocket();
+        int port = s.getLocalPort();
+        s.close();
+        return port;
+    }
+
+    private static FileDescriptor getBoundUdpSocket(InetAddress address) throws Exception {
+        FileDescriptor sock =
+                Os.socket(getDomain(address), OsConstants.SOCK_DGRAM, OsConstants.IPPROTO_UDP);
+
+        for (int i = 0; i < MAX_PORT_BIND_ATTEMPTS; i++) {
+            try {
+                int port = findUnusedPort();
+                Os.bind(sock, address, port);
+                break;
+            } catch (ErrnoException e) {
+                // Someone claimed the port since we called findUnusedPort.
+                if (e.errno == OsConstants.EADDRINUSE) {
+                    if (i == MAX_PORT_BIND_ATTEMPTS - 1) {
+
+                        fail("Failed " + MAX_PORT_BIND_ATTEMPTS + " attempts to bind to a port");
+                    }
+                    continue;
+                }
+                throw e.rethrowAsIOException();
+            }
+        }
+        return sock;
+    }
+
+    private void checkUnconnectedUdp(IpSecTransform transform, InetAddress local, int sendCount,
+                                     boolean useJavaSockets) throws Exception {
+        GenericUdpSocket sockLeft = null, sockRight = null;
+        if (useJavaSockets) {
+            SocketPair<JavaUdpSocket> sockets = getJavaUdpSocketPair(local, mISM, transform, false);
+            sockLeft = sockets.mLeftSock;
+            sockRight = sockets.mRightSock;
+        } else {
+            SocketPair<NativeUdpSocket> sockets =
+                    getNativeUdpSocketPair(local, mISM, transform, false);
+            sockLeft = sockets.mLeftSock;
+            sockRight = sockets.mRightSock;
+        }
+
+        for (int i = 0; i < sendCount; i++) {
+            byte[] in;
+
+            sockLeft.sendTo(TEST_DATA, local, sockRight.getPort());
+            in = sockRight.receive();
+            assertArrayEquals("Left-to-right encrypted data did not match.", TEST_DATA, in);
+
+            sockRight.sendTo(TEST_DATA, local, sockLeft.getPort());
+            in = sockLeft.receive();
+            assertArrayEquals("Right-to-left encrypted data did not match.", TEST_DATA, in);
+        }
+
+        sockLeft.close();
+        sockRight.close();
+    }
+
+    private void checkTcp(IpSecTransform transform, InetAddress local, int sendCount,
+                          boolean useJavaSockets) throws Exception {
+        GenericTcpSocket client = null, accepted = null;
+        if (useJavaSockets) {
+            SocketPair<JavaTcpSocket> sockets = getJavaTcpSocketPair(local, mISM, transform);
+            client = sockets.mLeftSock;
+            accepted = sockets.mRightSock;
+        } else {
+            SocketPair<NativeTcpSocket> sockets = getNativeTcpSocketPair(local, mISM, transform);
+            client = sockets.mLeftSock;
+            accepted = sockets.mRightSock;
+        }
+
+        // Wait for TCP handshake packets to be counted
+        StatsChecker.waitForNumPackets(3); // (SYN, SYN+ACK, ACK)
+
+        // Reset StatsChecker, to ignore negotiation overhead.
+        StatsChecker.initStatsChecker();
+        for (int i = 0; i < sendCount; i++) {
+            byte[] in;
+
+            client.send(TEST_DATA);
+            in = accepted.receive();
+            assertArrayEquals("Client-to-server encrypted data did not match.", TEST_DATA, in);
+
+            // Allow for newest data + ack packets to be returned before sending next packet
+            // Also add the number of expected packets in each of the previous runs (4 per run)
+            StatsChecker.waitForNumPackets(2 + (4 * i));
+
+            accepted.send(TEST_DATA);
+            in = client.receive();
+            assertArrayEquals("Server-to-client encrypted data did not match.", TEST_DATA, in);
+
+            // Allow for all data + ack packets to be returned before sending next packet
+            // Also add the number of expected packets in each of the previous runs (4 per run)
+            StatsChecker.waitForNumPackets(4 * (i + 1));
+        }
+
+        // Transforms should not be removed from the sockets, otherwise FIN packets will be sent
+        //     unencrypted.
+        // This test also unfortunately happens to rely on a nuance of the cleanup order. By
+        //     keeping the policy on the socket, but removing the SA before lingering FIN packets
+        //     are sent (at an undetermined later time), the FIN packets are dropped. Without this,
+        //     we run into all kinds of headaches trying to test data accounting (unsolicited
+        //     packets mysteriously appearing and messing up our counters)
+        // The right way to close sockets is to set SO_LINGER to ensure synchronous closure,
+        //     closing the sockets, and then closing the transforms. See documentation for the
+        //     Socket or FileDescriptor flavors of applyTransportModeTransform() in IpSecManager
+        //     for more details.
+
+        client.close();
+        accepted.close();
+    }
+
+    /*
+     * Alloc outbound SPI
+     * Alloc inbound SPI
+     * Create transport mode transform
+     * open socket
+     * apply transform to socket
+     * send data on socket
+     * release transform
+     * send data (expect exception)
+     */
+    public void testCreateTransform() throws Exception {
+        InetAddress localAddr = InetAddress.getByName(IPV4_LOOPBACK);
+        IpSecManager.SecurityParameterIndex spi =
+                mISM.allocateSecurityParameterIndex(localAddr);
+
+        IpSecTransform transform =
+                new IpSecTransform.Builder(mContext)
+                        .setEncryption(new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY))
+                        .setAuthentication(
+                                new IpSecAlgorithm(
+                                        IpSecAlgorithm.AUTH_HMAC_SHA256,
+                                        AUTH_KEY,
+                                        AUTH_KEY.length * 8))
+                        .buildTransportModeTransform(localAddr, spi);
+
+        final boolean [][] applyInApplyOut = {
+                {false, false}, {false, true}, {true, false}, {true,true}};
+        final byte[] data = new String("Best test data ever!").getBytes("UTF-8");
+        final DatagramPacket outPacket = new DatagramPacket(data, 0, data.length, localAddr, 0);
+
+        byte[] in = new byte[data.length];
+        DatagramPacket inPacket = new DatagramPacket(in, in.length);
+        DatagramSocket localSocket;
+        int localPort;
+
+        for(boolean[] io : applyInApplyOut) {
+            boolean applyIn = io[0];
+            boolean applyOut = io[1];
+            // Bind localSocket to a random available port.
+            localSocket = new DatagramSocket(0);
+            localPort = localSocket.getLocalPort();
+            localSocket.setSoTimeout(200);
+            outPacket.setPort(localPort);
+            if (applyIn) {
+                mISM.applyTransportModeTransform(
+                        localSocket, IpSecManager.DIRECTION_IN, transform);
+            }
+            if (applyOut) {
+                mISM.applyTransportModeTransform(
+                        localSocket, IpSecManager.DIRECTION_OUT, transform);
+            }
+            if (applyIn == applyOut) {
+                localSocket.send(outPacket);
+                localSocket.receive(inPacket);
+                assertTrue("Encapsulated data did not match.",
+                        Arrays.equals(outPacket.getData(), inPacket.getData()));
+                mISM.removeTransportModeTransforms(localSocket);
+                localSocket.close();
+            } else {
+                try {
+                    localSocket.send(outPacket);
+                    localSocket.receive(inPacket);
+                } catch (IOException e) {
+                    continue;
+                } finally {
+                    mISM.removeTransportModeTransforms(localSocket);
+                    localSocket.close();
+                }
+                // FIXME: This check is disabled because sockets currently receive data
+                // if there is a valid SA for decryption, even when the input policy is
+                // not applied to a socket.
+                //  fail("Data IO should fail on asymmetrical transforms! + Input="
+                //          + applyIn + " Output=" + applyOut);
+            }
+        }
+        transform.close();
+    }
+
+    /** Snapshot of TrafficStats as of initStatsChecker call for later comparisons */
+    private static class StatsChecker {
+        private static final double ERROR_MARGIN_BYTES = 1.05;
+        private static final double ERROR_MARGIN_PKTS = 1.05;
+        private static final int MAX_WAIT_TIME_MILLIS = 1000;
+
+        private static long uidTxBytes;
+        private static long uidRxBytes;
+        private static long uidTxPackets;
+        private static long uidRxPackets;
+
+        private static long ifaceTxBytes;
+        private static long ifaceRxBytes;
+        private static long ifaceTxPackets;
+        private static long ifaceRxPackets;
+
+        /**
+         * This method counts the number of incoming packets, polling intermittently up to
+         * MAX_WAIT_TIME_MILLIS.
+         */
+        private static void waitForNumPackets(int numPackets) throws Exception {
+            long uidTxDelta = 0;
+            long uidRxDelta = 0;
+            for (int i = 0; i < 100; i++) {
+                uidTxDelta = TrafficStats.getUidTxPackets(Os.getuid()) - uidTxPackets;
+                uidRxDelta = TrafficStats.getUidRxPackets(Os.getuid()) - uidRxPackets;
+
+                // TODO: Check Rx packets as well once kernel security policy bug is fixed.
+                // (b/70635417)
+                if (uidTxDelta >= numPackets) {
+                    return;
+                }
+                Thread.sleep(MAX_WAIT_TIME_MILLIS / 100);
+            }
+            fail(
+                    "Not enough traffic was recorded to satisfy the provided conditions: wanted "
+                            + numPackets
+                            + ", got "
+                            + uidTxDelta
+                            + " tx and "
+                            + uidRxDelta
+                            + " rx packets");
+        }
+
+        private static void assertUidStatsDelta(
+                int expectedTxByteDelta,
+                int expectedTxPacketDelta,
+                int expectedRxByteDelta,
+                int expectedRxPacketDelta) {
+            long newUidTxBytes = TrafficStats.getUidTxBytes(Os.getuid());
+            long newUidRxBytes = TrafficStats.getUidRxBytes(Os.getuid());
+            long newUidTxPackets = TrafficStats.getUidTxPackets(Os.getuid());
+            long newUidRxPackets = TrafficStats.getUidRxPackets(Os.getuid());
+
+            assertEquals(expectedTxByteDelta, newUidTxBytes - uidTxBytes);
+            assertEquals(expectedRxByteDelta, newUidRxBytes - uidRxBytes);
+            assertEquals(expectedTxPacketDelta, newUidTxPackets - uidTxPackets);
+            assertEquals(expectedRxPacketDelta, newUidRxPackets - uidRxPackets);
+        }
+
+        private static void assertIfaceStatsDelta(
+                int expectedTxByteDelta,
+                int expectedTxPacketDelta,
+                int expectedRxByteDelta,
+                int expectedRxPacketDelta)
+                throws IOException {
+            long newIfaceTxBytes = TrafficStats.getLoopbackTxBytes();
+            long newIfaceRxBytes = TrafficStats.getLoopbackRxBytes();
+            long newIfaceTxPackets = TrafficStats.getLoopbackTxPackets();
+            long newIfaceRxPackets = TrafficStats.getLoopbackRxPackets();
+
+            // Check that iface stats are within an acceptable range; data might be sent
+            // on the local interface by other apps.
+            assertApproxEquals(
+                    ifaceTxBytes, newIfaceTxBytes, expectedTxByteDelta, ERROR_MARGIN_BYTES);
+            assertApproxEquals(
+                    ifaceRxBytes, newIfaceRxBytes, expectedRxByteDelta, ERROR_MARGIN_BYTES);
+            assertApproxEquals(
+                    ifaceTxPackets, newIfaceTxPackets, expectedTxPacketDelta, ERROR_MARGIN_PKTS);
+            assertApproxEquals(
+                    ifaceRxPackets, newIfaceRxPackets, expectedRxPacketDelta, ERROR_MARGIN_PKTS);
+        }
+
+        private static void assertApproxEquals(
+                long oldStats, long newStats, int expectedDelta, double errorMargin) {
+            assertTrue(expectedDelta <= newStats - oldStats);
+            assertTrue((expectedDelta * errorMargin) > newStats - oldStats);
+        }
+
+        private static void initStatsChecker() throws Exception {
+            uidTxBytes = TrafficStats.getUidTxBytes(Os.getuid());
+            uidRxBytes = TrafficStats.getUidRxBytes(Os.getuid());
+            uidTxPackets = TrafficStats.getUidTxPackets(Os.getuid());
+            uidRxPackets = TrafficStats.getUidRxPackets(Os.getuid());
+
+            ifaceTxBytes = TrafficStats.getLoopbackTxBytes();
+            ifaceRxBytes = TrafficStats.getLoopbackRxBytes();
+            ifaceTxPackets = TrafficStats.getLoopbackTxPackets();
+            ifaceRxPackets = TrafficStats.getLoopbackRxPackets();
+        }
+    }
+
+    private int getTruncLenBits(IpSecAlgorithm authOrAead) {
+        return authOrAead == null ? 0 : authOrAead.getTruncationLengthBits();
+    }
+
+    private int getIvLen(IpSecAlgorithm cryptOrAead) {
+        if (cryptOrAead == null) { return 0; }
+
+        switch (cryptOrAead.getName()) {
+            case IpSecAlgorithm.CRYPT_AES_CBC:
+                return AES_CBC_IV_LEN;
+            case IpSecAlgorithm.AUTH_CRYPT_AES_GCM:
+                return AES_GCM_IV_LEN;
+            default:
+                throw new IllegalArgumentException(
+                        "IV length unknown for algorithm" + cryptOrAead.getName());
+        }
+    }
+
+    private int getBlkSize(IpSecAlgorithm cryptOrAead) {
+        // RFC 4303, section 2.4 states that ciphertext plus pad_len, next_header fields must
+        //     terminate on a 4-byte boundary. Thus, the minimum ciphertext block size is 4 bytes.
+        if (cryptOrAead == null) { return 4; }
+
+        switch (cryptOrAead.getName()) {
+            case IpSecAlgorithm.CRYPT_AES_CBC:
+                return AES_CBC_BLK_SIZE;
+            case IpSecAlgorithm.AUTH_CRYPT_AES_GCM:
+                return AES_GCM_BLK_SIZE;
+            default:
+                throw new IllegalArgumentException(
+                        "Blk size unknown for algorithm" + cryptOrAead.getName());
+        }
+    }
+
+    /** Helper function to calculate expected ESP packet size. */
+    private 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
+        payloadLen += 2; // ESP trailer
+
+        // Align to block size of encryption algorithm
+        payloadLen += (cryptBlockSize - (payloadLen % cryptBlockSize)) % cryptBlockSize;
+        return payloadLen + ESP_HDRLEN + ICV_LEN;
+    }
+
+    public void checkTransform(
+            int protocol,
+            String localAddress,
+            IpSecAlgorithm crypt,
+            IpSecAlgorithm auth,
+            IpSecAlgorithm aead,
+            boolean doUdpEncap,
+            int sendCount,
+            boolean useJavaSockets)
+            throws Exception {
+        StatsChecker.initStatsChecker();
+        InetAddress local = InetAddress.getByName(localAddress);
+
+        try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket();
+                IpSecManager.SecurityParameterIndex spi =
+                        mISM.allocateSecurityParameterIndex(local)) {
+
+            IpSecTransform.Builder transformBuilder = new IpSecTransform.Builder(mContext);
+            if (crypt != null) {
+                transformBuilder.setEncryption(crypt);
+            }
+            if (auth != null) {
+                transformBuilder.setAuthentication(auth);
+            }
+            if (aead != null) {
+                transformBuilder.setAuthenticatedEncryption(aead);
+            }
+
+            if (doUdpEncap) {
+                transformBuilder =
+                        transformBuilder.setIpv4Encapsulation(encapSocket, encapSocket.getPort());
+            }
+
+            int ipHdrLen = local instanceof Inet6Address ? IP6_HDRLEN : IP4_HDRLEN;
+            int transportHdrLen = 0;
+            int udpEncapLen = doUdpEncap ? UDP_HDRLEN : 0;
+
+            try (IpSecTransform transform =
+                        transformBuilder.buildTransportModeTransform(local, spi)) {
+                if (protocol == IPPROTO_TCP) {
+                    transportHdrLen = TCP_HDRLEN_WITH_OPTIONS;
+                    checkTcp(transform, local, sendCount, useJavaSockets);
+                } else if (protocol == IPPROTO_UDP) {
+                    transportHdrLen = UDP_HDRLEN;
+
+                    // TODO: Also check connected udp.
+                    checkUnconnectedUdp(transform, local, sendCount, useJavaSockets);
+                } else {
+                    throw new IllegalArgumentException("Invalid protocol");
+                }
+            }
+
+            checkStatsChecker(
+                    protocol,
+                    ipHdrLen,
+                    transportHdrLen,
+                    udpEncapLen,
+                    sendCount,
+                    getIvLen(crypt != null ? crypt : aead),
+                    getBlkSize(crypt != null ? crypt : aead),
+                    getTruncLenBits(auth != null ? auth : aead));
+        }
+    }
+
+    private void checkStatsChecker(
+            int protocol,
+            int ipHdrLen,
+            int transportHdrLen,
+            int udpEncapLen,
+            int sendCount,
+            int ivLen,
+            int blkSize,
+            int truncLenBits)
+            throws Exception {
+
+        int innerPacketSize = TEST_DATA.length + transportHdrLen + ipHdrLen;
+        int outerPacketSize =
+                calculateEspPacketSize(
+                                TEST_DATA.length + transportHdrLen, ivLen, blkSize, truncLenBits)
+                        + udpEncapLen
+                        + ipHdrLen;
+
+        int expectedOuterBytes = outerPacketSize * sendCount;
+        int expectedInnerBytes = innerPacketSize * sendCount;
+        int expectedPackets = sendCount;
+
+        // Each run sends two packets, one in each direction.
+        sendCount *= 2;
+        expectedOuterBytes *= 2;
+        expectedInnerBytes *= 2;
+        expectedPackets *= 2;
+
+        // Add TCP ACKs for data packets
+        if (protocol == IPPROTO_TCP) {
+            int encryptedTcpPktSize =
+                    calculateEspPacketSize(TCP_HDRLEN_WITH_OPTIONS, ivLen, blkSize, truncLenBits);
+
+
+                // Add data packet ACKs
+                expectedOuterBytes += (encryptedTcpPktSize + udpEncapLen + ipHdrLen) * (sendCount);
+                expectedInnerBytes += (TCP_HDRLEN_WITH_OPTIONS + ipHdrLen) * (sendCount);
+                expectedPackets += sendCount;
+        }
+
+        StatsChecker.waitForNumPackets(expectedPackets);
+
+        if (udpEncapLen != 0) {
+            StatsChecker.assertUidStatsDelta(
+                    expectedOuterBytes, expectedPackets, expectedOuterBytes, expectedPackets);
+        } else {
+            StatsChecker.assertUidStatsDelta(
+                    expectedOuterBytes, expectedPackets, expectedInnerBytes, expectedPackets);
+        }
+
+        // Unreliable at low numbers due to potential interference from other processes.
+        if (sendCount >= 1000) {
+            StatsChecker.assertIfaceStatsDelta(
+                    expectedOuterBytes, expectedPackets, expectedOuterBytes, expectedPackets);
+        }
+    }
+
+    private void checkIkePacket(
+            NativeUdpSocket wrappedEncapSocket, InetAddress localAddr) throws Exception {
+        StatsChecker.initStatsChecker();
+
+        try (NativeUdpSocket remoteSocket = new NativeUdpSocket(getBoundUdpSocket(localAddr))) {
+
+            // Append IKE/ESP header - 4 bytes of SPI, 4 bytes of seq number, all zeroed out
+            // If the first four bytes are zero, assume non-ESP (IKE traffic)
+            byte[] dataWithEspHeader = new byte[TEST_DATA.length + 8];
+            System.arraycopy(TEST_DATA, 0, dataWithEspHeader, 8, TEST_DATA.length);
+
+            // Send the IKE packet from remoteSocket to wrappedEncapSocket. Since IKE packets
+            // are multiplexed over the socket, we expect them to appear on the encap socket
+            // (as opposed to being decrypted and received on the non-encap socket)
+            remoteSocket.sendTo(dataWithEspHeader, localAddr, wrappedEncapSocket.getPort());
+            byte[] in = wrappedEncapSocket.receive();
+            assertArrayEquals("Encapsulated data did not match.", dataWithEspHeader, in);
+
+            // Also test that the IKE socket can send data out.
+            wrappedEncapSocket.sendTo(dataWithEspHeader, localAddr, remoteSocket.getPort());
+            in = remoteSocket.receive();
+            assertArrayEquals("Encapsulated data did not match.", dataWithEspHeader, in);
+
+            // Calculate expected packet sizes. Always use IPv4 header, since our kernels only
+            // guarantee support of UDP encap on IPv4.
+            int expectedNumPkts = 2;
+            int expectedPacketSize =
+                    expectedNumPkts * (dataWithEspHeader.length + UDP_HDRLEN + IP4_HDRLEN);
+
+            StatsChecker.waitForNumPackets(expectedNumPkts);
+            StatsChecker.assertUidStatsDelta(
+                    expectedPacketSize, expectedNumPkts, expectedPacketSize, expectedNumPkts);
+            StatsChecker.assertIfaceStatsDelta(
+                    expectedPacketSize, expectedNumPkts, expectedPacketSize, expectedNumPkts);
+        }
+    }
+
+    public void testIkeOverUdpEncapSocket() throws Exception {
+        // IPv6 not supported for UDP-encap-ESP
+        InetAddress local = InetAddress.getByName(IPV4_LOOPBACK);
+        try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) {
+            NativeUdpSocket wrappedEncapSocket =
+                    new NativeUdpSocket(encapSocket.getFileDescriptor());
+            checkIkePacket(wrappedEncapSocket, local);
+
+            // Now try with a transform applied to a socket using this Encap socket
+            IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+            IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+
+            try (IpSecManager.SecurityParameterIndex spi =
+                            mISM.allocateSecurityParameterIndex(local);
+                    IpSecTransform transform =
+                            new IpSecTransform.Builder(mContext)
+                                    .setEncryption(crypt)
+                                    .setAuthentication(auth)
+                                    .setIpv4Encapsulation(encapSocket, encapSocket.getPort())
+                                    .buildTransportModeTransform(local, spi);
+                    JavaUdpSocket localSocket = new JavaUdpSocket(local)) {
+                applyTransformBidirectionally(mISM, transform, localSocket);
+
+                checkIkePacket(wrappedEncapSocket, local);
+            }
+        }
+    }
+
+    // TODO: Check IKE over ESP sockets (IPv4, IPv6) - does this need SOCK_RAW?
+
+    /* TODO: Re-enable these when policy matcher works for reflected packets
+     *
+     * The issue here is that A sends to B, and everything is new; therefore PREROUTING counts
+     * correctly. But it appears that the security path is not cleared afterwards, thus when A
+     * sends an ACK back to B, the policy matcher flags it as a "IPSec" packet. See b/70635417
+     */
+
+    // public void testInterfaceCountersTcp4() throws Exception {
+    //     IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+    //     IpSecAlgorithm auth = new IpSecAlgorithm(
+    //             IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+    //     checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, false, 1000);
+    // }
+
+    // public void testInterfaceCountersTcp6() throws Exception {
+    //     IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+    //     IpSecAlgorithm auth = new IpSecAlgorithm(
+    //             IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+    //     checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, false, 1000);
+    // }
+
+    // public void testInterfaceCountersTcp4UdpEncap() throws Exception {
+    //     IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+    //     IpSecAlgorithm auth =
+    //             new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+    //     checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, true, 1000);
+    // }
+
+    public void testInterfaceCountersUdp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1000, false);
+    }
+
+    public void testInterfaceCountersUdp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1000, false);
+    }
+
+    public void testInterfaceCountersUdp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1000, false);
+    }
+
+    public void testAesCbcHmacMd5Tcp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    public void testAesCbcHmacMd5Tcp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    public void testAesCbcHmacMd5Udp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    public void testAesCbcHmacMd5Udp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha1Tcp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha1Tcp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha1Udp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha1Udp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha256Tcp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha256Tcp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha256Udp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha256Udp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha384Tcp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha384Tcp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha384Udp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha384Udp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha512Tcp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha512Tcp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha512Udp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    public void testAesCbcHmacSha512Udp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
+    }
+
+    public void testAesGcm64Tcp4() throws Exception {
+        IpSecAlgorithm authCrypt =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true);
+    }
+
+    public void testAesGcm64Tcp6() throws Exception {
+        IpSecAlgorithm authCrypt =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true);
+    }
+
+    public void testAesGcm64Udp4() throws Exception {
+        IpSecAlgorithm authCrypt =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true);
+    }
+
+    public void testAesGcm64Udp6() throws Exception {
+        IpSecAlgorithm authCrypt =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true);
+    }
+
+    public void testAesGcm96Tcp4() throws Exception {
+        IpSecAlgorithm authCrypt =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true);
+    }
+
+    public void testAesGcm96Tcp6() throws Exception {
+        IpSecAlgorithm authCrypt =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true);
+    }
+
+    public void testAesGcm96Udp4() throws Exception {
+        IpSecAlgorithm authCrypt =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true);
+    }
+
+    public void testAesGcm96Udp6() throws Exception {
+        IpSecAlgorithm authCrypt =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true);
+    }
+
+    public void testAesGcm128Tcp4() throws Exception {
+        IpSecAlgorithm authCrypt =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true);
+    }
+
+    public void testAesGcm128Tcp6() throws Exception {
+        IpSecAlgorithm authCrypt =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true);
+    }
+
+    public void testAesGcm128Udp4() throws Exception {
+        IpSecAlgorithm authCrypt =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true);
+    }
+
+    public void testAesGcm128Udp6() throws Exception {
+        IpSecAlgorithm authCrypt =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true);
+    }
+
+    public void testAesCbcHmacMd5Tcp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
+    }
+
+    public void testAesCbcHmacMd5Udp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
+    }
+
+    public void testAesCbcHmacSha1Tcp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
+    }
+
+    public void testAesCbcHmacSha1Udp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
+    }
+
+    public void testAesCbcHmacSha256Tcp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
+    }
+
+    public void testAesCbcHmacSha256Udp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
+    }
+
+    public void testAesCbcHmacSha384Tcp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
+    }
+
+    public void testAesCbcHmacSha384Udp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
+    }
+
+    public void testAesCbcHmacSha512Tcp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
+    }
+
+    public void testAesCbcHmacSha512Udp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
+    }
+
+    public void testAesGcm64Tcp4UdpEncap() throws Exception {
+        IpSecAlgorithm authCrypt =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true);
+    }
+
+    public void testAesGcm64Udp4UdpEncap() throws Exception {
+        IpSecAlgorithm authCrypt =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true);
+    }
+
+    public void testAesGcm96Tcp4UdpEncap() throws Exception {
+        IpSecAlgorithm authCrypt =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true);
+    }
+
+    public void testAesGcm96Udp4UdpEncap() throws Exception {
+        IpSecAlgorithm authCrypt =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true);
+    }
+
+    public void testAesGcm128Tcp4UdpEncap() throws Exception {
+        IpSecAlgorithm authCrypt =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true);
+    }
+
+    public void testAesGcm128Udp4UdpEncap() throws Exception {
+        IpSecAlgorithm authCrypt =
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true);
+    }
+
+    public void testCryptUdp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, false, 1, true);
+    }
+
+    public void testAuthUdp4() throws Exception {
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, false, 1, true);
+    }
+
+    public void testCryptUdp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, null, null, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, null, null, false, 1, true);
+    }
+
+    public void testAuthUdp6() throws Exception {
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, auth, null, false, 1, false);
+        checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, auth, null, false, 1, true);
+    }
+
+    public void testCryptTcp4() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, false, 1, true);
+    }
+
+    public void testAuthTcp4() throws Exception {
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, false, 1, true);
+    }
+
+    public void testCryptTcp6() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, null, null, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, null, null, false, 1, true);
+    }
+
+    public void testAuthTcp6() throws Exception {
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, auth, null, false, 1, false);
+        checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, auth, null, false, 1, true);
+    }
+
+    public void testCryptUdp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, true, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, true, 1, true);
+    }
+
+    public void testAuthUdp4UdpEncap() throws Exception {
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, true, 1, false);
+        checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, true, 1, true);
+    }
+
+    public void testCryptTcp4UdpEncap() throws Exception {
+        IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, true, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, true, 1, true);
+    }
+
+    public void testAuthTcp4UdpEncap() throws Exception {
+        IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, true, 1, false);
+        checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, true, 1, true);
+    }
+
+    public void testOpenUdpEncapSocketSpecificPort() throws Exception {
+        IpSecManager.UdpEncapsulationSocket encapSocket = null;
+        int port = -1;
+        for (int i = 0; i < MAX_PORT_BIND_ATTEMPTS; i++) {
+            try {
+                port = findUnusedPort();
+                encapSocket = mISM.openUdpEncapsulationSocket(port);
+                break;
+            } catch (ErrnoException e) {
+                if (e.errno == OsConstants.EADDRINUSE) {
+                    // Someone claimed the port since we called findUnusedPort.
+                    continue;
+                }
+                throw e;
+            } finally {
+                if (encapSocket != null) {
+                    encapSocket.close();
+                }
+            }
+        }
+
+        if (encapSocket == null) {
+            fail("Failed " + MAX_PORT_BIND_ATTEMPTS + " attempts to bind to a port");
+        }
+
+        assertTrue("Returned invalid port", encapSocket.getPort() == port);
+    }
+
+    public void testOpenUdpEncapSocketRandomPort() throws Exception {
+        try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) {
+            assertTrue("Returned invalid port", encapSocket.getPort() != 0);
+        }
+    }
+}
diff --git a/tests/cts/net/src/android/net/cts/IpSecSysctlTest.java b/tests/cts/net/src/android/net/cts/IpSecSysctlTest.java
new file mode 100644
index 0000000..b362282
--- /dev/null
+++ b/tests/cts/net/src/android/net/cts/IpSecSysctlTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2018 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.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.system.StructStat;
+import android.test.AndroidTestCase;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.IOException;
+
+/**
+ * Tests for multinetwork sysctl functionality.
+ */
+public class IpSecSysctlTest extends SysctlBaseTest {
+
+    // SPI expiration sysctls. Must be present and set greater than 1h.
+    private static final String SPI_TIMEOUT_SYSCTL = "/proc/sys/net/core/xfrm_acq_expires";
+    private static final int MIN_ACQ_EXPIRES = 3600;
+
+    /**
+     * Checks that SPI default timeouts are overridden, and set to a reasonable length of time
+     */
+    public void testProcFiles() throws ErrnoException, IOException, NumberFormatException {
+        int value = getIntValue(SPI_TIMEOUT_SYSCTL);
+        assertAtLeast(SPI_TIMEOUT_SYSCTL, value, MIN_ACQ_EXPIRES);
+    }
+}
diff --git a/tests/cts/net/src/android/net/cts/MacAddressTest.java b/tests/cts/net/src/android/net/cts/MacAddressTest.java
new file mode 100644
index 0000000..ace1cde
--- /dev/null
+++ b/tests/cts/net/src/android/net/cts/MacAddressTest.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2018 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.net.MacAddress.TYPE_BROADCAST;
+import static android.net.MacAddress.TYPE_MULTICAST;
+import static android.net.MacAddress.TYPE_UNICAST;
+import static org.junit.Assert.fail;
+
+import android.net.MacAddress;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class MacAddressTest {
+
+    static class TestCase {
+        final String macAddress;
+        final String ouiString;
+        final int addressType;
+        final boolean isLocallyAssigned;
+
+        TestCase(String macAddress, String ouiString, int addressType, boolean isLocallyAssigned) {
+            this.macAddress = macAddress;
+            this.ouiString = ouiString;
+            this.addressType = addressType;
+            this.isLocallyAssigned = isLocallyAssigned;
+        }
+    }
+
+    static final boolean LOCALLY_ASSIGNED = true;
+    static final boolean GLOBALLY_UNIQUE = false;
+
+    static String typeToString(int addressType) {
+        switch (addressType) {
+            case TYPE_UNICAST:
+                return "TYPE_UNICAST";
+            case TYPE_BROADCAST:
+                return "TYPE_BROADCAST";
+            case TYPE_MULTICAST:
+                return "TYPE_MULTICAST";
+            default:
+                return "UNKNOWN";
+        }
+    }
+
+    static String localAssignedToString(boolean isLocallyAssigned) {
+        return isLocallyAssigned ? "LOCALLY_ASSIGNED" : "GLOBALLY_UNIQUE";
+    }
+
+    @Test
+    public void testMacAddress() {
+        TestCase[] tests = {
+            new TestCase("ff:ff:ff:ff:ff:ff", "ff:ff:ff", TYPE_BROADCAST, LOCALLY_ASSIGNED),
+            new TestCase("d2:c4:22:4d:32:a8", "d2:c4:22", TYPE_UNICAST, LOCALLY_ASSIGNED),
+            new TestCase("33:33:aa:bb:cc:dd", "33:33:aa", TYPE_MULTICAST, LOCALLY_ASSIGNED),
+            new TestCase("06:00:00:00:00:00", "06:00:00", TYPE_UNICAST, LOCALLY_ASSIGNED),
+            new TestCase("07:00:d3:56:8a:c4", "07:00:d3", TYPE_MULTICAST, LOCALLY_ASSIGNED),
+            new TestCase("00:01:44:55:66:77", "00:01:44", TYPE_UNICAST, GLOBALLY_UNIQUE),
+            new TestCase("08:00:22:33:44:55", "08:00:22", TYPE_UNICAST, GLOBALLY_UNIQUE),
+        };
+
+        for (TestCase tc : tests) {
+            MacAddress mac = MacAddress.fromString(tc.macAddress);
+
+            if (!tc.ouiString.equals(mac.toOuiString())) {
+                fail(String.format("expected OUI string %s, got %s",
+                        tc.ouiString, mac.toOuiString()));
+            }
+
+            if (tc.isLocallyAssigned != mac.isLocallyAssigned()) {
+                fail(String.format("expected %s to be %s, got %s", mac,
+                        localAssignedToString(tc.isLocallyAssigned),
+                        localAssignedToString(mac.isLocallyAssigned())));
+            }
+
+            if (tc.addressType != mac.getAddressType()) {
+                fail(String.format("expected %s address type to be %s, got %s", mac,
+                        typeToString(tc.addressType), typeToString(mac.getAddressType())));
+            }
+
+            if (!tc.macAddress.equals(mac.toString())) {
+                fail(String.format("expected toString() to return %s, got %s",
+                        tc.macAddress, mac.toString()));
+            }
+
+            if (!mac.equals(MacAddress.fromBytes(mac.toByteArray()))) {
+                byte[] bytes = mac.toByteArray();
+                fail(String.format("expected mac address from bytes %s to be %s, got %s",
+                        Arrays.toString(bytes),
+                        MacAddress.fromBytes(bytes),
+                        mac));
+            }
+        }
+    }
+
+    @Test
+    public void testConstructorInputValidation() {
+        String[] invalidStringAddresses = {
+            "",
+            "abcd",
+            "1:2:3:4:5",
+            "1:2:3:4:5:6:7",
+            "10000:2:3:4:5:6",
+        };
+
+        for (String s : invalidStringAddresses) {
+            try {
+                MacAddress mac = MacAddress.fromString(s);
+                fail("MacAddress.fromString(" + s + ") should have failed, but returned " + mac);
+            } catch (IllegalArgumentException excepted) {
+            }
+        }
+
+        try {
+            MacAddress mac = MacAddress.fromString(null);
+            fail("MacAddress.fromString(null) should have failed, but returned " + mac);
+        } catch (NullPointerException excepted) {
+        }
+
+        byte[][] invalidBytesAddresses = {
+            {},
+            {1,2,3,4,5},
+            {1,2,3,4,5,6,7},
+        };
+
+        for (byte[] b : invalidBytesAddresses) {
+            try {
+                MacAddress mac = MacAddress.fromBytes(b);
+                fail("MacAddress.fromBytes(" + Arrays.toString(b)
+                        + ") should have failed, but returned " + mac);
+            } catch (IllegalArgumentException excepted) {
+            }
+        }
+
+        try {
+            MacAddress mac = MacAddress.fromBytes(null);
+            fail("MacAddress.fromBytes(null) should have failed, but returned " + mac);
+        } catch (NullPointerException excepted) {
+        }
+    }
+}
diff --git a/tests/cts/net/src/android/net/cts/MultinetworkApiTest.java b/tests/cts/net/src/android/net/cts/MultinetworkApiTest.java
index 51ee50e..b2c9d9b 100644
--- a/tests/cts/net/src/android/net/cts/MultinetworkApiTest.java
+++ b/tests/cts/net/src/android/net/cts/MultinetworkApiTest.java
@@ -152,4 +152,27 @@
         // to query on the default network.
         // assertEquals(-OsConstants.ENONET, runGetaddrinfoCheck(eNoNetHandle));
     }
+
+    public void testNetworkHandle() {
+        // Test Network -> NetworkHandle -> Network results in the same Network.
+        for (Network network : getTestableNetworks()) {
+            long networkHandle = network.getNetworkHandle();
+            Network newNetwork = Network.fromNetworkHandle(networkHandle);
+            assertEquals(newNetwork, network);
+        }
+
+        // Test that only obfuscated handles are allowed.
+        try {
+            Network.fromNetworkHandle(100);
+            fail();
+        } catch (IllegalArgumentException e) {}
+        try {
+            Network.fromNetworkHandle(-1);
+            fail();
+        } catch (IllegalArgumentException e) {}
+        try {
+            Network.fromNetworkHandle(0);
+            fail();
+        } catch (IllegalArgumentException e) {}
+    }
 }
diff --git a/tests/cts/net/src/android/net/cts/MultinetworkSysctlTest.java b/tests/cts/net/src/android/net/cts/MultinetworkSysctlTest.java
index c091a13..1d0c111 100644
--- a/tests/cts/net/src/android/net/cts/MultinetworkSysctlTest.java
+++ b/tests/cts/net/src/android/net/cts/MultinetworkSysctlTest.java
@@ -29,7 +29,7 @@
 /**
  * Tests for multinetwork sysctl functionality.
  */
-public class MultinetworkSysctlTest extends AndroidTestCase {
+public class MultinetworkSysctlTest extends SysctlBaseTest {
 
     // Global sysctls. Must be present and set to 1.
     private static final String[] GLOBAL_SYSCTLS = {
@@ -42,30 +42,6 @@
     private static final String IPV6_SYSCTL_DIR = "/proc/sys/net/ipv6/conf";
     private static final String AUTOCONF_SYSCTL = "accept_ra_rt_table";
 
-    // Expected mode, UID, and GID of sysctl files.
-    private static final int SYSCTL_MODE = 0100644;
-    private static final int SYSCTL_UID = 0;
-    private static final int SYSCTL_GID = 0;
-
-    private void checkSysctlPermissions(String fileName) throws ErrnoException {
-        StructStat stat = Os.stat(fileName);
-        assertEquals("mode of " + fileName + ":", SYSCTL_MODE, stat.st_mode);
-        assertEquals("UID of " + fileName + ":", SYSCTL_UID, stat.st_uid);
-        assertEquals("GID of " + fileName + ":", SYSCTL_GID, stat.st_gid);
-    }
-
-    private void assertLess(String what, int a, int b) {
-        assertTrue(what + " expected < " + b + " but was: " + a, a < b);
-    }
-
-    private String readFile(String fileName) throws ErrnoException, IOException {
-        byte[] buf = new byte[1024];
-        FileDescriptor fd = Os.open(fileName, 0, OsConstants.O_RDONLY);
-        int bytesRead = Os.read(fd, buf, 0, buf.length);
-        assertLess("length of " + fileName + ":", bytesRead, buf.length);
-        return new String(buf);
-    }
-
     /**
      * Checks that the sysctls for multinetwork kernel features are present and
      * enabled. The necessary kernel commits are:
@@ -80,9 +56,8 @@
      */
      public void testProcFiles() throws ErrnoException, IOException, NumberFormatException {
          for (String sysctl : GLOBAL_SYSCTLS) {
-             checkSysctlPermissions(sysctl);
-             int value = Integer.parseInt(readFile(sysctl).trim());
-             assertEquals("value of " + sysctl + ":", 1, value);
+             int value = getIntValue(sysctl);
+             assertEquals(sysctl, 1, value);
          }
 
          File[] interfaceDirs = new File(IPV6_SYSCTL_DIR).listFiles();
@@ -91,9 +66,8 @@
                  continue;
              }
              String sysctl = new File(interfaceDir, AUTOCONF_SYSCTL).getAbsolutePath();
-             checkSysctlPermissions(sysctl);
-             int value = Integer.parseInt(readFile(sysctl).trim());
-             assertLess("value of " + sysctl + ":", value, 0);
+             int value = getIntValue(sysctl);
+             assertLess(sysctl, value, 0);
          }
      }
 }
diff --git a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java
new file mode 100644
index 0000000..c862c77
--- /dev/null
+++ b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2018 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.net.NetworkCapabilities.NET_CAPABILITY_MMS;
+import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH;
+
+import android.net.NetworkRequest;
+import android.test.AndroidTestCase;
+
+public class NetworkRequestTest extends AndroidTestCase {
+    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));
+    }
+
+    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));
+    }
+}
diff --git a/tests/cts/net/src/android/net/cts/NetworkWatchlistTest.java b/tests/cts/net/src/android/net/cts/NetworkWatchlistTest.java
new file mode 100644
index 0000000..e85de2a
--- /dev/null
+++ b/tests/cts/net/src/android/net/cts/NetworkWatchlistTest.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2018 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 com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.os.FileUtils;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.InstrumentationRegistry;
+
+import com.android.compatibility.common.util.ApiLevelUtil;
+import com.android.compatibility.common.util.SystemUtil;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Formatter;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class NetworkWatchlistTest {
+
+    private static final String TEST_WATCHLIST_XML = "assets/network_watchlist_config_for_test.xml";
+    private static final String TEST_EMPTY_WATCHLIST_XML =
+            "assets/network_watchlist_config_empty_for_test.xml";
+    private static final String SDCARD_CONFIG_PATH =
+            "/sdcard/network_watchlist_config_for_test.xml";
+    private static final String TMP_CONFIG_PATH =
+            "/data/local/tmp/network_watchlist_config_for_test.xml";
+    // Generated from sha256sum network_watchlist_config_for_test.xml
+    private static final String TEST_WATCHLIST_CONFIG_HASH =
+            "B5FC4636994180D54E1E912F78178AB1D8BD2BE71D90CA9F5BBC3284E4D04ED4";
+
+    private ConnectivityManager mConnectivityManager;
+    private boolean mHasFeature;
+
+    @Before
+    public void setUp() throws Exception {
+        mHasFeature = isAtLeastP();
+        mConnectivityManager =
+                (ConnectivityManager) InstrumentationRegistry.getContext().getSystemService(
+                        Context.CONNECTIVITY_SERVICE);
+        assumeTrue(mHasFeature);
+        // Set empty watchlist test config before testing
+        setWatchlistConfig(TEST_EMPTY_WATCHLIST_XML);
+        // Verify test watchlist config is not set before testing
+        byte[] result = mConnectivityManager.getNetworkWatchlistConfigHash();
+        assertNotEquals(TEST_WATCHLIST_CONFIG_HASH, byteArrayToHexString(result));
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (mHasFeature) {
+            // Set empty watchlist test config after testing
+            setWatchlistConfig(TEST_EMPTY_WATCHLIST_XML);
+        }
+    }
+
+    private void cleanup() throws Exception {
+        runCommand("rm " + SDCARD_CONFIG_PATH);
+        runCommand("rm " + TMP_CONFIG_PATH);
+    }
+
+    private boolean isAtLeastP() throws Exception {
+        // TODO: replace with ApiLevelUtil.isAtLeast(Build.VERSION_CODES.P) when the P API level
+        // constant is defined.
+        return ApiLevelUtil.getCodename().compareToIgnoreCase("P") >= 0;
+    }
+
+    /**
+     * Test if ConnectivityManager.getNetworkWatchlistConfigHash() correctly
+     * returns the hash of config we set.
+     */
+    @Test
+    public void testGetWatchlistConfigHash() throws Exception {
+        // Set watchlist config file for test
+        setWatchlistConfig(TEST_WATCHLIST_XML);
+        // Test if watchlist config hash value is correct
+        byte[] result = mConnectivityManager.getNetworkWatchlistConfigHash();
+        Assert.assertEquals(TEST_WATCHLIST_CONFIG_HASH, byteArrayToHexString(result));
+    }
+
+    private static String byteArrayToHexString(byte[] bytes) {
+        Formatter formatter = new Formatter();
+        for (byte b : bytes) {
+            formatter.format("%02X", b);
+        }
+        return formatter.toString();
+    }
+
+    private void saveResourceToFile(String res, String filePath) throws IOException {
+        InputStream in = getClass().getClassLoader().getResourceAsStream(res);
+        FileUtils.copyToFileOrThrow(in, new File(filePath));
+    }
+
+    private static String runCommand(String command) throws IOException {
+        return SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(), command);
+    }
+
+    private void setWatchlistConfig(String watchlistConfigFile) throws Exception {
+        cleanup();
+        // Save test watchlist config to sdcard as app can't access /data/local/tmp
+        saveResourceToFile(watchlistConfigFile, SDCARD_CONFIG_PATH);
+        // Copy test watchlist config from sdcard to /data/local/tmp as system service
+        // can't access /sdcard
+        runCommand("cp " + SDCARD_CONFIG_PATH + " " + TMP_CONFIG_PATH);
+        // Set test watchlist config to system
+        final String cmdResult = runCommand(
+                "cmd network_watchlist set-test-config " + TMP_CONFIG_PATH).trim();
+        assertThat(cmdResult).contains("Success");
+        cleanup();
+    }
+}
diff --git a/tests/cts/net/src/android/net/cts/SysctlBaseTest.java b/tests/cts/net/src/android/net/cts/SysctlBaseTest.java
new file mode 100644
index 0000000..a5966d4
--- /dev/null
+++ b/tests/cts/net/src/android/net/cts/SysctlBaseTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2018 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.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.system.StructStat;
+import android.test.AndroidTestCase;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.IOException;
+
+/**
+ * Tests for multinetwork sysctl functionality.
+ */
+public class SysctlBaseTest extends AndroidTestCase {
+
+    // Expected mode, UID, and GID of sysctl files.
+    private static final int SYSCTL_MODE = 0100644;
+    private static final int SYSCTL_UID = 0;
+    private static final int SYSCTL_GID = 0;
+
+    private void checkSysctlPermissions(String fileName) throws ErrnoException {
+        StructStat stat = Os.stat(fileName);
+        assertEquals("mode of " + fileName + ":", SYSCTL_MODE, stat.st_mode);
+        assertEquals("UID of " + fileName + ":", SYSCTL_UID, stat.st_uid);
+        assertEquals("GID of " + fileName + ":", SYSCTL_GID, stat.st_gid);
+    }
+
+    protected void assertLess(String sysctl, int a, int b) {
+        assertTrue("value of " + sysctl + ": expected < " + b + " but was: " + a, a < b);
+    }
+
+    protected void assertAtLeast(String sysctl, int a, int b) {
+        assertTrue("value of " + sysctl + ": expected >= " + b + " but was: " + a, a >= b);
+    }
+
+    private String readFile(String fileName) throws ErrnoException, IOException {
+        byte[] buf = new byte[1024];
+        FileDescriptor fd = Os.open(fileName, 0, OsConstants.O_RDONLY);
+        int bytesRead = Os.read(fd, buf, 0, buf.length);
+        assertLess("length of " + fileName + ":", bytesRead, buf.length);
+        return new String(buf);
+    }
+
+    /*
+     * Checks permissions and retrieves the sysctl's value. Retrieval of value should always use
+     * this method
+     */
+    protected int getIntValue(String filename) throws ErrnoException, IOException {
+        checkSysctlPermissions(filename);
+        return Integer.parseInt(readFile(filename).trim());
+    }
+}
diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java
index 930c742..a8743fa 100755
--- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java
+++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java
@@ -81,26 +81,6 @@
         return packetCount * (20 + 32 + bytes);
     }
 
-    private void accessOwnTrafficStats() throws IOException {
-        final int ownAppUid = getContext().getApplicationInfo().uid;
-        Log.d(LOG_TAG, "accesOwnTrafficStatsWithTags(): about to read qtaguid stats for own uid " + ownAppUid);
-
-        boolean foundOwnDetailedStats = false;
-        try {
-            BufferedReader qtaguidReader = new BufferedReader(new FileReader("/proc/net/xt_qtaguid/stats"));
-            String line;
-            while ((line = qtaguidReader.readLine()) != null) {
-                String tokens[] = line.split(" ");
-                if (tokens.length > 3 && tokens[3].equals(String.valueOf(ownAppUid))) {
-                    Log.d(LOG_TAG, "accessOwnTrafficStatsWithTags(): got own stats: " + line);
-                }
-            }
-            qtaguidReader.close();
-        } catch (FileNotFoundException e) {
-            fail("Was not able to access qtaguid/stats: " + e);
-        }
-    }
-
     public void testTrafficStatsForLocalhost() throws IOException {
         final long mobileTxPacketsBefore = TrafficStats.getMobileTxPackets();
         final long mobileRxPacketsBefore = TrafficStats.getMobileRxPackets();
@@ -132,7 +112,6 @@
                     byte[] buf = new byte[byteCount];
                     TrafficStats.setThreadStatsTag(0x42);
                     TrafficStats.tagSocket(socket);
-                    accessOwnTrafficStats();
                     for (int i = 0; i < packetCount; i++) {
                         out.write(buf);
                         out.flush();
@@ -145,7 +124,6 @@
                     }
                     out.close();
                     socket.close();
-                    accessOwnTrafficStats();
                 } catch (IOException e) {
                     Log.i(LOG_TAG, "Badness during writes to socket: " + e);
                 }
diff --git a/tests/cts/net/src/android/net/wifi/aware/OWNERS b/tests/cts/net/src/android/net/wifi/aware/OWNERS
new file mode 100644
index 0000000..4afc47f
--- /dev/null
+++ b/tests/cts/net/src/android/net/wifi/aware/OWNERS
@@ -0,0 +1,2 @@
+etancohen@google.com
+satk@google.com
\ No newline at end of file
diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java
index 87e22d8..7277553 100644
--- a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java
+++ b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java
@@ -20,7 +20,9 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.location.LocationManager;
 import android.net.ConnectivityManager;
+import android.net.MacAddress;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
 import android.net.wifi.WifiManager;
@@ -37,14 +39,11 @@
 import android.net.wifi.aware.WifiAwareSession;
 import android.os.Handler;
 import android.os.HandlerThread;
-import android.provider.Settings;
 import android.test.AndroidTestCase;
-import android.util.Log;
 
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.CountDownLatch;
@@ -76,13 +75,6 @@
     // used to store any WifiAwareSession allocated during tests - will clean-up after tests
     private List<WifiAwareSession> mSessions = new ArrayList<>();
 
-    // Return true if location is enabled.
-    private boolean isLocationEnabled() {
-        return Settings.Secure.getInt(getContext().getContentResolver(),
-                Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF) !=
-                Settings.Secure.LOCATION_MODE_OFF;
-    }
-
     private class WifiAwareBroadcastReceiver extends BroadcastReceiver {
         private CountDownLatch mBlocker = new CountDownLatch(1);
 
@@ -358,6 +350,10 @@
             return;
         }
 
+        assertTrue("Wi-Fi Aware requires Location to be Enabled",
+                ((LocationManager) getContext().getSystemService(
+                        Context.LOCATION_SERVICE)).isLocationEnabled());
+
         mWifiAwareManager = (WifiAwareManager) getContext().getSystemService(
                 Context.WIFI_AWARE_SERVICE);
         assertNotNull("Wi-Fi Aware Manager", mWifiAwareManager);
@@ -431,18 +427,6 @@
             return;
         }
 
-        if (isLocationEnabled()) {
-            /* Can't execute this test with location on since it means that Aware will not get
-             * disabled even if we disable Wi-Fi (which when location is enabled does not correspond
-             * to disabling the Wi-Fi chip).
-             *
-             * Considering other tests may require locationing to be enable we can't also fail the
-             * test in such a case. Hence it is skipped.
-             */
-            Log.d(TAG, "Skipping test since location scans are enabled");
-            return;
-        }
-
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED);
 
@@ -717,82 +701,14 @@
     }
 
     /**
-     * Request an Aware data-path (open) on a Publish discovery session (which can be done with a
-     * null peer - to accept all requests). Validate that times-out.
-     */
-    public void testDataPathOpenInContextOfDiscoveryFail() {
-        if (!TestUtils.shouldTestWifiAware(getContext())) {
-            return;
-        }
-
-        WifiAwareSession session = attachAndGetSession();
-
-        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
-                "ValidName").build();
-        DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
-        NetworkCallbackTest networkCb = new NetworkCallbackTest();
-
-        // 1. publish
-        session.publish(publishConfig, discoveryCb, mHandler);
-        assertTrue("Publish started",
-                discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
-        PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession();
-        assertNotNull("Publish session", discoverySession);
-
-        // 2. request an AWARE network
-        NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
-                NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier(
-                discoverySession.createNetworkSpecifierOpen(null)).build();
-        mConnectivityManager.requestNetwork(nr, networkCb, 2000);
-        assertTrue("OnUnavailable received", networkCb.waitForOnUnavailable());
-
-        discoverySession.close();
-        session.close();
-    }
-
-    /**
-     * Request an Aware data-path (encrypted) on a Publish discovery session (which can be done
-     * with a null peer - to accept all requests). Validate that times-out.
-     */
-    public void testDataPathPassphraseInContextOfDiscoveryFail() {
-        if (!TestUtils.shouldTestWifiAware(getContext())) {
-            return;
-        }
-
-        WifiAwareSession session = attachAndGetSession();
-
-        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
-                "ValidName").build();
-        DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
-        NetworkCallbackTest networkCb = new NetworkCallbackTest();
-
-        // 1. publish
-        session.publish(publishConfig, discoveryCb, mHandler);
-        assertTrue("Publish started",
-                discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
-        PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession();
-        assertNotNull("Publish session", discoverySession);
-
-        // 2. request an AWARE network
-        NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
-                NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier(
-                discoverySession.createNetworkSpecifierPassphrase(null,
-                        "Some very long but not very good passphrase")).build();
-        mConnectivityManager.requestNetwork(nr, networkCb, 2000);
-        assertTrue("OnUnavailable received", networkCb.waitForOnUnavailable());
-
-        discoverySession.close();
-        session.close();
-    }
-
-    /**
-     * Request an Aware data-path (open) as a Responder with no peer MAC address (i.e. accept any
-     * peer request). Validate that times-out.
+     * Request an Aware data-path (open) as a Responder with an arbitrary peer MAC address. Validate
+     * that times-out.
      */
     public void testDataPathOpenOutOfBandFail() {
         if (!TestUtils.shouldTestWifiAware(getContext())) {
             return;
         }
+        MacAddress mac = MacAddress.fromString("00:01:02:03:04:05");
 
         WifiAwareSession session = attachAndGetSession();
 
@@ -805,7 +721,8 @@
         NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
                 NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier(
                 session.createNetworkSpecifierOpen(
-                        WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER, null)).build();
+                        WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER,
+                        mac.toByteArray())).build();
         mConnectivityManager.requestNetwork(nr, networkCb, 2000);
         assertTrue("OnUnavailable received", networkCb.waitForOnUnavailable());
 
@@ -813,13 +730,14 @@
     }
 
     /**
-     * Request an Aware data-path (encrypted) as a Responder with no peer MAC address (i.e.
-     * accept any peer request). Validate that times-out.
+     * Request an Aware data-path (encrypted) as a Responder with an arbitrary peer MAC address.
+     * Validate that times-out.
      */
     public void testDataPathPassphraseOutOfBandFail() {
         if (!TestUtils.shouldTestWifiAware(getContext())) {
             return;
         }
+        MacAddress mac = MacAddress.fromString("00:01:02:03:04:05");
 
         WifiAwareSession session = attachAndGetSession();
 
@@ -832,7 +750,7 @@
         NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
                 NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier(
                 session.createNetworkSpecifierPassphrase(
-                        WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER, null,
+                        WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER, mac.toByteArray(),
                         "abcdefghihk")).build();
         mConnectivityManager.requestNetwork(nr, networkCb, 2000);
         assertTrue("OnUnavailable received", networkCb.waitForOnUnavailable());
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java
index 89daca2..292ff0f 100644
--- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -201,6 +201,25 @@
         }
     }
 
+    // Get the current scan status from sticky broadcast.
+    private boolean isScanCurrentlyAvailable() {
+        boolean isAvailable = false;
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(WifiManager.WIFI_SCAN_AVAILABLE);
+        Intent intent = mContext.registerReceiver(null, intentFilter);
+        assertNotNull(intent);
+        if (intent.getAction().equals(WifiManager.WIFI_SCAN_AVAILABLE)) {
+            int state = intent.getIntExtra(
+                    WifiManager.EXTRA_SCAN_AVAILABLE, WifiManager.WIFI_STATE_UNKNOWN);
+            if (state == WifiManager.WIFI_STATE_ENABLED) {
+                isAvailable = true;
+            } else if (state == WifiManager.WIFI_STATE_DISABLED) {
+                isAvailable = false;
+            }
+        }
+        return isAvailable;
+    }
+
     private void startScan() throws Exception {
         synchronized (mMySync) {
             mMySync.expectedState = STATE_SCANNING;
@@ -245,8 +264,7 @@
      * 1.reconnect
      * 2.reassociate
      * 3.disconnect
-     * 4.pingSupplicant
-     * 5.satrtScan
+     * 4.createWifiLock
      */
     public void testWifiManagerActions() throws Exception {
         if (!WifiFeature.isWifiSupported(getContext())) {
@@ -256,10 +274,32 @@
         assertTrue(mWifiManager.reconnect());
         assertTrue(mWifiManager.reassociate());
         assertTrue(mWifiManager.disconnect());
+        final String TAG = "Test";
+        assertNotNull(mWifiManager.createWifiLock(TAG));
+        assertNotNull(mWifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, TAG));
+    }
+
+    /**
+     * Test wifi scanning when location scan is turned off.
+     */
+    public void testWifiManagerScanWhenWifiOffLocationTurnedOn() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        if (!hasLocationFeature()) {
+            Log.d(TAG, "Skipping test as location is not supported");
+            return;
+        }
+        if (!isLocationEnabled()) {
+            fail("Please enable location for this test - since Marshmallow WiFi scan results are"
+                    + " empty when location is disabled!");
+        }
+        assertTrue(mWifiManager.isScanAlwaysAvailable());
         setWifiEnabled(false);
-        startScan();
         Thread.sleep(DURATION);
-        if (mWifiManager.isScanAlwaysAvailable()) {
+        startScan();
+        if (isScanCurrentlyAvailable()) {
             // Make sure at least one AP is found.
             assertNotNull("mScanResult should not be null!", mScanResults);
             assertFalse("empty scan results!", mScanResults.isEmpty());
diff --git a/tests/cts/net/src/android/net/wifi/rtt/OWNERS b/tests/cts/net/src/android/net/wifi/rtt/OWNERS
new file mode 100644
index 0000000..4afc47f
--- /dev/null
+++ b/tests/cts/net/src/android/net/wifi/rtt/OWNERS
@@ -0,0 +1,2 @@
+etancohen@google.com
+satk@google.com
\ No newline at end of file
diff --git a/tests/cts/net/src/android/net/wifi/rtt/cts/TestBase.java b/tests/cts/net/src/android/net/wifi/rtt/cts/TestBase.java
new file mode 100644
index 0000000..adbe0f6
--- /dev/null
+++ b/tests/cts/net/src/android/net/wifi/rtt/cts/TestBase.java
@@ -0,0 +1,313 @@
+/*
+ * Copyright (C) 2018 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.wifi.rtt.cts;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.location.LocationManager;
+import android.net.NetworkInfo;
+import android.net.wifi.ScanResult;
+import android.net.wifi.SupplicantState;
+import android.net.wifi.WifiManager;
+import android.net.wifi.rtt.RangingResult;
+import android.net.wifi.rtt.RangingResultCallback;
+import android.net.wifi.rtt.WifiRttManager;
+import android.os.Handler;
+import android.os.HandlerExecutor;
+import android.os.HandlerThread;
+import android.test.AndroidTestCase;
+
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Base class for Wi-Fi RTT CTS test cases. Provides a uniform configuration and event management
+ * facility.
+ */
+public class TestBase extends AndroidTestCase {
+    protected static final String TAG = "WifiRttCtsTests";
+
+    // wait for Wi-Fi to enable and/or connect
+    private static final int WAIT_FOR_WIFI_ENABLE_SECS = 10;
+
+    // wait for Wi-Fi RTT to become available
+    private static final int WAIT_FOR_RTT_CHANGE_SECS = 10;
+
+    // wait for Wi-Fi scan results to become available
+    private static final int WAIT_FOR_SCAN_RESULTS_SECS = 20;
+
+    protected WifiRttManager mWifiRttManager;
+    protected WifiManager mWifiManager;
+    private LocationManager mLocationManager;
+    private WifiManager.WifiLock mWifiLock;
+
+    protected IntentFilter mRttIntent;
+    protected IntentFilter mWifiStateIntent;
+    protected IntentFilter mWifiConnectedIntent;
+
+    private final HandlerThread mHandlerThread = new HandlerThread("SingleDeviceTest");
+    protected final Executor mExecutor;
+    {
+        mHandlerThread.start();
+        mExecutor = new HandlerExecutor(new Handler(mHandlerThread.getLooper()));
+    }
+
+    /**
+     * Returns a flag indicating whether or not Wi-Fi RTT should be tested. Wi-Fi RTT
+     * should be tested if the feature is supported on the current device.
+     */
+    static boolean shouldTestWifiRtt(Context context) {
+        // TODO b/74457054: enable when t/31350604 resolved
+        return false;
+//        final PackageManager pm = context.getPackageManager();
+//        return pm.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        if (!shouldTestWifiRtt(getContext())) {
+            return;
+        }
+
+        mLocationManager = (LocationManager) getContext().getSystemService(
+                Context.LOCATION_SERVICE);
+        assertTrue("RTT testing requires Location to be enabled",
+                mLocationManager.isLocationEnabled());
+
+        mWifiRttManager = (WifiRttManager) getContext().getSystemService(
+                Context.WIFI_RTT_RANGING_SERVICE);
+        assertNotNull("Wi-Fi RTT Manager", mWifiRttManager);
+
+        mRttIntent = new IntentFilter();
+        mRttIntent.addAction(WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED);
+
+        mWifiStateIntent = new IntentFilter();
+        mWifiStateIntent.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+
+        mWifiConnectedIntent = new IntentFilter();
+        mWifiConnectedIntent.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+
+        mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
+        assertNotNull("Wi-Fi Manager", mWifiManager);
+        mWifiLock = mWifiManager.createWifiLock(TAG);
+        mWifiLock.acquire();
+        assertTrue("Location scans must be enabled", mWifiManager.isScanAlwaysAvailable());
+        if (!mWifiManager.isWifiEnabled()) {
+            mWifiManager.setWifiEnabled(true);
+            WifiEnableBroadcastReceiver receiver = new WifiEnableBroadcastReceiver(true);
+            mContext.registerReceiver(receiver, mWifiStateIntent);
+            receiver.waitForDesiredState();
+            mContext.unregisterReceiver(receiver);
+        }
+
+        if (!mWifiManager.getConnectionInfo().getSupplicantState().equals(
+                SupplicantState.COMPLETED)) {
+            WifiConnectedBroadcastReceiver receiver = new WifiConnectedBroadcastReceiver();
+            mContext.registerReceiver(receiver, mWifiConnectedIntent);
+            receiver.waitForConnected();
+            mContext.unregisterReceiver(receiver);
+        }
+
+        if (!mWifiRttManager.isAvailable()) {
+            WifiRttBroadcastReceiver receiver = new WifiRttBroadcastReceiver();
+            mContext.registerReceiver(receiver, mRttIntent);
+            assertTrue("Timeout waiting for Wi-Fi RTT to change status",
+                    receiver.waitForStateChange());
+            assertTrue("Wi-Fi RTT is not available (should be)", mWifiRttManager.isAvailable());
+            mContext.unregisterReceiver(receiver);
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (!shouldTestWifiRtt(getContext())) {
+            super.tearDown();
+            return;
+        }
+
+        super.tearDown();
+    }
+
+    private class SyncBroadcastReceiver extends BroadcastReceiver {
+        private CountDownLatch mBlocker = new CountDownLatch(1);
+        private String mAction;
+        private int mTimeout;
+
+        SyncBroadcastReceiver(String action, int timeout) {
+            mAction = action;
+            mTimeout = timeout;
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (mAction.equals(intent.getAction())) {
+                mBlocker.countDown();
+            }
+        }
+
+        boolean waitForStateChange() throws InterruptedException {
+            return mBlocker.await(mTimeout, TimeUnit.SECONDS);
+        }
+    };
+
+    class WifiEnableBroadcastReceiver extends BroadcastReceiver {
+        private CountDownLatch mBlocker = new CountDownLatch(1);
+        private boolean mDesiredState;
+
+        WifiEnableBroadcastReceiver(boolean desiredState) {
+            mDesiredState = desiredState;
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {
+                if (mWifiManager.isWifiEnabled() == mDesiredState) {
+                    mBlocker.countDown();
+                }
+            }
+        }
+
+        boolean waitForDesiredState() throws InterruptedException {
+            return mBlocker.await(WAIT_FOR_WIFI_ENABLE_SECS, TimeUnit.SECONDS);
+        }
+    }
+
+    class WifiConnectedBroadcastReceiver extends BroadcastReceiver {
+        private CountDownLatch mBlocker = new CountDownLatch(1);
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(intent.getAction())) {
+                NetworkInfo ni = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
+                if (ni.getState() == NetworkInfo.State.CONNECTED) {
+                    mBlocker.countDown();
+                }
+            }
+        }
+
+        boolean waitForConnected() throws InterruptedException {
+            return mBlocker.await(WAIT_FOR_WIFI_ENABLE_SECS, TimeUnit.SECONDS);
+        }
+    }
+
+    class WifiRttBroadcastReceiver extends SyncBroadcastReceiver {
+        WifiRttBroadcastReceiver() {
+            super(WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED, WAIT_FOR_RTT_CHANGE_SECS);
+        }
+    }
+
+    class WifiScansBroadcastReceiver extends SyncBroadcastReceiver {
+        WifiScansBroadcastReceiver() {
+            super(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION, WAIT_FOR_SCAN_RESULTS_SECS);
+        }
+    }
+
+    class ResultCallback extends RangingResultCallback {
+        private CountDownLatch mBlocker = new CountDownLatch(1);
+        private int mCode; // 0: success, otherwise RangingResultCallback STATUS_CODE_*.
+        private List<RangingResult> mResults;
+
+        @Override
+        public void onRangingFailure(int code) {
+            mCode = code;
+            mResults = null; // not necessary since intialized to null - but for completeness
+            mBlocker.countDown();
+        }
+
+        @Override
+        public void onRangingResults(List<RangingResult> results) {
+            mCode = 0; // not necessary since initialized to 0 - but for completeness
+            mResults = results;
+            mBlocker.countDown();
+        }
+
+        /**
+         * Waits for the listener callback to be called - or an error (timeout, interruption).
+         * Returns true on callback called, false on error (timeout, interruption).
+         */
+        boolean waitForCallback() throws InterruptedException {
+            return mBlocker.await(WAIT_FOR_RTT_CHANGE_SECS, TimeUnit.SECONDS);
+        }
+
+        /**
+         * Returns the code of the callback operation. Will be 0 for success (onRangingResults
+         * called), else (if onRangingFailure called) will be one of the STATUS_CODE_* values.
+         */
+        int getCode() {
+            return mCode;
+        }
+
+        /**
+         * Returns the list of ranging results. In cases of error (getCode() != 0) will return null.
+         */
+        List<RangingResult> getResults() {
+            return mResults;
+        }
+    }
+
+    /**
+     * Start a scan and return a list of observed ScanResults (APs).
+     */
+    protected List<ScanResult> scanAps() throws InterruptedException {
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
+        WifiScansBroadcastReceiver receiver = new WifiScansBroadcastReceiver();
+        mContext.registerReceiver(receiver, intentFilter);
+
+        mWifiManager.startScan();
+        receiver.waitForStateChange();
+        mContext.unregisterReceiver(receiver);
+        return mWifiManager.getScanResults();
+    }
+
+    /**
+     * Start a scan and return the test AP with the specified SSID and which supports IEEE 802.11mc.
+     * If the AP is not found re-attempts the scan maxScanRetries times (i.e. total number of
+     * scans can be maxScanRetries + 1).
+     *
+     * Returns null if test AP is not found in the specified number of scans.
+     *
+     * @param bssid The BSSID of the test AP
+     * @param maxScanRetries Maximum number of scans retries (in addition to first scan).
+     */
+    protected ScanResult scanForTestAp(String bssid, int maxScanRetries)
+            throws InterruptedException {
+        int scanCount = 0;
+        while (scanCount <= maxScanRetries) {
+            for (ScanResult scanResult : scanAps()) {
+                if (!scanResult.is80211mcResponder()) {
+                    continue;
+                }
+                if (!bssid.equals(scanResult.BSSID)) {
+                    continue;
+                }
+
+                return scanResult;
+            }
+
+            scanCount++;
+        }
+
+        return null;
+    }
+}
diff --git a/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java b/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java
new file mode 100644
index 0000000..5e8ae16
--- /dev/null
+++ b/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2018 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.wifi.rtt.cts;
+
+import android.net.wifi.ScanResult;
+import android.net.wifi.rtt.RangingRequest;
+import android.net.wifi.rtt.RangingResult;
+
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Wi-Fi RTT CTS test: range to all available Access Points which support IEEE 802.11mc.
+ */
+public class WifiRttTest extends TestBase {
+    // Max number of scan retries to do while searching for APs supporting IEEE 802.11mc
+    private static final int MAX_NUM_SCAN_RETRIES_SEARCHING_FOR_IEEE80211MC_AP = 2;
+
+    // Number of RTT measurements per AP
+    private static final int NUM_OF_RTT_ITERATIONS = 10;
+
+    // Maximum failure rate of RTT measurements (percentage)
+    private static final int MAX_FAILURE_RATE_PERCENT = 10;
+
+    // Maximum variation from the average measurement (measures consistency)
+    private static final int MAX_VARIATION_FROM_AVERAGE_DISTANCE_MM = 1000;
+
+    // Minimum valid RSSI value
+    private static final int MIN_VALID_RSSI = -100;
+
+    /**
+     * Test Wi-Fi RTT ranging operation:
+     * - Scan for visible APs for the test AP (which is validated to support IEEE 802.11mc)
+     * - Perform N (constant) RTT operations
+     * - Validate:
+     *   - Failure ratio < threshold (constant)
+     *   - Result margin < threshold (constant)
+     */
+    public void testRangingToTestAp() throws InterruptedException {
+        if (!shouldTestWifiRtt(getContext())) {
+            return;
+        }
+
+        // Find the associated AP: get BSSID and disable Wi-Fi
+        String bssid = mWifiManager.getConnectionInfo().getBSSID();
+        assertNotNull("Null BSSID - must be associated!", bssid);
+        assertTrue("Cannot disable Wi-Fi (to disassociate)", mWifiManager.setWifiEnabled(false));
+        WifiEnableBroadcastReceiver receiver = new WifiEnableBroadcastReceiver(false);
+        mContext.registerReceiver(receiver, mWifiStateIntent);
+        receiver.waitForDesiredState();
+        mContext.unregisterReceiver(receiver);
+
+        // Scan for IEEE 802.11mc supporting APs
+        ScanResult testAp = scanForTestAp(bssid, MAX_NUM_SCAN_RETRIES_SEARCHING_FOR_IEEE80211MC_AP);
+        assertTrue("Cannot find test AP: bssid=" + bssid, testAp != null);
+
+        // Perform RTT operations
+        RangingRequest request = new RangingRequest.Builder().addAccessPoint(testAp).build();
+        List<RangingResult> allResults = new ArrayList<>();
+        int numFailures = 0;
+        int distanceSum = 0;
+        int distanceMin = 0;
+        int distanceMax = 0;
+        int[] statuses = new int[NUM_OF_RTT_ITERATIONS];
+        int[] distanceMms = new int[NUM_OF_RTT_ITERATIONS];
+        int[] distanceStdDevMms = new int[NUM_OF_RTT_ITERATIONS];
+        int[] rssis = new int[NUM_OF_RTT_ITERATIONS];
+        for (int i = 0; i < NUM_OF_RTT_ITERATIONS; ++i) {
+            ResultCallback callback = new ResultCallback();
+            mWifiRttManager.startRanging(request, mExecutor, callback);
+            assertTrue("Wi-Fi RTT results: no callback on iteration " + i,
+                    callback.waitForCallback());
+
+            List<RangingResult> currentResults = callback.getResults();
+            assertTrue("Wi-Fi RTT results: null results (onRangingFailure) on iteration " + i,
+                    currentResults != null);
+            assertTrue("Wi-Fi RTT results: unexpected # of results (expect 1) on iteration " + i,
+                    currentResults.size() == 1);
+            RangingResult result = currentResults.get(0);
+            assertTrue("Wi-Fi RTT results: invalid result (wrong BSSID) entry on iteration " + i,
+                    result.getMacAddress().toString().equals(testAp.BSSID));
+
+            allResults.add(result);
+            int status = result.getStatus();
+            statuses[i] = status;
+            if (status == RangingResult.STATUS_SUCCESS) {
+                distanceSum += result.getDistanceMm();
+                if (i == 0) {
+                    distanceMin = result.getDistanceMm();
+                    distanceMax = result.getDistanceMm();
+                } else {
+                    distanceMin = Math.min(distanceMin, result.getDistanceMm());
+                    distanceMax = Math.max(distanceMax, result.getDistanceMm());
+                }
+
+                assertTrue("Wi-Fi RTT results: invalid RSSI on iteration " + i,
+                        result.getRssi() >= MIN_VALID_RSSI);
+
+                distanceMms[i - numFailures] = result.getDistanceMm();
+                distanceStdDevMms[i - numFailures] = result.getDistanceStdDevMm();
+                rssis[i - numFailures] = result.getRssi();
+            } else {
+                numFailures++;
+            }
+        }
+
+        // Save results to log
+        int numGoodResults = NUM_OF_RTT_ITERATIONS - numFailures;
+        DeviceReportLog reportLog = new DeviceReportLog(TAG, "testRangingToTestAp");
+        reportLog.addValues("status_codes", statuses, ResultType.NEUTRAL, ResultUnit.NONE);
+        reportLog.addValues("distance_mm", Arrays.copyOf(distanceMms, numGoodResults),
+                ResultType.NEUTRAL, ResultUnit.NONE);
+        reportLog.addValues("distance_stddev_mm", Arrays.copyOf(distanceStdDevMms, numGoodResults),
+                ResultType.NEUTRAL, ResultUnit.NONE);
+        reportLog.addValues("rssi_dbm", Arrays.copyOf(rssis, numGoodResults), ResultType.NEUTRAL,
+                ResultUnit.NONE);
+        reportLog.submit();
+
+        // Analyze results
+        assertTrue("Wi-Fi RTT failure rate exceeds threshold",
+                numFailures <= NUM_OF_RTT_ITERATIONS * MAX_FAILURE_RATE_PERCENT / 100);
+        if (numFailures != NUM_OF_RTT_ITERATIONS) {
+            double distanceAvg = distanceSum / (NUM_OF_RTT_ITERATIONS - numFailures);
+            assertTrue("Wi-Fi RTT: Variation (max direction) exceeds threshold",
+                    (distanceMax - distanceAvg) <= MAX_VARIATION_FROM_AVERAGE_DISTANCE_MM);
+            assertTrue("Wi-Fi RTT: Variation (min direction) exceeds threshold",
+                    (distanceAvg - distanceMin) <= MAX_VARIATION_FROM_AVERAGE_DISTANCE_MM);
+        }
+    }
+
+    /**
+     * Validate that when a request contains more range operations than allowed (by API) that we
+     * get an exception.
+     */
+    public void testRequestTooLarge() {
+        if (!shouldTestWifiRtt(getContext())) {
+            return;
+        }
+
+        RangingRequest.Builder builder = new RangingRequest.Builder();
+        for (int i = 0; i < RangingRequest.getMaxPeers() + 1; ++i) {
+            ScanResult dummy = new ScanResult();
+            dummy.BSSID = "00:01:02:03:04:05";
+            builder.addAccessPoint(dummy);
+        }
+
+        try {
+            mWifiRttManager.startRanging(builder.build(), mExecutor, new ResultCallback());
+        } catch (IllegalArgumentException e) {
+            return;
+        }
+
+        assertTrue(
+                "Did not receive expected IllegalArgumentException when tried to range to too "
+                        + "many peers",
+                false);
+    }
+}
