diff --git a/tests/cts/hostside/AndroidTest.xml b/tests/cts/hostside/AndroidTest.xml
index c7cab7b..dbff179 100644
--- a/tests/cts/hostside/AndroidTest.xml
+++ b/tests/cts/hostside/AndroidTest.xml
@@ -18,6 +18,7 @@
     <option name="config-descriptor:metadata" key="component" value="networking" />
     <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
     <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
 
     <target_preparer class="com.android.cts.net.NetPolicyTestsPreparer" />
 
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 7bf7bd4..55bd406 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
@@ -150,6 +150,11 @@
     }
 
     public void testAppIdleNetworkAccess_whenCharging() throws Exception {
+        if (!isBatterySaverSupported()) {
+            Log.i(TAG, "Skipping " + getClass() + "." + getName()
+                    + "() because device does not support Battery saver mode");
+            return;
+        }
         if (!isSupported()) return;
 
         // Check that app is paroled when charging
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java
index 28175b8..931376b 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java
@@ -16,6 +16,7 @@
 
 package com.android.cts.net.hostside;
 
+import android.text.TextUtils;
 import android.util.Log;
 
 /**
@@ -52,12 +53,19 @@
 
     @Override
     protected boolean isSupported() throws Exception {
-        boolean supported = isDozeModeEnabled();
-        if (!supported) {
-            Log.i(TAG, "Skipping " + getClass() + "." + getName()
-                    + "() because device does not support Doze Mode");
+        String unSupported = "";
+        if (!isDozeModeEnabled()) {
+            unSupported += "Doze mode,";
         }
-        return supported;
+        if (!isBatterySaverSupported()) {
+            unSupported += "Battery saver mode,";
+        }
+        if (!TextUtils.isEmpty(unSupported)) {
+            Log.i(TAG, "Skipping " + getClass() + "." + getName()
+                    + "() because device does not support " + unSupported);
+            return false;
+        }
+        return 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 6dfa2f3..40d7e34 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
@@ -34,6 +34,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
@@ -43,12 +44,15 @@
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.SystemClock;
+import android.os.SystemProperties;
 import android.provider.Settings;
 import android.service.notification.NotificationListenerService;
 import android.test.InstrumentationTestCase;
 import android.text.TextUtils;
 import android.util.Log;
 
+import com.android.compatibility.common.util.BatteryUtils;
+
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
@@ -311,6 +315,10 @@
         return mSupported;
     }
 
+    protected boolean isBatterySaverSupported() {
+        return BatteryUtils.isBatterySaverSupported();
+    }
+
     /**
      * Asserts that an app always have access while on foreground or running a foreground service.
      *
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 74875cd..b1a2186 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
@@ -71,6 +71,11 @@
      * Tests all DS ON and BS ON scenarios from network-policy-restrictions.md on metered networks.
      */
     public void testDataAndBatterySaverModes_meteredNetwork() throws Exception {
+        if (!isBatterySaverSupported()) {
+            Log.i(TAG, "Skipping " + getClass() + "." + getName()
+                    + "() because device does not support Battery saver mode");
+            return;
+        }
         if (!isSupported()) return;
 
         Log.i(TAG, "testDataAndBatterySaverModes_meteredNetwork() tests");
@@ -141,6 +146,11 @@
      * networks.
      */
     public void testDataAndBatterySaverModes_nonMeteredNetwork() throws Exception {
+        if (!isBatterySaverSupported()) {
+            Log.i(TAG, "Skipping " + getClass() + "." + getName()
+                    + "() because device does not support Battery saver mode");
+            return;
+        }
         if (!isSupported()) return;
 
         if (!setUnmeteredNetwork()) {
@@ -206,6 +216,11 @@
      * are enabled.
      */
     public void testDozeAndBatterySaverMode_powerSaveWhitelists() throws Exception {
+        if (!isBatterySaverSupported()) {
+            Log.i(TAG, "Skipping " + getClass() + "." + getName()
+                    + "() because device does not support Battery saver mode");
+            return;
+        }
         if (!isSupported()) {
             return;
         }
@@ -285,6 +300,11 @@
     }
 
     public void testAppIdleAndBatterySaver_tempPowerSaveWhitelists() throws Exception {
+        if (!isBatterySaverSupported()) {
+            Log.i(TAG, "Skipping " + getClass() + "." + getName()
+                    + "() because device does not support Battery saver mode");
+            return;
+        }
         if (!isSupported()) {
             return;
         }
@@ -361,6 +381,11 @@
     }
 
     public void testAppIdleAndBatterySaver_tempPowerSaveAndAppIdleWhitelists() throws Exception {
+        if (!isBatterySaverSupported()) {
+            Log.i(TAG, "Skipping " + getClass() + "." + getName()
+                    + "() because device does not support Battery saver mode");
+            return;
+        }
         if (!isSupported()) {
             return;
         }
diff --git a/tests/cts/net/AndroidTest.xml b/tests/cts/net/AndroidTest.xml
index 1807a6b..3ff019e 100644
--- a/tests/cts/net/AndroidTest.xml
+++ b/tests/cts/net/AndroidTest.xml
@@ -18,6 +18,7 @@
     <option name="config-descriptor:metadata" key="token" value="SIM_CARD" />
     <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
     <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
     <option name="not-shardable" value="true" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index 8c9bf6e..ca1f771 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -35,6 +35,7 @@
 
 import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
 
+import android.annotation.NonNull;
 import android.app.Instrumentation;
 import android.app.PendingIntent;
 import android.app.UiAutomation;
@@ -43,6 +44,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
+import android.content.res.Resources;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
 import android.net.IpSecManager;
@@ -59,6 +61,7 @@
 import android.net.cts.util.CtsNetUtils;
 import android.net.util.KeepaliveUtils;
 import android.net.wifi.WifiManager;
+import android.os.Build;
 import android.os.Looper;
 import android.os.MessageQueue;
 import android.os.SystemClock;
@@ -73,9 +76,6 @@
 
 import androidx.test.InstrumentationRegistry;
 
-import com.android.internal.R;
-import com.android.internal.telephony.PhoneConstants;
-
 import libcore.io.Streams;
 
 import java.io.FileDescriptor;
@@ -99,6 +99,7 @@
 import java.util.concurrent.Executor;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Supplier;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -113,6 +114,8 @@
     private static final int CONNECT_TIMEOUT_MS = 2000;
     private static final int KEEPALIVE_CALLBACK_TIMEOUT_MS = 2000;
     private static final int KEEPALIVE_SOCKET_TIMEOUT_MS = 5000;
+    private static final int INTERVAL_KEEPALIVE_RETRY_MS = 500;
+    private static final int MAX_KEEPALIVE_RETRY_COUNT = 3;
     private static final int MIN_KEEPALIVE_INTERVAL = 10;
     private static final int NETWORK_CHANGE_METEREDNESS_TIMEOUT = 5000;
     private static final int NUM_TRIES_MULTIPATH_PREF_CHECK = 20;
@@ -120,6 +123,17 @@
     // device could have only one interface: data, wifi.
     private static final int MIN_NUM_NETWORK_TYPES = 1;
 
+    // Minimum supported keepalive counts for wifi and cellular.
+    public static final int MIN_SUPPORTED_CELLULAR_KEEPALIVE_COUNT = 1;
+    public static final int MIN_SUPPORTED_WIFI_KEEPALIVE_COUNT = 3;
+
+    private static final String NETWORK_METERED_MULTIPATH_PREFERENCE_RES_NAME =
+            "config_networkMeteredMultipathPreference";
+    private static final String KEEPALIVE_ALLOWED_UNPRIVILEGED_RES_NAME =
+            "config_allowedUnprivilegedKeepalivePerUid";
+    private static final String KEEPALIVE_RESERVED_PER_SLOT_RES_NAME =
+            "config_reservedPrivilegedKeepaliveSlots";
+
     private Context mContext;
     private Instrumentation mInstrumentation;
     private ConnectivityManager mCm;
@@ -367,9 +381,6 @@
 
         final String invalidateFeature = "invalidateFeature";
         final String mmsFeature = "enableMMS";
-        final int failureCode = -1;
-        final int wifiOnlyStartFailureCode = PhoneConstants.APN_REQUEST_FAILED;
-        final int wifiOnlyStopFailureCode = -1;
 
         assertStartUsingNetworkFeatureUnsupported(TYPE_MOBILE, invalidateFeature);
         assertStopUsingNetworkFeatureUnsupported(TYPE_MOBILE, invalidateFeature);
@@ -663,7 +674,7 @@
         final String rawMeteredPref = Settings.Global.getString(resolver,
                 NETWORK_METERED_MULTIPATH_PREFERENCE);
         return TextUtils.isEmpty(rawMeteredPref)
-            ? mContext.getResources().getInteger(R.integer.config_networkMeteredMultipathPreference)
+            ? getIntResourceForName(NETWORK_METERED_MULTIPATH_PREFERENCE_RES_NAME)
             : Integer.parseInt(rawMeteredPref);
     }
 
@@ -839,8 +850,7 @@
         return s;
     }
 
-    private int getSupportedKeepalivesFromRes() throws Exception {
-        final Network network = ensureWifiConnected();
+    private int getSupportedKeepalivesForNet(@NonNull Network network) throws Exception {
         final NetworkCapabilities nc = mCm.getNetworkCapabilities(network);
 
         // Get number of supported concurrent keepalives for testing network.
@@ -914,34 +924,46 @@
      * keepalives is set to 0.
      */
     @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
-    public void testKeepaliveUnsupported() throws Exception {
-        if (getSupportedKeepalivesFromRes() != 0) return;
+    public void testKeepaliveWifiUnsupported() throws Exception {
+        if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
+            Log.i(TAG, "testKeepaliveUnsupported cannot execute unless device"
+                    + " supports WiFi");
+            return;
+        }
+
+        final Network network = ensureWifiConnected();
+        if (getSupportedKeepalivesForNet(network) != 0) return;
 
         adoptShellPermissionIdentity();
 
-        assertEquals(0, createConcurrentSocketKeepalives(1, 0));
-        assertEquals(0, createConcurrentSocketKeepalives(0, 1));
+        assertEquals(0, createConcurrentSocketKeepalives(network, 1, 0));
+        assertEquals(0, createConcurrentSocketKeepalives(network, 0, 1));
 
         dropShellPermissionIdentity();
     }
 
     @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
     public void testCreateTcpKeepalive() throws Exception {
+        if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
+            Log.i(TAG, "testCreateTcpKeepalive cannot execute unless device supports WiFi");
+            return;
+        }
+
         adoptShellPermissionIdentity();
 
-        if (getSupportedKeepalivesFromRes() == 0) return;
+        final Network network = ensureWifiConnected();
+        if (getSupportedKeepalivesForNet(network) == 0) return;
         // If kernel < 4.8 then it doesn't support TCP keepalive, but it might still support
         // NAT-T keepalive. If keepalive limits from resource overlay is not zero, TCP keepalive
         // needs to be supported except if the kernel doesn't support it.
         if (!isTcpKeepaliveSupportedByKernel()) {
             // Sanity check to ensure the callback result is expected.
-            assertEquals(0, createConcurrentSocketKeepalives(0, 1));
+            assertEquals(0, createConcurrentSocketKeepalives(network, 0, 1));
             Log.i(TAG, "testCreateTcpKeepalive is skipped for kernel "
                     + VintfRuntimeInfo.getKernelVersion());
             return;
         }
 
-        final Network network = ensureWifiConnected();
         final byte[] requestBytes = CtsNetUtils.HTTP_REQUEST.getBytes("UTF-8");
         // So far only ipv4 tcp keepalive offload is supported.
         // TODO: add test case for ipv6 tcp keepalive offload when it is supported.
@@ -1007,80 +1029,102 @@
         }
     }
 
-    /**
-     * Creates concurrent keepalives until the specified counts of each type of keepalives are
-     * reached or the expected error callbacks are received for each type of keepalives.
-     *
-     * @return the total number of keepalives created.
-     */
-    private int createConcurrentSocketKeepalives(int nattCount, int tcpCount) throws Exception {
-        final Network network = ensureWifiConnected();
-
+    private ArrayList<SocketKeepalive> createConcurrentKeepalivesOfType(
+            int requestCount, @NonNull TestSocketKeepaliveCallback callback,
+            Supplier<SocketKeepalive> kaFactory) {
         final ArrayList<SocketKeepalive> kalist = new ArrayList<>();
-        final TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback();
-        final Executor executor = mContext.getMainExecutor();
 
-        // Create concurrent TCP keepalives.
-        for (int i = 0; i < tcpCount; i++) {
-            // Assert that TCP connections can be established on wifi. The file descriptor of tcp
-            // sockets will be duplicated and kept valid in service side if the keepalives are
-            // successfully started.
-            try (Socket tcpSocket = getConnectedSocket(network, TEST_HOST, HTTP_PORT,
-                        0 /* Unused */, AF_INET)) {
-                final SocketKeepalive ka = mCm.createSocketKeepalive(network, tcpSocket, executor,
-                        callback);
-                ka.start(MIN_KEEPALIVE_INTERVAL);
-                TestSocketKeepaliveCallback.CallbackValue cv = callback.pollCallback();
-                assertNotNull(cv);
-                if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_ERROR) {
-                    if (i == 0 && cv.error == SocketKeepalive.ERROR_UNSUPPORTED) {
-                        // Unsupported.
-                        break;
-                    } else if (i != 0 && cv.error == SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES) {
-                        // Limit reached.
-                        break;
-                    }
-                }
-                if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_STARTED) {
-                    kalist.add(ka);
-                } else {
-                    fail("Unexpected error when creating " + (i + 1) + " TCP keepalives: " + cv);
-                }
-            }
-        }
+        int remainingRetries = MAX_KEEPALIVE_RETRY_COUNT;
 
-        // Assert that a Nat-T socket can be created.
-        final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE);
-        final UdpEncapsulationSocket nattSocket = mIpSec.openUdpEncapsulationSocket();
-
-        final InetAddress srcAddr = getFirstV4Address(network);
-        final InetAddress dstAddr = getAddrByName(TEST_HOST, AF_INET);
-        assertNotNull(srcAddr);
-        assertNotNull(dstAddr);
-
-        // Test concurrent Nat-T keepalives.
-        for (int i = 0; i < nattCount; i++) {
-            final SocketKeepalive ka = mCm.createSocketKeepalive(network, nattSocket,
-                    srcAddr, dstAddr, executor, callback);
+        // Test concurrent keepalives with the given supplier.
+        while (kalist.size() < requestCount) {
+            final SocketKeepalive ka = kaFactory.get();
             ka.start(MIN_KEEPALIVE_INTERVAL);
             TestSocketKeepaliveCallback.CallbackValue cv = callback.pollCallback();
             assertNotNull(cv);
             if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_ERROR) {
-                if (i == 0 && cv.error == SocketKeepalive.ERROR_UNSUPPORTED) {
+                if (kalist.size() == 0 && cv.error == SocketKeepalive.ERROR_UNSUPPORTED) {
                     // Unsupported.
                     break;
-                } else if (i != 0 && cv.error == SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES) {
-                    // Limit reached.
+                } else if (cv.error == SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES) {
+                    // Limit reached or temporary unavailable due to stopped slot is not yet
+                    // released.
+                    if (remainingRetries > 0) {
+                        SystemClock.sleep(INTERVAL_KEEPALIVE_RETRY_MS);
+                        remainingRetries--;
+                        continue;
+                    }
                     break;
                 }
             }
             if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_STARTED) {
                 kalist.add(ka);
             } else {
-                fail("Unexpected error when creating " + (i + 1) + " Nat-T keepalives: " + cv);
+                fail("Unexpected error when creating " + (kalist.size() + 1) + " "
+                        + ka.getClass().getSimpleName() + ": " + cv);
             }
         }
 
+        return kalist;
+    }
+
+    private @NonNull ArrayList<SocketKeepalive> createConcurrentNattSocketKeepalives(
+            @NonNull Network network, int requestCount,
+            @NonNull TestSocketKeepaliveCallback callback)  throws Exception {
+
+        final Executor executor = mContext.getMainExecutor();
+
+        // Initialize a real NaT-T socket.
+        final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE);
+        final UdpEncapsulationSocket nattSocket = mIpSec.openUdpEncapsulationSocket();
+        final InetAddress srcAddr = getFirstV4Address(network);
+        final InetAddress dstAddr = getAddrByName(TEST_HOST, AF_INET);
+        assertNotNull(srcAddr);
+        assertNotNull(dstAddr);
+
+        // Test concurrent Nat-T keepalives.
+        final ArrayList<SocketKeepalive> result = createConcurrentKeepalivesOfType(requestCount,
+                callback, () -> mCm.createSocketKeepalive(network, nattSocket,
+                        srcAddr, dstAddr, executor, callback));
+
+        nattSocket.close();
+        return result;
+    }
+
+    private @NonNull ArrayList<SocketKeepalive> createConcurrentTcpSocketKeepalives(
+            @NonNull Network network, int requestCount,
+            @NonNull TestSocketKeepaliveCallback callback) {
+        final Executor executor = mContext.getMainExecutor();
+
+        // Create concurrent TCP keepalives.
+        return createConcurrentKeepalivesOfType(requestCount, callback, () -> {
+            // Assert that TCP connections can be established. The file descriptor of tcp
+            // sockets will be duplicated and kept valid in service side if the keepalives are
+            // successfully started.
+            try (Socket tcpSocket = getConnectedSocket(network, TEST_HOST, HTTP_PORT,
+                    0 /* Unused */, AF_INET)) {
+                return mCm.createSocketKeepalive(network, tcpSocket, executor, callback);
+            } catch (Exception e) {
+                fail("Unexpected error when creating TCP socket: " + e);
+            }
+            return null;
+        });
+    }
+
+    /**
+     * Creates concurrent keepalives until the specified counts of each type of keepalives are
+     * reached or the expected error callbacks are received for each type of keepalives.
+     *
+     * @return the total number of keepalives created.
+     */
+    private int createConcurrentSocketKeepalives(
+            @NonNull Network network, int nattCount, int tcpCount) throws Exception {
+        final ArrayList<SocketKeepalive> kalist = new ArrayList<>();
+        final TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback();
+
+        kalist.addAll(createConcurrentNattSocketKeepalives(network, nattCount, callback));
+        kalist.addAll(createConcurrentTcpSocketKeepalives(network, tcpCount, callback));
+
         final int ret = kalist.size();
 
         // Clean up.
@@ -1089,7 +1133,6 @@
             callback.expectStopped();
         }
         kalist.clear();
-        nattSocket.close();
 
         return ret;
     }
@@ -1099,8 +1142,15 @@
      * get leaked after iterations.
      */
     @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
-    public void testSocketKeepaliveLimit() throws Exception {
-        final int supported = getSupportedKeepalivesFromRes();
+    public void testSocketKeepaliveLimitWifi() throws Exception {
+        if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
+            Log.i(TAG, "testSocketKeepaliveLimitWifi cannot execute unless device"
+                    + " supports WiFi");
+            return;
+        }
+
+        final Network network = ensureWifiConnected();
+        final int supported = getSupportedKeepalivesForNet(network);
         if (supported == 0) {
             return;
         }
@@ -1108,25 +1158,25 @@
         adoptShellPermissionIdentity();
 
         // Verifies that the supported keepalive slots meet MIN_SUPPORTED_KEEPALIVE_COUNT.
-        assertGreaterOrEqual(supported, KeepaliveUtils.MIN_SUPPORTED_KEEPALIVE_COUNT);
+        assertGreaterOrEqual(supported, MIN_SUPPORTED_WIFI_KEEPALIVE_COUNT);
 
         // Verifies that Nat-T keepalives can be established.
-        assertEquals(supported, createConcurrentSocketKeepalives(supported + 1, 0));
+        assertEquals(supported, createConcurrentSocketKeepalives(network, supported + 1, 0));
         // Verifies that keepalives don't get leaked in second round.
-        assertEquals(supported, createConcurrentSocketKeepalives(supported + 1, 0));
+        assertEquals(supported, createConcurrentSocketKeepalives(network, supported, 0));
 
         // If kernel < 4.8 then it doesn't support TCP keepalive, but it might still support
         // NAT-T keepalive. Test below cases only if TCP keepalive is supported by kernel.
         if (isTcpKeepaliveSupportedByKernel()) {
-            assertEquals(supported, createConcurrentSocketKeepalives(0, supported + 1));
+            assertEquals(supported, createConcurrentSocketKeepalives(network, 0, supported + 1));
 
             // Verifies that different types can be established at the same time.
-            assertEquals(supported, createConcurrentSocketKeepalives(
+            assertEquals(supported, createConcurrentSocketKeepalives(network,
                     supported / 2, supported - supported / 2));
 
             // Verifies that keepalives don't get leaked in second round.
-            assertEquals(supported, createConcurrentSocketKeepalives(0, supported + 1));
-            assertEquals(supported, createConcurrentSocketKeepalives(
+            assertEquals(supported, createConcurrentSocketKeepalives(network, 0, supported));
+            assertEquals(supported, createConcurrentSocketKeepalives(network,
                     supported / 2, supported - supported / 2));
         }
 
@@ -1134,19 +1184,69 @@
     }
 
     /**
+     * Verifies that the concurrent keepalive slots meet the minimum telephony requirement, and
+     * don't get leaked after iterations.
+     */
+    @AppModeFull(reason = "Cannot request network in instant app mode")
+    public void testSocketKeepaliveLimitTelephony() throws Exception {
+        if (!mPackageManager.hasSystemFeature(FEATURE_TELEPHONY)) {
+            Log.i(TAG, "testSocketKeepaliveLimitTelephony cannot execute unless device"
+                    + " supports telephony");
+            return;
+        }
+
+        final int firstSdk = Build.VERSION.FIRST_SDK_INT;
+        if (firstSdk < Build.VERSION_CODES.Q) {
+            Log.i(TAG, "testSocketKeepaliveLimitTelephony: skip test for devices launching"
+                    + " before Q: " + firstSdk);
+            return;
+        }
+
+        final Network network = mCtsNetUtils.connectToCell();
+        final int supported = getSupportedKeepalivesForNet(network);
+
+        adoptShellPermissionIdentity();
+
+        // Verifies that the supported keepalive slots meet minimum requirement.
+        assertGreaterOrEqual(supported, MIN_SUPPORTED_CELLULAR_KEEPALIVE_COUNT);
+
+        // Verifies that Nat-T keepalives can be established.
+        assertEquals(supported, createConcurrentSocketKeepalives(network, supported + 1, 0));
+        // Verifies that keepalives don't get leaked in second round.
+        assertEquals(supported, createConcurrentSocketKeepalives(network, supported, 0));
+
+        dropShellPermissionIdentity();
+    }
+
+    private int getIntResourceForName(@NonNull String resName) {
+        final Resources r = mContext.getResources();
+        final int resId = r.getIdentifier(resName, "integer", "android");
+        return r.getInteger(resId);
+    }
+
+    /**
      * Verifies that the keepalive slots are limited as customized for unprivileged requests.
      */
     @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
     public void testSocketKeepaliveUnprivileged() throws Exception {
-        final int supported = getSupportedKeepalivesFromRes();
+        if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
+            Log.i(TAG, "testSocketKeepaliveUnprivileged cannot execute unless device"
+                    + " supports WiFi");
+            return;
+        }
+
+        final Network network = ensureWifiConnected();
+        final int supported = getSupportedKeepalivesForNet(network);
         if (supported == 0) {
             return;
         }
 
-        final int allowedUnprivilegedPerUid = mContext.getResources().getInteger(
-                R.integer.config_allowedUnprivilegedKeepalivePerUid);
-        final int reservedPrivilegedSlots = mContext.getResources().getInteger(
-                R.integer.config_reservedPrivilegedKeepaliveSlots);
+        // Resource ID might be shifted on devices that compiled with different symbols.
+        // Thus, resolve ID at runtime is needed.
+        final int allowedUnprivilegedPerUid =
+                getIntResourceForName(KEEPALIVE_ALLOWED_UNPRIVILEGED_RES_NAME);
+        final int reservedPrivilegedSlots =
+                getIntResourceForName(KEEPALIVE_RESERVED_PER_SLOT_RES_NAME);
         // Verifies that unprivileged request per uid cannot exceed the limit customized in the
         // resource. Currently, unprivileged keepalive slots are limited to Nat-T only, this test
         // does not apply to TCP.
@@ -1154,7 +1254,8 @@
         assertGreaterOrEqual(supported, allowedUnprivilegedPerUid);
         final int expectedUnprivileged =
                 Math.min(allowedUnprivilegedPerUid, supported - reservedPrivilegedSlots);
-        assertEquals(expectedUnprivileged, createConcurrentSocketKeepalives(supported + 1, 0));
+        assertEquals(expectedUnprivileged,
+                createConcurrentSocketKeepalives(network, supported + 1, 0));
     }
 
     private static void assertGreaterOrEqual(long greater, long lesser) {
diff --git a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java
index 01ac3fd..cbe54f8 100644
--- a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java
+++ b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java
@@ -16,135 +16,333 @@
 
 package android.net.cts;
 
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-
-import javax.net.SocketFactory;
-import javax.net.ssl.SSLPeerUnverifiedException;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import android.net.SSLCertificateSocketFactory;
 import android.platform.test.annotations.AppModeFull;
-import android.test.AndroidTestCase;
-
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
 import libcore.javax.net.ssl.SSLConfigurationAsserts;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
 
-public class SSLCertificateSocketFactoryTest extends AndroidTestCase {
-    private SSLCertificateSocketFactory mFactory;
-    private int mTimeout;
+@RunWith(JUnit4.class)
+public class SSLCertificateSocketFactoryTest {
+    // TEST_HOST should point to a web server with a valid TLS certificate.
+    private static final String TEST_HOST = "www.google.com";
+    private static final int HTTPS_PORT = 443;
+    private HostnameVerifier mDefaultVerifier;
+    private SSLCertificateSocketFactory mSocketFactory;
+    private InetAddress mLocalAddress;
+    // InetAddress obtained by resolving TEST_HOST.
+    private InetAddress mTestHostAddress;
+    // SocketAddress combining mTestHostAddress and HTTPS_PORT.
+    private List<SocketAddress> mTestSocketAddresses;
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mTimeout = 1000;
-        mFactory = (SSLCertificateSocketFactory) SSLCertificateSocketFactory.getDefault(mTimeout);
+    @Before
+    public void setUp() {
+        // Expected state before each test method is that
+        // HttpsURLConnection.getDefaultHostnameVerifier() will return the system default.
+        mDefaultVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
+        mSocketFactory = (SSLCertificateSocketFactory)
+            SSLCertificateSocketFactory.getDefault(1000 /* handshakeTimeoutMillis */);
+        assertNotNull(mSocketFactory);
+        InetAddress[] addresses;
+        try {
+            addresses = InetAddress.getAllByName(TEST_HOST);
+            mTestHostAddress = addresses[0];
+        } catch (UnknownHostException uhe) {
+            throw new AssertionError(
+                "Unable to test SSLCertificateSocketFactory: cannot resolve " + TEST_HOST, uhe);
+        }
+
+        mTestSocketAddresses = Arrays.stream(addresses)
+            .map(addr -> new InetSocketAddress(addr, HTTPS_PORT))
+            .collect(Collectors.toList());
+
+        // Find the local IP address which will be used to connect to TEST_HOST.
+        try {
+            Socket testSocket = new Socket(TEST_HOST, HTTPS_PORT);
+            mLocalAddress = testSocket.getLocalAddress();
+            testSocket.close();
+        } catch (IOException ioe) {
+            throw new AssertionError(""
+                + "Unable to test SSLCertificateSocketFactory: cannot connect to "
+                + TEST_HOST, ioe);
+        }
     }
 
+    // Restore the system default hostname verifier after each test.
+    @After
+    public void restoreDefaultHostnameVerifier() {
+        HttpsURLConnection.setDefaultHostnameVerifier(mDefaultVerifier);
+    }
+
+    @Test
     public void testDefaultConfiguration() throws Exception {
-        SSLConfigurationAsserts.assertSSLSocketFactoryDefaultConfiguration(mFactory);
+        SSLConfigurationAsserts.assertSSLSocketFactoryDefaultConfiguration(mSocketFactory);
     }
 
-    public void testAccessProperties() throws Exception {
-        mFactory.getSupportedCipherSuites();
-        mFactory.getDefaultCipherSuites();
-        SocketFactory sf = SSLCertificateSocketFactory.getDefault(mTimeout);
-        assertNotNull(sf);
+    @Test
+    public void testAccessProperties() {
+        mSocketFactory.getSupportedCipherSuites();
+        mSocketFactory.getDefaultCipherSuites();
     }
 
-    public void testCreateSocket() throws Exception {
-        new SSLCertificateSocketFactory(100);
-        int port = 443;
-        String host = "www.google.com";
-        InetAddress inetAddress = null;
-        inetAddress = InetAddress.getLocalHost();
+    /**
+     * Tests the {@code createSocket()} cases which are expected to fail with {@code IOException}.
+     */
+    @Test
+    @AppModeFull(reason = "Socket cannot bind in instant app mode")
+    public void createSocket_io_error_expected() {
+        // Connect to the localhost HTTPS port. Should result in connection refused IOException
+        // because no service should be listening on that port.
+        InetAddress localhostAddress = InetAddress.getLoopbackAddress();
         try {
-            mFactory.createSocket(inetAddress, port);
-            fail("should throw exception!");
+            mSocketFactory.createSocket(localhostAddress, HTTPS_PORT);
+            fail();
         } catch (IOException e) {
             // expected
         }
 
+        // Same, but also binding to a local address.
         try {
-            InetAddress inetAddress1 = InetAddress.getLocalHost();
-            InetAddress inetAddress2 = InetAddress.getLocalHost();
-            mFactory.createSocket(inetAddress1, port, inetAddress2, port);
-            fail("should throw exception!");
+            mSocketFactory.createSocket(localhostAddress, HTTPS_PORT, localhostAddress, 0);
+            fail();
         } catch (IOException e) {
             // expected
         }
 
+        // Same, wrapping an existing plain socket which is in an unconnected state.
         try {
             Socket socket = new Socket();
-            mFactory.createSocket(socket, host, port, true);
-            fail("should throw exception!");
+            mSocketFactory.createSocket(socket, "localhost", HTTPS_PORT, true);
+            fail();
         } catch (IOException e) {
             // expected
         }
-        Socket socket = null;
-        socket = mFactory.createSocket(host, port);
+    }
+
+    /**
+     * Tests hostname verification for
+     * {@link SSLCertificateSocketFactory#createSocket(String, int)}.
+     *
+     * <p>This method should return a socket which is fully connected (i.e. TLS handshake complete)
+     * and whose peer TLS certificate has been verified to have the correct hostname.
+     *
+     * <p>{@link SSLCertificateSocketFactory} is documented to verify hostnames using
+     * the {@link HostnameVerifier} returned by
+     * {@link HttpsURLConnection#getDefaultHostnameVerifier}, so this test connects twice,
+     * once with the system default {@link HostnameVerifier} which is expected to succeed,
+     * and once after installing a {@link NegativeHostnameVerifier} which will cause
+     * {@link SSLCertificateSocketFactory#verifyHostname} to throw a
+     * {@link SSLPeerUnverifiedException}.
+     *
+     * <p>These tests only test the hostname verification logic in SSLCertificateSocketFactory,
+     * other TLS failure modes and the default HostnameVerifier are tested elsewhere, see
+     * {@link com.squareup.okhttp.internal.tls.HostnameVerifierTest} and
+     * https://android.googlesource.com/platform/external/boringssl/+/refs/heads/master/src/ssl/test
+     *
+     * <p>Tests the following behaviour:-
+     * <ul>
+     * <li>TEST_SERVER is available and has a valid TLS certificate
+     * <li>{@code createSocket()} verifies the remote hostname is correct using
+     *     {@link HttpsURLConnection#getDefaultHostnameVerifier}
+     * <li>{@link SSLPeerUnverifiedException} is thrown when the remote hostname is invalid
+     * </ul>
+     *
+     * <p>See also http://b/2807618.
+     */
+    @Test
+    public void createSocket_simple_with_hostname_verification() throws Exception {
+        Socket socket = mSocketFactory.createSocket(TEST_HOST, HTTPS_PORT);
+        assertConnectedSocket(socket);
+        socket.close();
+
+        HttpsURLConnection.setDefaultHostnameVerifier(new NegativeHostnameVerifier());
+        try {
+            mSocketFactory.createSocket(TEST_HOST, HTTPS_PORT);
+            fail();
+        } catch (SSLPeerUnverifiedException expected) {
+            // expected
+        }
+    }
+
+    /**
+     * Tests hostname verification for
+     * {@link SSLCertificateSocketFactory#createSocket(Socket, String, int, boolean)}.
+     *
+     * <p>This method should return a socket which is fully connected (i.e. TLS handshake complete)
+     * and whose peer TLS certificate has been verified to have the correct hostname.
+     *
+     * <p>The TLS socket returned is wrapped around the plain socket passed into
+     * {@code createSocket()}.
+     *
+     * <p>See {@link #createSocket_simple_with_hostname_verification()} for test methodology.
+     */
+    @Test
+    public void createSocket_wrapped_with_hostname_verification() throws Exception {
+        Socket underlying = new Socket(TEST_HOST, HTTPS_PORT);
+        Socket socket = mSocketFactory.createSocket(underlying, TEST_HOST, HTTPS_PORT, true);
+        assertConnectedSocket(socket);
+        socket.close();
+
+        HttpsURLConnection.setDefaultHostnameVerifier(new NegativeHostnameVerifier());
+        try {
+            underlying = new Socket(TEST_HOST, HTTPS_PORT);
+            mSocketFactory.createSocket(underlying, TEST_HOST, HTTPS_PORT, true);
+            fail();
+        } catch (SSLPeerUnverifiedException expected) {
+            // expected
+        }
+    }
+
+    /**
+     * Tests hostname verification for
+     * {@link SSLCertificateSocketFactory#createSocket(String, int, InetAddress, int)}.
+     *
+     * <p>This method should return a socket which is fully connected (i.e. TLS handshake complete)
+     * and whose peer TLS certificate has been verified to have the correct hostname.
+     *
+     * <p>The TLS socket returned is also bound to the local address determined in {@link #setUp} to
+     * be used for connections to TEST_HOST, and a wildcard port.
+     *
+     * <p>See {@link #createSocket_simple_with_hostname_verification()} for test methodology.
+     */
+    @Test
+    @AppModeFull(reason = "Socket cannot bind in instant app mode")
+    public void createSocket_bound_with_hostname_verification() throws Exception {
+        Socket socket = mSocketFactory.createSocket(TEST_HOST, HTTPS_PORT, mLocalAddress, 0);
+        assertConnectedSocket(socket);
+        socket.close();
+
+        HttpsURLConnection.setDefaultHostnameVerifier(new NegativeHostnameVerifier());
+        try {
+            mSocketFactory.createSocket(TEST_HOST, HTTPS_PORT, mLocalAddress, 0);
+            fail();
+        } catch (SSLPeerUnverifiedException expected) {
+            // expected
+        }
+    }
+
+    /**
+     * Tests hostname verification for
+     * {@link SSLCertificateSocketFactory#createSocket(InetAddress, int)}.
+     *
+     * <p>This method should return a socket which the documentation describes as "unconnected",
+     * which actually means that the socket is fully connected at the TCP layer but TLS handshaking
+     * and hostname verification have not yet taken place.
+     *
+     * <p>Behaviour is tested by installing a {@link NegativeHostnameVerifier} and by calling
+     * {@link #assertConnectedSocket} to ensure TLS handshaking but no hostname verification takes
+     * place.  Next, {@link SSLCertificateSocketFactory#verifyHostname} is called to ensure
+     * that hostname verification is using the {@link HostnameVerifier} returned by
+     * {@link HttpsURLConnection#getDefaultHostnameVerifier} as documented.
+     *
+     * <p>Tests the following behaviour:-
+     * <ul>
+     * <li>TEST_SERVER is available and has a valid TLS certificate
+     * <li>{@code createSocket()} does not verify the remote hostname
+     * <li>Calling {@link SSLCertificateSocketFactory#verifyHostname} on the returned socket
+     *     throws {@link SSLPeerUnverifiedException} if the remote hostname is invalid
+     * </ul>
+     */
+    @Test
+    public void createSocket_simple_no_hostname_verification() throws Exception{
+        HttpsURLConnection.setDefaultHostnameVerifier(new NegativeHostnameVerifier());
+        Socket socket = mSocketFactory.createSocket(mTestHostAddress, HTTPS_PORT);
+        // Need to provide the expected hostname here or the TLS handshake will
+        // be unable to supply SNI to the remote host.
+        mSocketFactory.setHostname(socket, TEST_HOST);
+        assertConnectedSocket(socket);
+        try {
+          SSLCertificateSocketFactory.verifyHostname(socket, TEST_HOST);
+          fail();
+        } catch (SSLPeerUnverifiedException expected) {
+            // expected
+        }
+        HttpsURLConnection.setDefaultHostnameVerifier(mDefaultVerifier);
+        SSLCertificateSocketFactory.verifyHostname(socket, TEST_HOST);
+        socket.close();
+    }
+
+    /**
+     * Tests hostname verification for
+     * {@link SSLCertificateSocketFactory#createSocket(InetAddress, int, InetAddress, int)}.
+     *
+     * <p>This method should return a socket which the documentation describes as "unconnected",
+     * which actually means that the socket is fully connected at the TCP layer but TLS handshaking
+     * and hostname verification have not yet taken place.
+     *
+     * <p>The TLS socket returned is also bound to the local address determined in {@link #setUp} to
+     * be used for connections to TEST_HOST, and a wildcard port.
+     *
+     * <p>See {@link #createSocket_simple_no_hostname_verification()} for test methodology.
+     */
+    @Test
+    @AppModeFull(reason = "Socket cannot bind in instant app mode")
+    public void createSocket_bound_no_hostname_verification() throws Exception{
+        HttpsURLConnection.setDefaultHostnameVerifier(new NegativeHostnameVerifier());
+        Socket socket =
+            mSocketFactory.createSocket(mTestHostAddress, HTTPS_PORT, mLocalAddress, 0);
+        // Need to provide the expected hostname here or the TLS handshake will
+        // be unable to supply SNI to the peer.
+        mSocketFactory.setHostname(socket, TEST_HOST);
+        assertConnectedSocket(socket);
+        try {
+          SSLCertificateSocketFactory.verifyHostname(socket, TEST_HOST);
+          fail();
+        } catch (SSLPeerUnverifiedException expected) {
+            // expected
+        }
+        HttpsURLConnection.setDefaultHostnameVerifier(mDefaultVerifier);
+        SSLCertificateSocketFactory.verifyHostname(socket, TEST_HOST);
+        socket.close();
+    }
+
+    /**
+     * Asserts a socket is fully connected to the expected peer.
+     *
+     * <p>For the variants of createSocket which verify the remote hostname,
+     * {@code socket} should already be fully connected.
+     *
+     * <p>For the non-verifying variants, retrieving the input stream will trigger a TLS handshake
+     * and so may throw an exception, for example if the peer's certificate is invalid.
+     *
+     * <p>Does no hostname verification.
+     */
+    private void assertConnectedSocket(Socket socket) throws Exception {
         assertNotNull(socket);
-        assertNotNull(socket.getOutputStream());
+        assertTrue(socket.isConnected());
         assertNotNull(socket.getInputStream());
-
-        // it throw exception when calling createSocket(String, int, InetAddress, int)
-        // The socket level is invalid.
-    }
-
-    // a host and port that are expected to be available but have
-    // a cert with a different CN, in this case CN=mail.google.com
-    private static String TEST_CREATE_SOCKET_HOST = "www3.l.google.com";
-    private static int TEST_CREATE_SOCKET_PORT = 443;
-
-    /**
-     * b/2807618 Make sure that hostname verifcation in cases were it
-     * is documented to be included by various
-     * SSLCertificateSocketFactory.createSocket messages.
-     *
-     * NOTE: Test will fail if external server is not available.
-     */
-    @AppModeFull(reason = "Socket cannot bind in instant app mode")
-    public void test_createSocket_simple() throws Exception {
-        try {
-            mFactory.createSocket(TEST_CREATE_SOCKET_HOST, TEST_CREATE_SOCKET_PORT);
-            fail();
-        } catch (SSLPeerUnverifiedException expected) {
-            // expected
-        }
+        assertNotNull(socket.getOutputStream());
+        assertTrue(mTestSocketAddresses.contains(socket.getRemoteSocketAddress()));
     }
 
     /**
-     * b/2807618 Make sure that hostname verifcation in cases were it
-     * is documented to be included by various
-     * SSLCertificateSocketFactory.createSocket messages.
-     *
-     * NOTE: Test will fail if external server is not available.
+     * A HostnameVerifier which always returns false to simulate a server returning a
+     * certificate which does not match the expected hostname.
      */
-    @AppModeFull(reason = "Socket cannot bind in instant app mode")
-    public void test_createSocket_wrapping() throws Exception {
-        try {
-            Socket underlying = new Socket(TEST_CREATE_SOCKET_HOST, TEST_CREATE_SOCKET_PORT);
-            mFactory.createSocket(
-                    underlying, TEST_CREATE_SOCKET_HOST, TEST_CREATE_SOCKET_PORT, true);
-            fail();
-        } catch (SSLPeerUnverifiedException expected) {
-            // expected
-        }
-    }
-
-    /**
-     * b/2807618 Make sure that hostname verifcation in cases were it
-     * is documented to be included by various
-     * SSLCertificateSocketFactory.createSocket messages.
-     *
-     * NOTE: Test will fail if external server is not available.
-     */
-    @AppModeFull(reason = "Socket cannot bind in instant app mode")
-    public void test_createSocket_bind() throws Exception {
-        try {
-            mFactory.createSocket(TEST_CREATE_SOCKET_HOST, TEST_CREATE_SOCKET_PORT, null, 0);
-            fail();
-        } catch (SSLPeerUnverifiedException expected) {
-            // expected
+    private static class NegativeHostnameVerifier implements HostnameVerifier {
+        @Override
+        public boolean verify(String hostname, SSLSession sslSession) {
+            return false;
         }
     }
 }
