diff --git a/tests/cts/hostside/Android.bp b/tests/cts/hostside/Android.bp
deleted file mode 100644
index 741c961..0000000
--- a/tests/cts/hostside/Android.bp
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (C) 2014 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.
-
-java_test_host {
-    name: "CtsHostsideNetworkTests",
-    defaults: ["cts_defaults"],
-    // Only compile source java files in this apk.
-    srcs: ["src/**/*.java"],
-    libs: [
-        "cts-tradefed",
-        "tradefed",
-    ],
-    // Tag this module as a cts test artifact
-    test_suites: [
-        "cts",
-        "vts10",
-        "general-tests",
-    ],
-}
diff --git a/tests/cts/hostside/AndroidTest.xml b/tests/cts/hostside/AndroidTest.xml
deleted file mode 100644
index b7fefaf..0000000
--- a/tests/cts/hostside/AndroidTest.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="Config for CTS net host test cases">
-    <option name="test-suite-tag" value="cts" />
-    <option name="config-descriptor:metadata" key="component" value="networking" />
-    <option name="config-descriptor:metadata" key="parameter" value="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.compatibility.common.tradefed.targetprep.LocationCheck" />
-    <target_preparer class="com.android.cts.net.NetworkPolicyTestsPreparer" />
-
-    <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" />
-        <option name="teardown-command" value="cmd netpolicy stop-watching" />
-    </target_preparer>
-
-    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
-        <option name="jar" value="CtsHostsideNetworkTests.jar" />
-        <option name="runtime-hint" value="3m56s" />
-    </test>
-
-    <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
-        <option name="directory-keys" value="/sdcard/CtsHostsideNetworkTests" />
-        <option name="collect-on-run-ended-only" value="true" />
-    </metrics_collector>
-</configuration>
diff --git a/tests/cts/hostside/OWNERS b/tests/cts/hostside/OWNERS
deleted file mode 100644
index 52c8053..0000000
--- a/tests/cts/hostside/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Bug component: 61373
-sudheersai@google.com
-lorenzo@google.com
-jchalard@google.com
diff --git a/tests/cts/hostside/aidl/Android.bp b/tests/cts/hostside/aidl/Android.bp
deleted file mode 100644
index 320a1fa..0000000
--- a/tests/cts/hostside/aidl/Android.bp
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (C) 2016 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.
-
-java_test_helper_library {
-    name: "CtsHostsideNetworkTestsAidl",
-    sdk_version: "current",
-    srcs: [
-        "com/android/cts/net/hostside/IMyService.aidl",
-        "com/android/cts/net/hostside/INetworkCallback.aidl",
-        "com/android/cts/net/hostside/INetworkStateObserver.aidl",
-        "com/android/cts/net/hostside/IRemoteSocketFactory.aidl",
-    ],
-}
diff --git a/tests/cts/hostside/aidl/com/android/cts/net/hostside/IMyService.aidl b/tests/cts/hostside/aidl/com/android/cts/net/hostside/IMyService.aidl
deleted file mode 100644
index 5aafdf0..0000000
--- a/tests/cts/hostside/aidl/com/android/cts/net/hostside/IMyService.aidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-import com.android.cts.net.hostside.INetworkCallback;
-
-interface IMyService {
-    void registerBroadcastReceiver();
-    int getCounters(String receiverName, String action);
-    String checkNetworkStatus();
-    String getRestrictBackgroundStatus();
-    void sendNotification(int notificationId, String notificationType);
-    void registerNetworkCallback(in INetworkCallback cb);
-    void unregisterNetworkCallback();
-}
diff --git a/tests/cts/hostside/aidl/com/android/cts/net/hostside/INetworkCallback.aidl b/tests/cts/hostside/aidl/com/android/cts/net/hostside/INetworkCallback.aidl
deleted file mode 100644
index 2048bab..0000000
--- a/tests/cts/hostside/aidl/com/android/cts/net/hostside/INetworkCallback.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-import android.net.Network;
-import android.net.NetworkCapabilities;
-
-interface INetworkCallback {
-    void onBlockedStatusChanged(in Network network, boolean blocked);
-    void onAvailable(in Network network);
-    void onLost(in Network network);
-    void onCapabilitiesChanged(in Network network, in NetworkCapabilities cap);
-}
diff --git a/tests/cts/hostside/aidl/com/android/cts/net/hostside/INetworkStateObserver.aidl b/tests/cts/hostside/aidl/com/android/cts/net/hostside/INetworkStateObserver.aidl
deleted file mode 100644
index 165f530..0000000
--- a/tests/cts/hostside/aidl/com/android/cts/net/hostside/INetworkStateObserver.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-interface INetworkStateObserver {
-    boolean isForeground();
-    void onNetworkStateChecked(String resultData);
-}
\ No newline at end of file
diff --git a/tests/cts/hostside/aidl/com/android/cts/net/hostside/IRemoteSocketFactory.aidl b/tests/cts/hostside/aidl/com/android/cts/net/hostside/IRemoteSocketFactory.aidl
deleted file mode 100644
index 68176ad..0000000
--- a/tests/cts/hostside/aidl/com/android/cts/net/hostside/IRemoteSocketFactory.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-import android.os.ParcelFileDescriptor;
-
-interface IRemoteSocketFactory {
-    ParcelFileDescriptor openSocketFd(String host, int port, int timeoutMs);
-    String getPackageName();
-    int getUid();
-}
diff --git a/tests/cts/hostside/app/Android.bp b/tests/cts/hostside/app/Android.bp
deleted file mode 100644
index e129be7..0000000
--- a/tests/cts/hostside/app/Android.bp
+++ /dev/null
@@ -1,41 +0,0 @@
-//
-// Copyright (C) 2014 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-android_test_helper_app {
-    name: "CtsHostsideNetworkTestsApp",
-    defaults: ["cts_support_defaults"],
-    //sdk_version: "current",
-    platform_apis: true,
-    static_libs: [
-        "androidx.test.rules",
-        "androidx.test.ext.junit",
-        "compatibility-device-util-axt",
-        "ctstestrunner-axt",
-        "ub-uiautomator",
-        "CtsHostsideNetworkTestsAidl",
-    ],
-    libs: [
-        "android.test.runner",
-        "android.test.base",
-    ],
-    srcs: ["src/**/*.java"],
-    // Tag this module as a cts test artifact
-    test_suites: [
-        "cts",
-        "vts10",
-        "general-tests",
-    ],
-}
diff --git a/tests/cts/hostside/app/AndroidManifest.xml b/tests/cts/hostside/app/AndroidManifest.xml
deleted file mode 100644
index 3940de4..0000000
--- a/tests/cts/hostside/app/AndroidManifest.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.net.hostside">
-
-    <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.ACCESS_FINE_LOCATION" />
-    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
-    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
-    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
-
-    <application android:requestLegacyExternalStorage="true" >
-        <uses-library android:name="android.test.runner" />
-        <activity android:name=".MyActivity" />
-        <service android:name=".MyVpnService"
-                android:permission="android.permission.BIND_VPN_SERVICE">
-            <intent-filter>
-                <action android:name="android.net.VpnService"/>
-            </intent-filter>
-        </service>
-        <service
-            android:name=".MyNotificationListenerService"
-            android:label="MyNotificationListenerService"
-            android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
-            <intent-filter>
-                <action android:name="android.service.notification.NotificationListenerService" />
-            </intent-filter>
-        </service>
-    </application>
-
-    <instrumentation
-        android:name="androidx.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.android.cts.net.hostside" />
-
-</manifest>
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
deleted file mode 100644
index 219cc3d..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-import static com.android.cts.net.hostside.Property.APP_STANDBY_MODE;
-import static com.android.cts.net.hostside.Property.BATTERY_SAVER_MODE;
-
-import static org.junit.Assert.assertEquals;
-
-import android.os.SystemClock;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Base class for metered and non-metered tests on idle apps.
- */
-@RequiredProperties({APP_STANDBY_MODE})
-abstract class AbstractAppIdleTestCase extends AbstractRestrictBackgroundNetworkTestCase {
-
-    @Before
-    public final void setUp() throws Exception {
-        super.setUp();
-
-        // Set initial state.
-        removePowerSaveModeWhitelist(TEST_APP2_PKG);
-        removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
-        setAppIdle(false);
-        turnBatteryOn();
-
-        registerBroadcastReceiver();
-    }
-
-    @After
-    public final void tearDown() throws Exception {
-        super.tearDown();
-
-        executeSilentShellCommand("cmd battery reset");
-        setAppIdle(false);
-    }
-
-    @Test
-    public void testBackgroundNetworkAccess_enabled() throws Exception {
-        setAppIdle(true);
-        assertBackgroundNetworkAccess(false);
-
-        assertsForegroundAlwaysHasNetworkAccess();
-        setAppIdle(true);
-        assertBackgroundNetworkAccess(false);
-
-        // Make sure foreground app doesn't lose access upon enabling it.
-        setAppIdle(true);
-        launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY);
-        finishActivity();
-        assertAppIdle(false); // Sanity check - not idle anymore, since activity was launched...
-        assertBackgroundNetworkAccess(true);
-        setAppIdle(true);
-        assertBackgroundNetworkAccess(false);
-
-        // Same for foreground service.
-        setAppIdle(true);
-        launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_FOREGROUND_SERVICE);
-        stopForegroundService();
-        assertAppIdle(true);
-        assertBackgroundNetworkAccess(false);
-    }
-
-    @Test
-    public void testBackgroundNetworkAccess_whitelisted() throws Exception {
-        setAppIdle(true);
-        assertBackgroundNetworkAccess(false);
-
-        addPowerSaveModeWhitelist(TEST_APP2_PKG);
-        assertAppIdle(false); // Sanity check - not idle anymore, since whitelisted
-        assertBackgroundNetworkAccess(true);
-
-        setAppIdleNoAssert(true);
-        assertAppIdle(false); // app is still whitelisted
-        removePowerSaveModeWhitelist(TEST_APP2_PKG);
-        assertAppIdle(true); // Sanity check - idle again, once whitelisted was removed
-        assertBackgroundNetworkAccess(false);
-
-        setAppIdle(true);
-        addPowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
-        assertAppIdle(false); // Sanity check - not idle anymore, since whitelisted
-        assertBackgroundNetworkAccess(true);
-
-        setAppIdleNoAssert(true);
-        assertAppIdle(false); // app is still whitelisted
-        removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
-        assertAppIdle(true); // Sanity check - idle again, once whitelisted was removed
-        assertBackgroundNetworkAccess(false);
-
-        assertsForegroundAlwaysHasNetworkAccess();
-
-        // Sanity check - no whitelist, no access!
-        setAppIdle(true);
-        assertBackgroundNetworkAccess(false);
-    }
-
-    @Test
-    public void testBackgroundNetworkAccess_tempWhitelisted() throws Exception {
-        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);
-    }
-
-    @Test
-    public void testBackgroundNetworkAccess_disabled() throws Exception {
-        assertBackgroundNetworkAccess(true);
-
-        assertsForegroundAlwaysHasNetworkAccess();
-        assertBackgroundNetworkAccess(true);
-    }
-
-    @RequiredProperties({BATTERY_SAVER_MODE})
-    @Test
-    public void testAppIdleNetworkAccess_whenCharging() throws Exception {
-        // Check that app is paroled when charging
-        setAppIdle(true);
-        assertBackgroundNetworkAccess(false);
-        turnBatteryOff();
-        assertBackgroundNetworkAccess(true);
-        turnBatteryOn();
-        assertBackgroundNetworkAccess(false);
-
-        // Check that app is restricted when not idle but power-save is on
-        setAppIdle(false);
-        assertBackgroundNetworkAccess(true);
-        setBatterySaverMode(true);
-        assertBackgroundNetworkAccess(false);
-        // Use setBatterySaverMode API to leave power-save mode instead of plugging in charger
-        setBatterySaverMode(false);
-        turnBatteryOff();
-        assertBackgroundNetworkAccess(true);
-
-        // And when no longer charging, it still has network access, since it's not idle
-        turnBatteryOn();
-        assertBackgroundNetworkAccess(true);
-    }
-
-    @Test
-    public void testAppIdleNetworkAccess_idleWhitelisted() throws Exception {
-        setAppIdle(true);
-        assertAppIdle(true);
-        assertBackgroundNetworkAccess(false);
-
-        addAppIdleWhitelist(mUid);
-        assertBackgroundNetworkAccess(true);
-
-        removeAppIdleWhitelist(mUid);
-        assertBackgroundNetworkAccess(false);
-
-        // Make sure whitelisting a random app doesn't affect the tested app.
-        addAppIdleWhitelist(mUid + 1);
-        assertBackgroundNetworkAccess(false);
-        removeAppIdleWhitelist(mUid + 1);
-    }
-
-    @Test
-    public void testAppIdle_toast() throws Exception {
-        setAppIdle(true);
-        assertAppIdle(true);
-        assertEquals("Shown", showToast());
-        assertAppIdle(true);
-        // Wait for a couple of seconds for the toast to actually be shown
-        SystemClock.sleep(2000);
-        assertAppIdle(true);
-    }
-}
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
deleted file mode 100644
index 04d054d..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-import static com.android.cts.net.hostside.Property.BATTERY_SAVER_MODE;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Base class for metered and non-metered Battery Saver Mode tests.
- */
-@RequiredProperties({BATTERY_SAVER_MODE})
-abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgroundNetworkTestCase {
-
-    @Before
-    public final void setUp() throws Exception {
-        super.setUp();
-
-        // Set initial state.
-        removePowerSaveModeWhitelist(TEST_APP2_PKG);
-        removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
-        setBatterySaverMode(false);
-
-        registerBroadcastReceiver();
-    }
-
-    @After
-    public final void tearDown() throws Exception {
-        super.tearDown();
-
-        setBatterySaverMode(false);
-    }
-
-    @Test
-    public void testBackgroundNetworkAccess_enabled() throws Exception {
-        setBatterySaverMode(true);
-        assertBackgroundNetworkAccess(false);
-
-        assertsForegroundAlwaysHasNetworkAccess();
-        assertBackgroundNetworkAccess(false);
-
-        // Make sure foreground app doesn't lose access upon Battery Saver.
-        setBatterySaverMode(false);
-        launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY);
-        setBatterySaverMode(true);
-        assertForegroundNetworkAccess();
-
-        // Although it should not have access while the screen is off.
-        turnScreenOff();
-        assertBackgroundNetworkAccess(false);
-        turnScreenOn();
-        assertForegroundNetworkAccess();
-
-        // Goes back to background state.
-        finishActivity();
-        assertBackgroundNetworkAccess(false);
-
-        // Make sure foreground service doesn't lose access upon enabling Battery Saver.
-        setBatterySaverMode(false);
-        launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_FOREGROUND_SERVICE);
-        setBatterySaverMode(true);
-        assertForegroundNetworkAccess();
-        stopForegroundService();
-        assertBackgroundNetworkAccess(false);
-    }
-
-    @Test
-    public void testBackgroundNetworkAccess_whitelisted() throws Exception {
-        setBatterySaverMode(true);
-        assertBackgroundNetworkAccess(false);
-
-        addPowerSaveModeWhitelist(TEST_APP2_PKG);
-        assertBackgroundNetworkAccess(true);
-
-        removePowerSaveModeWhitelist(TEST_APP2_PKG);
-        assertBackgroundNetworkAccess(false);
-
-        addPowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
-        assertBackgroundNetworkAccess(true);
-
-        removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
-        assertBackgroundNetworkAccess(false);
-
-        assertsForegroundAlwaysHasNetworkAccess();
-        assertBackgroundNetworkAccess(false);
-    }
-
-    @Test
-    public void testBackgroundNetworkAccess_disabled() throws Exception {
-        assertBackgroundNetworkAccess(true);
-
-        assertsForegroundAlwaysHasNetworkAccess();
-        assertBackgroundNetworkAccess(true);
-    }
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java
deleted file mode 100644
index 6f32c56..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-import static com.android.cts.net.hostside.Property.DOZE_MODE;
-import static com.android.cts.net.hostside.Property.NOT_LOW_RAM_DEVICE;
-
-import android.os.SystemClock;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Base class for metered and non-metered Doze Mode tests.
- */
-@RequiredProperties({DOZE_MODE})
-abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetworkTestCase {
-
-    @Before
-    public final void setUp() throws Exception {
-        super.setUp();
-
-        // Set initial state.
-        removePowerSaveModeWhitelist(TEST_APP2_PKG);
-        removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
-        setDozeMode(false);
-
-        registerBroadcastReceiver();
-    }
-
-    @After
-    public final void tearDown() throws Exception {
-        super.tearDown();
-
-        setDozeMode(false);
-    }
-
-    @Test
-    public void testBackgroundNetworkAccess_enabled() throws Exception {
-        setDozeMode(true);
-        assertBackgroundNetworkAccess(false);
-
-        assertsForegroundAlwaysHasNetworkAccess();
-        assertBackgroundNetworkAccess(false);
-
-        // Make sure foreground service doesn't lose network access upon enabling doze.
-        setDozeMode(false);
-        launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_FOREGROUND_SERVICE);
-        setDozeMode(true);
-        assertForegroundNetworkAccess();
-        stopForegroundService();
-        assertBackgroundState();
-        assertBackgroundNetworkAccess(false);
-    }
-
-    @Test
-    public void testBackgroundNetworkAccess_whitelisted() throws Exception {
-        setDozeMode(true);
-        assertBackgroundNetworkAccess(false);
-
-        addPowerSaveModeWhitelist(TEST_APP2_PKG);
-        assertBackgroundNetworkAccess(true);
-
-        removePowerSaveModeWhitelist(TEST_APP2_PKG);
-        assertBackgroundNetworkAccess(false);
-
-        addPowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
-        assertBackgroundNetworkAccess(false);
-
-        removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
-        assertBackgroundNetworkAccess(false);
-
-        assertsForegroundAlwaysHasNetworkAccess();
-        assertBackgroundNetworkAccess(false);
-    }
-
-    @Test
-    public void testBackgroundNetworkAccess_disabled() throws Exception {
-        assertBackgroundNetworkAccess(true);
-
-        assertsForegroundAlwaysHasNetworkAccess();
-        assertBackgroundNetworkAccess(true);
-    }
-
-    @RequiredProperties({NOT_LOW_RAM_DEVICE})
-    @Test
-    public void testBackgroundNetworkAccess_enabledButWhitelistedOnNotificationAction()
-            throws Exception {
-        setPendingIntentWhitelistDuration(NETWORK_TIMEOUT_MS);
-        try {
-            registerNotificationListenerService();
-            setDozeMode(true);
-            assertBackgroundNetworkAccess(false);
-
-            testNotification(4, NOTIFICATION_TYPE_CONTENT);
-            testNotification(8, NOTIFICATION_TYPE_DELETE);
-            testNotification(15, NOTIFICATION_TYPE_FULL_SCREEN);
-            testNotification(16, NOTIFICATION_TYPE_BUNDLE);
-            testNotification(23, NOTIFICATION_TYPE_ACTION);
-            testNotification(42, NOTIFICATION_TYPE_ACTION_BUNDLE);
-            testNotification(108, NOTIFICATION_TYPE_ACTION_REMOTE_INPUT);
-        } finally {
-            resetDeviceIdleSettings();
-        }
-    }
-
-    private void testNotification(int id, String type) throws Exception {
-        sendNotification(id, type);
-        assertBackgroundNetworkAccess(true);
-        if (type.equals(NOTIFICATION_TYPE_ACTION)) {
-            // Make sure access is disabled after it expires. Since this check considerably slows
-            // downs the CTS tests, do it just once.
-            SystemClock.sleep(NETWORK_TIMEOUT_MS);
-            assertBackgroundNetworkAccess(false);
-        }
-    }
-
-    // Must override so it only tests foreground service - once an app goes to foreground, device
-    // leaves Doze Mode.
-    @Override
-    protected void assertsForegroundAlwaysHasNetworkAccess() throws Exception {
-        launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_FOREGROUND_SERVICE);
-        stopForegroundService();
-        assertBackgroundState();
-    }
-}
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
deleted file mode 100644
index e5fd149..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
+++ /dev/null
@@ -1,881 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
-import static android.os.BatteryManager.BATTERY_PLUGGED_AC;
-import static android.os.BatteryManager.BATTERY_PLUGGED_USB;
-import static android.os.BatteryManager.BATTERY_PLUGGED_WIRELESS;
-
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.executeShellCommand;
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getConnectivityManager;
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getContext;
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getInstrumentation;
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getWifiManager;
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isDozeModeSupported;
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.restrictBackgroundValueToString;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.app.ActivityManager;
-import android.app.Instrumentation;
-import android.app.NotificationManager;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo.DetailedState;
-import android.net.NetworkInfo.State;
-import android.net.wifi.WifiManager;
-import android.os.BatteryManager;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.service.notification.NotificationListenerService;
-import android.util.Log;
-
-import org.junit.Rule;
-import org.junit.rules.RuleChain;
-import org.junit.runner.RunWith;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Superclass for tests related to background network restrictions.
- */
-@RunWith(NetworkPolicyTestRunner.class)
-public abstract class AbstractRestrictBackgroundNetworkTestCase {
-    public static final String TAG = "RestrictBackgroundNetworkTests";
-
-    protected static final String TEST_PKG = "com.android.cts.net.hostside";
-    protected static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2";
-
-    private static final String TEST_APP2_ACTIVITY_CLASS = TEST_APP2_PKG + ".MyActivity";
-    private static final String TEST_APP2_SERVICE_CLASS = TEST_APP2_PKG + ".MyForegroundService";
-
-    private static final int SLEEP_TIME_SEC = 1;
-
-    // Constants below must match values defined on app2's Common.java
-    private static final String MANIFEST_RECEIVER = "ManifestReceiver";
-    private static final String DYNAMIC_RECEIVER = "DynamicReceiver";
-
-    private static final String ACTION_RECEIVER_READY =
-            "com.android.cts.net.hostside.app2.action.RECEIVER_READY";
-    static final String ACTION_SHOW_TOAST =
-            "com.android.cts.net.hostside.app2.action.SHOW_TOAST";
-
-    protected static final String NOTIFICATION_TYPE_CONTENT = "CONTENT";
-    protected static final String NOTIFICATION_TYPE_DELETE = "DELETE";
-    protected static final String NOTIFICATION_TYPE_FULL_SCREEN = "FULL_SCREEN";
-    protected static final String NOTIFICATION_TYPE_BUNDLE = "BUNDLE";
-    protected static final String NOTIFICATION_TYPE_ACTION = "ACTION";
-    protected static final String NOTIFICATION_TYPE_ACTION_BUNDLE = "ACTION_BUNDLE";
-    protected static final String NOTIFICATION_TYPE_ACTION_REMOTE_INPUT = "ACTION_REMOTE_INPUT";
-
-    // TODO: Update BatteryManager.BATTERY_PLUGGED_ANY as @TestApi
-    public static final int BATTERY_PLUGGED_ANY =
-            BATTERY_PLUGGED_AC | BATTERY_PLUGGED_USB | BATTERY_PLUGGED_WIRELESS;
-
-    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 int PROCESS_STATE_FOREGROUND_SERVICE;
-
-    private static final String KEY_NETWORK_STATE_OBSERVER = TEST_PKG + ".observer";
-
-    protected static final int TYPE_COMPONENT_ACTIVTIY = 0;
-    protected static final int TYPE_COMPONENT_FOREGROUND_SERVICE = 1;
-
-    private static final int BATTERY_STATE_TIMEOUT_MS = 5000;
-    private static final int BATTERY_STATE_CHECK_INTERVAL_MS = 500;
-
-    private static final int FOREGROUND_PROC_NETWORK_TIMEOUT_MS = 6000;
-
-    // Must be higher than NETWORK_TIMEOUT_MS
-    private static final int ORDERED_BROADCAST_TIMEOUT_MS = NETWORK_TIMEOUT_MS * 4;
-
-    private static final IntentFilter BATTERY_CHANGED_FILTER =
-            new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
-
-    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;
-    protected int mUid;
-    private int mMyUid;
-    private MyServiceClient mServiceClient;
-    private String mDeviceIdleConstantsSetting;
-
-    @Rule
-    public final RuleChain mRuleChain = RuleChain.outerRule(new RequiredPropertiesRule())
-            .around(new MeterednessConfigurationRule());
-
-    protected void setUp() throws Exception {
-
-        PROCESS_STATE_FOREGROUND_SERVICE = (Integer) ActivityManager.class
-                .getDeclaredField("PROCESS_STATE_FOREGROUND_SERVICE").get(null);
-        mInstrumentation = getInstrumentation();
-        mContext = getContext();
-        mCm = getConnectivityManager();
-        mUid = getUid(TEST_APP2_PKG);
-        mMyUid = getUid(mContext.getPackageName());
-        mServiceClient = new MyServiceClient(mContext);
-        mServiceClient.bind();
-        mDeviceIdleConstantsSetting = "device_idle_constants";
-        executeShellCommand("cmd netpolicy start-watching " + mUid);
-        setAppIdle(false);
-
-        Log.i(TAG, "Apps status:\n"
-                + "\ttest app: uid=" + mMyUid + ", state=" + getProcessStateByUid(mMyUid) + "\n"
-                + "\tapp2: uid=" + mUid + ", state=" + getProcessStateByUid(mUid));
-    }
-
-    protected void tearDown() throws Exception {
-        executeShellCommand("cmd netpolicy stop-watching");
-        mServiceClient.unbind();
-    }
-
-    protected int getUid(String packageName) throws Exception {
-        return mContext.getPackageManager().getPackageUid(packageName, 0);
-    }
-
-    protected void assertRestrictBackgroundChangedReceived(int expectedCount) throws Exception {
-        assertRestrictBackgroundChangedReceived(DYNAMIC_RECEIVER, expectedCount);
-        assertRestrictBackgroundChangedReceived(MANIFEST_RECEIVER, 0);
-    }
-
-    protected void assertRestrictBackgroundChangedReceived(String receiverName, int expectedCount)
-            throws Exception {
-        int attempts = 0;
-        int count = 0;
-        final int maxAttempts = 5;
-        do {
-            attempts++;
-            count = getNumberBroadcastsReceived(receiverName, ACTION_RESTRICT_BACKGROUND_CHANGED);
-            assertFalse("Expected count " + expectedCount + " but actual is " + count,
-                    count > expectedCount);
-            if (count == expectedCount) {
-                break;
-            }
-            Log.d(TAG, "Expecting count " + expectedCount + " but actual is " + count + " after "
-                    + attempts + " attempts; sleeping "
-                    + SLEEP_TIME_SEC + " seconds before trying again");
-            SystemClock.sleep(SLEEP_TIME_SEC * SECOND_IN_MS);
-        } while (attempts <= maxAttempts);
-        assertEquals("Number of expected broadcasts for " + receiverName + " not reached after "
-                + maxAttempts * SLEEP_TIME_SEC + " seconds", expectedCount, count);
-    }
-
-    protected String sendOrderedBroadcast(Intent intent) throws Exception {
-        return sendOrderedBroadcast(intent, ORDERED_BROADCAST_TIMEOUT_MS);
-    }
-
-    protected String sendOrderedBroadcast(Intent intent, int timeoutMs) throws Exception {
-        final LinkedBlockingQueue<String> result = new LinkedBlockingQueue<>(1);
-        Log.d(TAG, "Sending ordered broadcast: " + intent);
-        mContext.sendOrderedBroadcast(intent, null, new BroadcastReceiver() {
-
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                final String resultData = getResultData();
-                if (resultData == null) {
-                    Log.e(TAG, "Received null data from ordered intent");
-                    return;
-                }
-                result.offer(resultData);
-            }
-        }, null, 0, null, null);
-
-        final String resultData = result.poll(timeoutMs, TimeUnit.MILLISECONDS);
-        Log.d(TAG, "Ordered broadcast response after " + timeoutMs + "ms: " + resultData );
-        return resultData;
-    }
-
-    protected int getNumberBroadcastsReceived(String receiverName, String action) throws Exception {
-        return mServiceClient.getCounters(receiverName, action);
-    }
-
-    protected void assertRestrictBackgroundStatus(int expectedStatus) throws Exception {
-        final String status = mServiceClient.getRestrictBackgroundStatus();
-        assertNotNull("didn't get API status from app2", status);
-        assertEquals(restrictBackgroundValueToString(expectedStatus),
-                restrictBackgroundValueToString(Integer.parseInt(status)));
-    }
-
-    protected void assertBackgroundNetworkAccess(boolean expectAllowed) throws Exception {
-        assertBackgroundState(); // Sanity check.
-        assertNetworkAccess(expectAllowed /* expectAvailable */, false /* needScreenOn */);
-    }
-
-    protected void assertForegroundNetworkAccess() throws Exception {
-        assertForegroundState(); // Sanity check.
-        // 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 /* expectAvailable */, false /* needScreenOn */);
-    }
-
-    /**
-     * Asserts that an app always have access while on foreground or running a foreground service.
-     *
-     * <p>This method will launch an activity and a foreground service to make the assertion, but
-     * will finish the activity / stop the service afterwards.
-     */
-    protected void assertsForegroundAlwaysHasNetworkAccess() throws Exception{
-        // Checks foreground first.
-        launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY);
-        finishActivity();
-
-        // Then foreground service
-        launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_FOREGROUND_SERVICE);
-        stopForegroundService();
-    }
-
-    protected final void assertBackgroundState() throws Exception {
-        final int maxTries = 30;
-        ProcessState state = null;
-        for (int i = 1; i <= maxTries; i++) {
-            state = getProcessStateByUid(mUid);
-            Log.v(TAG, "assertBackgroundState(): status for app2 (" + mUid + ") on attempt #" + i
-                    + ": " + state);
-            if (isBackground(state.state)) {
-                return;
-            }
-            Log.d(TAG, "App not on background state (" + state + ") on attempt #" + i
-                    + "; sleeping 1s before trying again");
-            SystemClock.sleep(SECOND_IN_MS);
-        }
-        fail("App2 is not on background state after " + maxTries + " attempts: " + state );
-    }
-
-    protected final void assertForegroundState() throws Exception {
-        final int maxTries = 30;
-        ProcessState state = null;
-        for (int i = 1; i <= maxTries; i++) {
-            state = getProcessStateByUid(mUid);
-            Log.v(TAG, "assertForegroundState(): status for app2 (" + mUid + ") on attempt #" + i
-                    + ": " + state);
-            if (!isBackground(state.state)) {
-                return;
-            }
-            Log.d(TAG, "App not on foreground state on attempt #" + i
-                    + "; sleeping 1s before trying again");
-            turnScreenOn();
-            SystemClock.sleep(SECOND_IN_MS);
-        }
-        fail("App2 is not on foreground state after " + maxTries + " attempts: " + state );
-    }
-
-    protected final void assertForegroundServiceState() throws Exception {
-        final int maxTries = 30;
-        ProcessState state = null;
-        for (int i = 1; i <= maxTries; i++) {
-            state = getProcessStateByUid(mUid);
-            Log.v(TAG, "assertForegroundServiceState(): status for app2 (" + mUid + ") on attempt #"
-                    + i + ": " + state);
-            if (state.state == PROCESS_STATE_FOREGROUND_SERVICE) {
-                return;
-            }
-            Log.d(TAG, "App not on foreground service state on attempt #" + i
-                    + "; sleeping 1s before trying again");
-            SystemClock.sleep(SECOND_IN_MS);
-        }
-        fail("App2 is not on foreground service state after " + maxTries + " attempts: " + state );
-    }
-
-    /**
-     * Returns whether an app state should be considered "background" for restriction purposes.
-     */
-    protected boolean isBackground(int state) {
-        return state > PROCESS_STATE_FOREGROUND_SERVICE;
-    }
-
-    /**
-     * Asserts whether the active network is available or not.
-     */
-    private void assertNetworkAccess(boolean expectAvailable, boolean needScreenOn)
-            throws Exception {
-        final int maxTries = 5;
-        String error = null;
-        int timeoutMs = 500;
-
-        for (int i = 1; i <= maxTries; i++) {
-            error = checkNetworkAccess(expectAvailable);
-
-            if (error.isEmpty()) return;
-
-            // TODO: ideally, it should retry only when it cannot connect to an external site,
-            // or no retry at all! But, currently, the initial change fails almost always on
-            // battery saver tests because the netd changes are made asynchronously.
-            // Once b/27803922 is fixed, this retry mechanism should be revisited.
-
-            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);
-            }
-            // Exponential back-off.
-            timeoutMs = Math.min(timeoutMs*2, NETWORK_TIMEOUT_MS);
-        }
-        fail("Invalid state for expectAvailable=" + expectAvailable + " after " + maxTries
-                + " attempts.\nLast error: " + error);
-    }
-
-    /**
-     * Checks whether the network is available as expected.
-     *
-     * @return error message with the mismatch (or empty if assertion passed).
-     */
-    private String checkNetworkAccess(boolean expectAvailable) throws Exception {
-        final String resultData = mServiceClient.checkNetworkStatus();
-        return checkForAvailabilityInResultData(resultData, expectAvailable);
-    }
-
-    private String checkForAvailabilityInResultData(String resultData, boolean expectAvailable) {
-        if (resultData == null) {
-            assertNotNull("Network status from app2 is null", resultData);
-        }
-        // Network status format is described on MyBroadcastReceiver.checkNetworkStatus()
-        final String[] parts = resultData.split(NETWORK_STATUS_SEPARATOR);
-        assertEquals("Wrong network status: " + resultData, 5, parts.length); // Sanity check
-        final State state = parts[0].equals("null") ? null : State.valueOf(parts[0]);
-        final DetailedState detailedState = parts[1].equals("null")
-                ? null : DetailedState.valueOf(parts[1]);
-        final boolean connected = Boolean.valueOf(parts[2]);
-        final String connectionCheckDetails = parts[3];
-        final String networkInfo = parts[4];
-
-        final StringBuilder errors = new StringBuilder();
-        final State expectedState;
-        final DetailedState expectedDetailedState;
-        if (expectAvailable) {
-            expectedState = State.CONNECTED;
-            expectedDetailedState = DetailedState.CONNECTED;
-        } else {
-            expectedState = State.DISCONNECTED;
-            expectedDetailedState = DetailedState.BLOCKED;
-        }
-
-        if (expectAvailable != connected) {
-            errors.append(String.format("External site connection failed: expected %s, got %s\n",
-                    expectAvailable, connected));
-        }
-        if (expectedState != state || expectedDetailedState != detailedState) {
-            errors.append(String.format("Connection state mismatch: expected %s/%s, got %s/%s\n",
-                    expectedState, expectedDetailedState, state, detailedState));
-        }
-
-        if (errors.length() > 0) {
-            errors.append("\tnetworkInfo: " + networkInfo + "\n");
-            errors.append("\tconnectionCheckDetails: " + connectionCheckDetails + "\n");
-        }
-        return errors.toString();
-    }
-
-    /**
-     * Runs a Shell command which is not expected to generate output.
-     */
-    protected void executeSilentShellCommand(String command) {
-        final String result = executeShellCommand(command);
-        assertTrue("Command '" + command + "' failed: " + result, result.trim().isEmpty());
-    }
-
-    /**
-     * Asserts the result of a command, wait and re-running it a couple times if necessary.
-     */
-    protected void assertDelayedShellCommand(String command, final String expectedResult)
-            throws Exception {
-        assertDelayedShellCommand(command, 5, 1, expectedResult);
-    }
-
-    protected void assertDelayedShellCommand(String command, int maxTries, int napTimeSeconds,
-            final String expectedResult) throws Exception {
-        assertDelayedShellCommand(command, maxTries, napTimeSeconds, new ExpectResultChecker() {
-
-            @Override
-            public boolean isExpected(String result) {
-                return expectedResult.equals(result);
-            }
-
-            @Override
-            public String getExpected() {
-                return expectedResult;
-            }
-        });
-    }
-
-    protected void assertDelayedShellCommand(String command, int maxTries, int napTimeSeconds,
-            ExpectResultChecker checker) throws Exception {
-        String result = "";
-        for (int i = 1; i <= maxTries; i++) {
-            result = executeShellCommand(command).trim();
-            if (checker.isExpected(result)) return;
-            Log.v(TAG, "Command '" + command + "' returned '" + result + " instead of '"
-                    + checker.getExpected() + "' on attempt #" + i
-                    + "; sleeping " + napTimeSeconds + "s before trying again");
-            SystemClock.sleep(napTimeSeconds * SECOND_IN_MS);
-        }
-        fail("Command '" + command + "' did not return '" + checker.getExpected() + "' after "
-                + maxTries
-                + " attempts. Last result: '" + result + "'");
-    }
-
-    protected void addRestrictBackgroundWhitelist(int uid) throws Exception {
-        executeShellCommand("cmd netpolicy add restrict-background-whitelist " + uid);
-        assertRestrictBackgroundWhitelist(uid, true);
-        // UID policies live by the Highlander rule: "There can be only one".
-        // Hence, if app is whitelisted, it should not be blacklisted.
-        assertRestrictBackgroundBlacklist(uid, false);
-    }
-
-    protected void removeRestrictBackgroundWhitelist(int uid) throws Exception {
-        executeShellCommand("cmd netpolicy remove restrict-background-whitelist " + uid);
-        assertRestrictBackgroundWhitelist(uid, false);
-    }
-
-    protected void assertRestrictBackgroundWhitelist(int uid, boolean expected) throws Exception {
-        assertRestrictBackground("restrict-background-whitelist", uid, expected);
-    }
-
-    protected void addRestrictBackgroundBlacklist(int uid) throws Exception {
-        executeShellCommand("cmd netpolicy add restrict-background-blacklist " + uid);
-        assertRestrictBackgroundBlacklist(uid, true);
-        // UID policies live by the Highlander rule: "There can be only one".
-        // Hence, if app is blacklisted, it should not be whitelisted.
-        assertRestrictBackgroundWhitelist(uid, false);
-    }
-
-    protected void removeRestrictBackgroundBlacklist(int uid) throws Exception {
-        executeShellCommand("cmd netpolicy remove restrict-background-blacklist " + uid);
-        assertRestrictBackgroundBlacklist(uid, false);
-    }
-
-    protected void assertRestrictBackgroundBlacklist(int uid, boolean expected) throws Exception {
-        assertRestrictBackground("restrict-background-blacklist", uid, expected);
-    }
-
-    protected void addAppIdleWhitelist(int uid) throws Exception {
-        executeShellCommand("cmd netpolicy add app-idle-whitelist " + uid);
-        assertAppIdleWhitelist(uid, true);
-    }
-
-    protected void removeAppIdleWhitelist(int uid) throws Exception {
-        executeShellCommand("cmd netpolicy remove app-idle-whitelist " + uid);
-        assertAppIdleWhitelist(uid, false);
-    }
-
-    protected void assertAppIdleWhitelist(int uid, boolean expected) throws Exception {
-        assertRestrictBackground("app-idle-whitelist", uid, expected);
-    }
-
-    private void assertRestrictBackground(String list, int uid, boolean expected) throws Exception {
-        final int maxTries = 5;
-        boolean actual = false;
-        final String expectedUid = Integer.toString(uid);
-        String uids = "";
-        for (int i = 1; i <= maxTries; i++) {
-            final String output =
-                    executeShellCommand("cmd netpolicy list " + list);
-            uids = output.split(":")[1];
-            for (String candidate : uids.split(" ")) {
-                actual = candidate.trim().equals(expectedUid);
-                if (expected == actual) {
-                    return;
-                }
-            }
-            Log.v(TAG, list + " check for uid " + uid + " doesn't match yet (expected "
-                    + expected + ", got " + actual + "); sleeping 1s before polling again");
-            SystemClock.sleep(SECOND_IN_MS);
-        }
-        fail(list + " check for uid " + uid + " failed: expected " + expected + ", got " + actual
-                + ". 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
-        // need to use netpolicy for whitelisting
-        assertDelayedShellCommand("dumpsys deviceidle whitelist =" + packageName,
-                Boolean.toString(expected));
-    }
-
-    protected void addPowerSaveModeWhitelist(String packageName) throws Exception {
-        Log.i(TAG, "Adding package " + packageName + " to power-save-mode whitelist");
-        // TODO: currently the power-save mode is behaving like idle, but once it changes, we'll
-        // need to use netpolicy for whitelisting
-        executeShellCommand("dumpsys deviceidle whitelist +" + packageName);
-        assertPowerSaveModeWhitelist(packageName, true); // Sanity check
-    }
-
-    protected void removePowerSaveModeWhitelist(String packageName) throws Exception {
-        Log.i(TAG, "Removing package " + packageName + " from power-save-mode whitelist");
-        // TODO: currently the power-save mode is behaving like idle, but once it changes, we'll
-        // need to use netpolicy for whitelisting
-        executeShellCommand("dumpsys deviceidle whitelist -" + packageName);
-        assertPowerSaveModeWhitelist(packageName, false); // Sanity check
-    }
-
-    protected void assertPowerSaveModeExceptIdleWhitelist(String packageName, boolean expected)
-            throws Exception {
-        // TODO: currently the power-save mode is behaving like idle, but once it changes, we'll
-        // need to use netpolicy for whitelisting
-        assertDelayedShellCommand("dumpsys deviceidle except-idle-whitelist =" + packageName,
-                Boolean.toString(expected));
-    }
-
-    protected void addPowerSaveModeExceptIdleWhitelist(String packageName) throws Exception {
-        Log.i(TAG, "Adding package " + packageName + " to power-save-mode-except-idle whitelist");
-        // TODO: currently the power-save mode is behaving like idle, but once it changes, we'll
-        // need to use netpolicy for whitelisting
-        executeShellCommand("dumpsys deviceidle except-idle-whitelist +" + packageName);
-        assertPowerSaveModeExceptIdleWhitelist(packageName, true); // Sanity check
-    }
-
-    protected void removePowerSaveModeExceptIdleWhitelist(String packageName) throws Exception {
-        Log.i(TAG, "Removing package " + packageName
-                + " from power-save-mode-except-idle whitelist");
-        // TODO: currently the power-save mode is behaving like idle, but once it changes, we'll
-        // need to use netpolicy for whitelisting
-        executeShellCommand("dumpsys deviceidle except-idle-whitelist reset");
-        assertPowerSaveModeExceptIdleWhitelist(packageName, false); // Sanity check
-    }
-
-    protected void turnBatteryOn() throws Exception {
-        executeSilentShellCommand("cmd battery unplug");
-        executeSilentShellCommand("cmd battery set status "
-                + BatteryManager.BATTERY_STATUS_DISCHARGING);
-        assertBatteryState(false);
-    }
-
-    protected void turnBatteryOff() throws Exception {
-        executeSilentShellCommand("cmd battery set ac " + BATTERY_PLUGGED_ANY);
-        executeSilentShellCommand("cmd battery set level 100");
-        executeSilentShellCommand("cmd battery set status "
-                + BatteryManager.BATTERY_STATUS_CHARGING);
-        assertBatteryState(true);
-    }
-
-    private void assertBatteryState(boolean pluggedIn) throws Exception {
-        final long endTime = SystemClock.elapsedRealtime() + BATTERY_STATE_TIMEOUT_MS;
-        while (isDevicePluggedIn() != pluggedIn && SystemClock.elapsedRealtime() <= endTime) {
-            Thread.sleep(BATTERY_STATE_CHECK_INTERVAL_MS);
-        }
-        if (isDevicePluggedIn() != pluggedIn) {
-            fail("Timed out waiting for the plugged-in state to change,"
-                    + " expected pluggedIn: " + pluggedIn);
-        }
-    }
-
-    private boolean isDevicePluggedIn() {
-        final Intent batteryIntent = mContext.registerReceiver(null, BATTERY_CHANGED_FILTER);
-        return batteryIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) > 0;
-    }
-
-    protected void turnScreenOff() throws Exception {
-        executeSilentShellCommand("input keyevent KEYCODE_SLEEP");
-    }
-
-    protected void turnScreenOn() throws Exception {
-        executeSilentShellCommand("input keyevent KEYCODE_WAKEUP");
-        executeSilentShellCommand("wm dismiss-keyguard");
-    }
-
-    protected void setBatterySaverMode(boolean enabled) throws Exception {
-        Log.i(TAG, "Setting Battery Saver Mode to " + enabled);
-        if (enabled) {
-            turnBatteryOn();
-            executeSilentShellCommand("cmd power set-mode 1");
-        } else {
-            executeSilentShellCommand("cmd power set-mode 0");
-            turnBatteryOff();
-        }
-    }
-
-    protected void setDozeMode(boolean enabled) throws Exception {
-        // Sanity check, since tests should check beforehand....
-        assertTrue("Device does not support Doze Mode", isDozeModeSupported());
-
-        Log.i(TAG, "Setting Doze Mode to " + enabled);
-        if (enabled) {
-            turnBatteryOn();
-            turnScreenOff();
-            executeShellCommand("dumpsys deviceidle force-idle deep");
-        } else {
-            turnScreenOn();
-            turnBatteryOff();
-            executeShellCommand("dumpsys deviceidle unforce");
-        }
-        // Sanity check.
-        assertDozeMode(enabled);
-    }
-
-    protected void assertDozeMode(boolean enabled) throws Exception {
-        assertDelayedShellCommand("dumpsys deviceidle get deep", enabled ? "IDLE" : "ACTIVE");
-    }
-
-    protected void setAppIdle(boolean enabled) throws Exception {
-        Log.i(TAG, "Setting app idle to " + enabled);
-        executeSilentShellCommand("am set-inactive " + TEST_APP2_PKG + " " + enabled );
-        assertAppIdle(enabled); // Sanity check
-    }
-
-    protected void setAppIdleNoAssert(boolean enabled) throws Exception {
-        Log.i(TAG, "Setting app idle to " + enabled);
-        executeSilentShellCommand("am set-inactive " + TEST_APP2_PKG + " " + enabled );
-    }
-
-    protected void assertAppIdle(boolean enabled) throws Exception {
-        try {
-            assertDelayedShellCommand("am get-inactive " + TEST_APP2_PKG, 15, 2, "Idle=" + enabled);
-        } catch (Throwable e) {
-            throw e;
-        }
-    }
-
-    /**
-     * Starts a service that will register a broadcast receiver to receive
-     * {@code RESTRICT_BACKGROUND_CHANGE} intents.
-     * <p>
-     * The service must run in a separate app because otherwise it would be killed every time
-     * {@link #runDeviceTests(String, String)} is executed.
-     */
-    protected void registerBroadcastReceiver() throws Exception {
-        mServiceClient.registerBroadcastReceiver();
-
-        final Intent intent = new Intent(ACTION_RECEIVER_READY)
-                .addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-        // Wait until receiver is ready.
-        final int maxTries = 10;
-        for (int i = 1; i <= maxTries; i++) {
-            final String message = sendOrderedBroadcast(intent, SECOND_IN_MS * 4);
-            Log.d(TAG, "app2 receiver acked: " + message);
-            if (message != null) {
-                return;
-            }
-            Log.v(TAG, "app2 receiver is not ready yet; sleeping 1s before polling again");
-            SystemClock.sleep(SECOND_IN_MS);
-        }
-        fail("app2 receiver is not ready");
-    }
-
-    protected void registerNetworkCallback(INetworkCallback cb) throws Exception {
-        mServiceClient.registerNetworkCallback(cb);
-    }
-
-    protected void unregisterNetworkCallback() throws Exception {
-        mServiceClient.unregisterNetworkCallback();
-    }
-
-    /**
-     * Registers a {@link NotificationListenerService} implementation that will execute the
-     * notification actions right after the notification is sent.
-     */
-    protected void registerNotificationListenerService() throws Exception {
-        executeShellCommand("cmd notification allow_listener "
-                + MyNotificationListenerService.getId());
-        final NotificationManager nm = mContext.getSystemService(NotificationManager.class);
-        final ComponentName listenerComponent = MyNotificationListenerService.getComponentName();
-        assertTrue(listenerComponent + " has not been granted access",
-                nm.isNotificationListenerAccessGranted(listenerComponent));
-    }
-
-    protected void setPendingIntentWhitelistDuration(int durationMs) throws Exception {
-        executeSilentShellCommand(String.format(
-                "settings put global %s %s=%d", mDeviceIdleConstantsSetting,
-                "notification_whitelist_duration", durationMs));
-    }
-
-    protected void resetDeviceIdleSettings() throws Exception {
-        executeShellCommand(String.format("settings delete global %s",
-                mDeviceIdleConstantsSetting));
-    }
-
-    protected void launchComponentAndAssertNetworkAccess(int type) throws Exception {
-        if (type == TYPE_COMPONENT_FOREGROUND_SERVICE) {
-            startForegroundService();
-            assertForegroundServiceNetworkAccess();
-            return;
-        } else if (type == TYPE_COMPONENT_ACTIVTIY) {
-            turnScreenOn();
-            // Wait for screen-on state to propagate through the system.
-            SystemClock.sleep(2000);
-            final CountDownLatch latch = new CountDownLatch(1);
-            final Intent launchIntent = getIntentForComponent(type);
-            final Bundle extras = new Bundle();
-            final String[] errors = new String[]{null};
-            extras.putBinder(KEY_NETWORK_STATE_OBSERVER, getNewNetworkStateObserver(latch, errors));
-            launchIntent.putExtras(extras);
-            mContext.startActivity(launchIntent);
-            if (latch.await(FOREGROUND_PROC_NETWORK_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
-                if (!errors[0].isEmpty()) {
-                    if (errors[0] == APP_NOT_FOREGROUND_ERROR) {
-                        // App didn't come to foreground when the activity is started, so try again.
-                        assertForegroundNetworkAccess();
-                    } else {
-                        fail("Network is not available for app2 (" + mUid + "): " + errors[0]);
-                    }
-                }
-            } else {
-                fail("Timed out waiting for network availability status from app2 (" + mUid + ")");
-            }
-        } else {
-            throw new IllegalArgumentException("Unknown type: " + type);
-        }
-    }
-
-    private void startForegroundService() throws Exception {
-        final Intent launchIntent = getIntentForComponent(TYPE_COMPONENT_FOREGROUND_SERVICE);
-        mContext.startForegroundService(launchIntent);
-        assertForegroundServiceState();
-    }
-
-    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))
-                    .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);
-        } else {
-            fail("Unknown type: " + type);
-        }
-        return intent;
-    }
-
-    protected void stopForegroundService() throws Exception {
-        executeShellCommand(String.format("am startservice -f 2 %s/%s",
-                TEST_APP2_PKG, TEST_APP2_SERVICE_CLASS));
-        // NOTE: cannot assert state because it depends on whether activity was on top before.
-    }
-
-    private Binder getNewNetworkStateObserver(final CountDownLatch latch,
-            final String[] errors) {
-        return new INetworkStateObserver.Stub() {
-            @Override
-            public boolean isForeground() {
-                try {
-                    final ProcessState state = getProcessStateByUid(mUid);
-                    return !isBackground(state.state);
-                } catch (Exception e) {
-                    Log.d(TAG, "Error while reading the proc state for " + mUid + ": " + e);
-                    return false;
-                }
-            }
-
-            @Override
-            public void onNetworkStateChecked(String resultData) {
-                errors[0] = resultData == null
-                        ? APP_NOT_FOREGROUND_ERROR
-                        : checkForAvailabilityInResultData(resultData, true);
-                latch.countDown();
-            }
-        };
-    }
-
-    /**
-     * Finishes an activity on app2 so its process is demoted fromforeground status.
-     */
-    protected void finishActivity() throws Exception {
-        executeShellCommand("am broadcast -a "
-                + " com.android.cts.net.hostside.app2.action.FINISH_ACTIVITY "
-                + "--receiver-foreground --receiver-registered-only");
-    }
-
-    protected void sendNotification(int notificationId, String notificationType) throws Exception {
-        Log.d(TAG, "Sending notification broadcast (id=" + notificationId
-                + ", type=" + notificationType);
-        mServiceClient.sendNotification(notificationId, notificationType);
-    }
-
-    protected String showToast() {
-        final Intent intent = new Intent(ACTION_SHOW_TOAST);
-        intent.setPackage(TEST_APP2_PKG);
-        Log.d(TAG, "Sending request to show toast");
-        try {
-            return sendOrderedBroadcast(intent, 3 * SECOND_IN_MS);
-        } catch (Exception e) {
-            return "";
-        }
-    }
-
-    private ProcessState getProcessStateByUid(int uid) throws Exception {
-        return new ProcessState(executeShellCommand("cmd activity get-uid-state " + uid));
-    }
-
-    private static class ProcessState {
-        private final String fullState;
-        final int state;
-
-        ProcessState(String fullState) {
-            this.fullState = fullState;
-            try {
-                this.state = Integer.parseInt(fullState.split(" ")[0]);
-            } catch (Exception e) {
-                throw new IllegalArgumentException("Could not parse " + fullState);
-            }
-        }
-
-        @Override
-        public String toString() {
-            return fullState;
-        }
-    }
-
-    /**
-     * Helper class used to assert the result of a Shell command.
-     */
-    protected static interface ExpectResultChecker {
-        /**
-         * Checkes whether the result of the command matched the expectation.
-         */
-        boolean isExpected(String result);
-        /**
-         * Gets the expected result so it's displayed on log and failure messages.
-         */
-        String getExpected();
-    }
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java
deleted file mode 100644
index f1858d6..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-import static com.android.cts.net.hostside.Property.METERED_NETWORK;
-
-@RequiredProperties({METERED_NETWORK})
-public class AppIdleMeteredTest extends AbstractAppIdleTestCase {
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java
deleted file mode 100644
index e737a6d..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK;
-
-@RequiredProperties({NON_METERED_NETWORK})
-public class AppIdleNonMeteredTest extends AbstractAppIdleTestCase {
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java
deleted file mode 100644
index c78ca2e..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-import static com.android.cts.net.hostside.Property.METERED_NETWORK;
-
-@RequiredProperties({METERED_NETWORK})
-public class BatterySaverModeMeteredTest extends AbstractBatterySaverModeTestCase {
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java
deleted file mode 100644
index fb52a54..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-
-import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK;
-
-@RequiredProperties({NON_METERED_NETWORK})
-public class BatterySaverModeNonMeteredTest extends AbstractBatterySaverModeTestCase {
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java
deleted file mode 100644
index aa2c914..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
-import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
-import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED;
-
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground;
-import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE;
-import static com.android.cts.net.hostside.Property.METERED_NETWORK;
-import static com.android.cts.net.hostside.Property.NO_DATA_SAVER_MODE;
-
-import static org.junit.Assert.fail;
-
-import com.android.compatibility.common.util.CddTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import androidx.test.filters.LargeTest;
-
-@RequiredProperties({DATA_SAVER_MODE, METERED_NETWORK})
-@LargeTest
-public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase {
-
-    private static final String[] REQUIRED_WHITELISTED_PACKAGES = {
-        "com.android.providers.downloads"
-    };
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-
-        // Set initial state.
-        setRestrictBackground(false);
-        removeRestrictBackgroundWhitelist(mUid);
-        removeRestrictBackgroundBlacklist(mUid);
-
-        registerBroadcastReceiver();
-        assertRestrictBackgroundChangedReceived(0);
-   }
-
-    @After
-    public void tearDown() throws Exception {
-        super.tearDown();
-
-        setRestrictBackground(false);
-    }
-
-    @Test
-    public void testGetRestrictBackgroundStatus_disabled() throws Exception {
-        assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED);
-
-        // Sanity check: make sure status is always disabled, never whitelisted
-        addRestrictBackgroundWhitelist(mUid);
-        assertRestrictBackgroundChangedReceived(0);
-        assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED);
-
-        assertsForegroundAlwaysHasNetworkAccess();
-        assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED);
-    }
-
-    @Test
-    public void testGetRestrictBackgroundStatus_whitelisted() throws Exception {
-        setRestrictBackground(true);
-        assertRestrictBackgroundChangedReceived(1);
-        assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED);
-
-        addRestrictBackgroundWhitelist(mUid);
-        assertRestrictBackgroundChangedReceived(2);
-        assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_WHITELISTED);
-
-        removeRestrictBackgroundWhitelist(mUid);
-        assertRestrictBackgroundChangedReceived(3);
-        assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED);
-
-        assertsForegroundAlwaysHasNetworkAccess();
-        assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED);
-    }
-
-    @Test
-    public void testGetRestrictBackgroundStatus_enabled() throws Exception {
-        setRestrictBackground(true);
-        assertRestrictBackgroundChangedReceived(1);
-        assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED);
-
-        assertsForegroundAlwaysHasNetworkAccess();
-        assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED);
-
-        // Make sure foreground app doesn't lose access upon enabling Data Saver.
-        setRestrictBackground(false);
-        launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY);
-        setRestrictBackground(true);
-        assertForegroundNetworkAccess();
-
-        // Although it should not have access while the screen is off.
-        turnScreenOff();
-        assertBackgroundNetworkAccess(false);
-        turnScreenOn();
-        assertForegroundNetworkAccess();
-
-        // Goes back to background state.
-        finishActivity();
-        assertBackgroundNetworkAccess(false);
-
-        // Make sure foreground service doesn't lose access upon enabling Data Saver.
-        setRestrictBackground(false);
-        launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_FOREGROUND_SERVICE);
-        setRestrictBackground(true);
-        assertForegroundNetworkAccess();
-        stopForegroundService();
-        assertBackgroundNetworkAccess(false);
-    }
-
-    @Test
-    public void testGetRestrictBackgroundStatus_blacklisted() throws Exception {
-        addRestrictBackgroundBlacklist(mUid);
-        assertRestrictBackgroundChangedReceived(1);
-        assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED);
-
-        assertsForegroundAlwaysHasNetworkAccess();
-        assertRestrictBackgroundChangedReceived(1);
-        assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED);
-
-        // UID policies live by the Highlander rule: "There can be only one".
-        // Hence, if app is whitelisted, it should not be blacklisted anymore.
-        setRestrictBackground(true);
-        assertRestrictBackgroundChangedReceived(2);
-        assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED);
-        addRestrictBackgroundWhitelist(mUid);
-        assertRestrictBackgroundChangedReceived(3);
-        assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_WHITELISTED);
-
-        // Check status after removing blacklist.
-        // ...re-enables first
-        addRestrictBackgroundBlacklist(mUid);
-        assertRestrictBackgroundChangedReceived(4);
-        assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED);
-        assertsForegroundAlwaysHasNetworkAccess();
-        // ... remove blacklist - access's still rejected because Data Saver is on
-        removeRestrictBackgroundBlacklist(mUid);
-        assertRestrictBackgroundChangedReceived(4);
-        assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED);
-        assertsForegroundAlwaysHasNetworkAccess();
-        // ... finally, disable Data Saver
-        setRestrictBackground(false);
-        assertRestrictBackgroundChangedReceived(5);
-        assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED);
-        assertsForegroundAlwaysHasNetworkAccess();
-    }
-
-    @Test
-    public void testGetRestrictBackgroundStatus_requiredWhitelistedPackages() throws Exception {
-        final StringBuilder error = new StringBuilder();
-        for (String packageName : REQUIRED_WHITELISTED_PACKAGES) {
-            int uid = -1;
-            try {
-                uid = getUid(packageName);
-                assertRestrictBackgroundWhitelist(uid, true);
-            } catch (Throwable t) {
-                error.append("\nFailed for '").append(packageName).append("'");
-                if (uid > 0) {
-                    error.append(" (uid ").append(uid).append(")");
-                }
-                error.append(": ").append(t).append("\n");
-            }
-        }
-        if (error.length() > 0) {
-            fail(error.toString());
-        }
-    }
-
-    @RequiredProperties({NO_DATA_SAVER_MODE})
-    @CddTest(requirement="7.4.7/C-2-2")
-    @Test
-    public void testBroadcastNotSentOnUnsupportedDevices() throws Exception {
-        setRestrictBackground(true);
-        assertRestrictBackgroundChangedReceived(0);
-
-        setRestrictBackground(false);
-        assertRestrictBackgroundChangedReceived(0);
-
-        setRestrictBackground(true);
-        assertRestrictBackgroundChangedReceived(0);
-    }
-
-    private void assertDataSaverStatusOnBackground(int expectedStatus) throws Exception {
-        assertRestrictBackgroundStatus(expectedStatus);
-        assertBackgroundNetworkAccess(expectedStatus != RESTRICT_BACKGROUND_STATUS_ENABLED);
-    }
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java
deleted file mode 100644
index 4306c99..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-import static com.android.cts.net.hostside.Property.METERED_NETWORK;
-
-@RequiredProperties({METERED_NETWORK})
-public class DozeModeMeteredTest extends AbstractDozeModeTestCase {
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java
deleted file mode 100644
index 1e89f15..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK;
-
-@RequiredProperties({NON_METERED_NETWORK})
-public class DozeModeNonMeteredTest extends AbstractDozeModeTestCase {
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java
deleted file mode 100644
index 5ecb399..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.net.hostside;
-
-import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TAG;
-import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TEST_APP2_PKG;
-import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TEST_PKG;
-
-import android.os.Environment;
-import android.os.FileUtils;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
-
-import com.android.compatibility.common.util.OnFailureRule;
-
-import org.junit.AssumptionViolatedException;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-
-import androidx.test.platform.app.InstrumentationRegistry;
-
-public class DumpOnFailureRule extends OnFailureRule {
-    private File mDumpDir = new File(Environment.getExternalStorageDirectory(),
-            "CtsHostsideNetworkTests");
-
-    @Override
-    public void onTestFailure(Statement base, Description description, Throwable throwable) {
-        final String testName = description.getClassName() + "_" + description.getMethodName();
-
-        if (throwable instanceof AssumptionViolatedException) {
-            Log.d(TAG, "Skipping test " + testName + ": " + throwable);
-            return;
-        }
-
-        prepareDumpRootDir();
-        final File dumpFile = new File(mDumpDir, "dump-" + testName);
-        Log.i(TAG, "Dumping debug info for " + description + ": " + dumpFile.getPath());
-        try (FileOutputStream out = new FileOutputStream(dumpFile)) {
-            for (String cmd : new String[] {
-                    "dumpsys netpolicy",
-                    "dumpsys network_management",
-                    "dumpsys usagestats " + TEST_PKG + " " + TEST_APP2_PKG,
-                    "dumpsys usagestats appstandby",
-            }) {
-                dumpCommandOutput(out, cmd);
-            }
-        } catch (FileNotFoundException e) {
-            Log.e(TAG, "Error opening file: " + dumpFile, e);
-        } catch (IOException e) {
-            Log.e(TAG, "Error closing file: " + dumpFile, e);
-        }
-    }
-
-    void dumpCommandOutput(FileOutputStream out, String cmd) {
-        final ParcelFileDescriptor pfd = InstrumentationRegistry.getInstrumentation()
-                .getUiAutomation().executeShellCommand(cmd);
-        try (FileInputStream in = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) {
-            out.write(("Output of '" + cmd + "':\n").getBytes(StandardCharsets.UTF_8));
-            FileUtils.copy(in, out);
-            out.write("\n\n=================================================================\n\n"
-                    .getBytes(StandardCharsets.UTF_8));
-        } catch (IOException e) {
-            Log.e(TAG, "Error dumping '" + cmd + "'", e);
-        }
-    }
-
-    void prepareDumpRootDir() {
-        if (!mDumpDir.exists() && !mDumpDir.mkdir()) {
-            Log.e(TAG, "Error creating " + mDumpDir);
-        }
-    }
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java
deleted file mode 100644
index 8fadf9e..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.net.hostside;
-
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.resetMeteredNetwork;
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setupMeteredNetwork;
-import static com.android.cts.net.hostside.Property.METERED_NETWORK;
-import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK;
-
-import android.util.ArraySet;
-import android.util.Pair;
-
-import com.android.compatibility.common.util.BeforeAfterRule;
-
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-public class MeterednessConfigurationRule extends BeforeAfterRule {
-    private Pair<String, Boolean> mSsidAndInitialMeteredness;
-
-    @Override
-    public void onBefore(Statement base, Description description) throws Throwable {
-        final ArraySet<Property> requiredProperties
-                = RequiredPropertiesRule.getRequiredProperties();
-        if (requiredProperties.contains(METERED_NETWORK)) {
-            configureNetworkMeteredness(true);
-        } else if (requiredProperties.contains(NON_METERED_NETWORK)) {
-            configureNetworkMeteredness(false);
-        }
-    }
-
-    @Override
-    public void onAfter(Statement base, Description description) throws Throwable {
-        resetNetworkMeteredness();
-    }
-
-    public void configureNetworkMeteredness(boolean metered) throws Exception {
-        mSsidAndInitialMeteredness = setupMeteredNetwork(metered);
-    }
-
-    public void resetNetworkMeteredness() throws Exception {
-        if (mSsidAndInitialMeteredness != null) {
-            resetMeteredNetwork(mSsidAndInitialMeteredness.first,
-                    mSsidAndInitialMeteredness.second);
-        }
-    }
-}
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
deleted file mode 100644
index c9edda6..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.net.hostside;
-
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground;
-import static com.android.cts.net.hostside.Property.APP_STANDBY_MODE;
-import static com.android.cts.net.hostside.Property.BATTERY_SAVER_MODE;
-import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE;
-import static com.android.cts.net.hostside.Property.DOZE_MODE;
-import static com.android.cts.net.hostside.Property.METERED_NETWORK;
-import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK;
-
-import android.os.SystemClock;
-import android.util.Log;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Test cases for the more complex scenarios where multiple restrictions (like Battery Saver Mode
- * and Data Saver Mode) are applied simultaneously.
- * <p>
- * <strong>NOTE: </strong>it might sound like the test methods on this class are testing too much,
- * which would make it harder to diagnose individual failures, but the assumption is that such
- * failure most likely will happen when the restriction is tested individually as well.
- */
-public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase {
-    private static final String TAG = "MixedModesTest";
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-
-        // Set initial state.
-        removeRestrictBackgroundWhitelist(mUid);
-        removeRestrictBackgroundBlacklist(mUid);
-        removePowerSaveModeWhitelist(TEST_APP2_PKG);
-        removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
-
-        registerBroadcastReceiver();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        super.tearDown();
-
-        try {
-            setRestrictBackground(false);
-        } finally {
-            setBatterySaverMode(false);
-        }
-    }
-
-    /**
-     * Tests all DS ON and BS ON scenarios from network-policy-restrictions.md on metered networks.
-     */
-    @RequiredProperties({DATA_SAVER_MODE, BATTERY_SAVER_MODE, METERED_NETWORK})
-    @Test
-    public void testDataAndBatterySaverModes_meteredNetwork() throws Exception {
-        final MeterednessConfigurationRule meterednessConfiguration
-                = new MeterednessConfigurationRule();
-        meterednessConfiguration.configureNetworkMeteredness(true);
-        try {
-            setRestrictBackground(true);
-            setBatterySaverMode(true);
-
-            Log.v(TAG, "Not whitelisted for any.");
-            assertBackgroundNetworkAccess(false);
-            assertsForegroundAlwaysHasNetworkAccess();
-            assertBackgroundNetworkAccess(false);
-
-            Log.v(TAG, "Whitelisted for Data Saver but not for Battery Saver.");
-            addRestrictBackgroundWhitelist(mUid);
-            removePowerSaveModeWhitelist(TEST_APP2_PKG);
-            assertBackgroundNetworkAccess(false);
-            assertsForegroundAlwaysHasNetworkAccess();
-            assertBackgroundNetworkAccess(false);
-            removeRestrictBackgroundWhitelist(mUid);
-
-            Log.v(TAG, "Whitelisted for Battery Saver but not for Data Saver.");
-            addPowerSaveModeWhitelist(TEST_APP2_PKG);
-            removeRestrictBackgroundWhitelist(mUid);
-            assertBackgroundNetworkAccess(false);
-            assertsForegroundAlwaysHasNetworkAccess();
-            assertBackgroundNetworkAccess(false);
-            removePowerSaveModeWhitelist(TEST_APP2_PKG);
-
-            Log.v(TAG, "Whitelisted for both.");
-            addRestrictBackgroundWhitelist(mUid);
-            addPowerSaveModeWhitelist(TEST_APP2_PKG);
-            assertBackgroundNetworkAccess(true);
-            assertsForegroundAlwaysHasNetworkAccess();
-            assertBackgroundNetworkAccess(true);
-            removePowerSaveModeWhitelist(TEST_APP2_PKG);
-            assertBackgroundNetworkAccess(false);
-            removeRestrictBackgroundWhitelist(mUid);
-
-            Log.v(TAG, "Blacklisted for Data Saver, not whitelisted for Battery Saver.");
-            addRestrictBackgroundBlacklist(mUid);
-            removePowerSaveModeWhitelist(TEST_APP2_PKG);
-            assertBackgroundNetworkAccess(false);
-            assertsForegroundAlwaysHasNetworkAccess();
-            assertBackgroundNetworkAccess(false);
-            removeRestrictBackgroundBlacklist(mUid);
-
-            Log.v(TAG, "Blacklisted for Data Saver, whitelisted for Battery Saver.");
-            addRestrictBackgroundBlacklist(mUid);
-            addPowerSaveModeWhitelist(TEST_APP2_PKG);
-            assertBackgroundNetworkAccess(false);
-            assertsForegroundAlwaysHasNetworkAccess();
-            assertBackgroundNetworkAccess(false);
-            removeRestrictBackgroundBlacklist(mUid);
-            removePowerSaveModeWhitelist(TEST_APP2_PKG);
-        } finally {
-            meterednessConfiguration.resetNetworkMeteredness();
-        }
-    }
-
-    /**
-     * Tests all DS ON and BS ON scenarios from network-policy-restrictions.md on non-metered
-     * networks.
-     */
-    @RequiredProperties({DATA_SAVER_MODE, BATTERY_SAVER_MODE, NON_METERED_NETWORK})
-    @Test
-    public void testDataAndBatterySaverModes_nonMeteredNetwork() throws Exception {
-        final MeterednessConfigurationRule meterednessConfiguration
-                = new MeterednessConfigurationRule();
-        meterednessConfiguration.configureNetworkMeteredness(false);
-        try {
-            setRestrictBackground(true);
-            setBatterySaverMode(true);
-
-            Log.v(TAG, "Not whitelisted for any.");
-            assertBackgroundNetworkAccess(false);
-            assertsForegroundAlwaysHasNetworkAccess();
-            assertBackgroundNetworkAccess(false);
-
-            Log.v(TAG, "Whitelisted for Data Saver but not for Battery Saver.");
-            addRestrictBackgroundWhitelist(mUid);
-            removePowerSaveModeWhitelist(TEST_APP2_PKG);
-            assertBackgroundNetworkAccess(false);
-            assertsForegroundAlwaysHasNetworkAccess();
-            assertBackgroundNetworkAccess(false);
-            removeRestrictBackgroundWhitelist(mUid);
-
-            Log.v(TAG, "Whitelisted for Battery Saver but not for Data Saver.");
-            addPowerSaveModeWhitelist(TEST_APP2_PKG);
-            removeRestrictBackgroundWhitelist(mUid);
-            assertBackgroundNetworkAccess(true);
-            assertsForegroundAlwaysHasNetworkAccess();
-            assertBackgroundNetworkAccess(true);
-            removePowerSaveModeWhitelist(TEST_APP2_PKG);
-
-            Log.v(TAG, "Whitelisted for both.");
-            addRestrictBackgroundWhitelist(mUid);
-            addPowerSaveModeWhitelist(TEST_APP2_PKG);
-            assertBackgroundNetworkAccess(true);
-            assertsForegroundAlwaysHasNetworkAccess();
-            assertBackgroundNetworkAccess(true);
-            removePowerSaveModeWhitelist(TEST_APP2_PKG);
-            assertBackgroundNetworkAccess(false);
-            removeRestrictBackgroundWhitelist(mUid);
-
-            Log.v(TAG, "Blacklisted for Data Saver, not whitelisted for Battery Saver.");
-            addRestrictBackgroundBlacklist(mUid);
-            removePowerSaveModeWhitelist(TEST_APP2_PKG);
-            assertBackgroundNetworkAccess(false);
-            assertsForegroundAlwaysHasNetworkAccess();
-            assertBackgroundNetworkAccess(false);
-            removeRestrictBackgroundBlacklist(mUid);
-
-            Log.v(TAG, "Blacklisted for Data Saver, whitelisted for Battery Saver.");
-            addRestrictBackgroundBlacklist(mUid);
-            addPowerSaveModeWhitelist(TEST_APP2_PKG);
-            assertBackgroundNetworkAccess(true);
-            assertsForegroundAlwaysHasNetworkAccess();
-            assertBackgroundNetworkAccess(true);
-            removeRestrictBackgroundBlacklist(mUid);
-            removePowerSaveModeWhitelist(TEST_APP2_PKG);
-        } finally {
-            meterednessConfiguration.resetNetworkMeteredness();
-        }
-    }
-
-    /**
-     * Tests that powersave whitelists works as expected when doze and battery saver modes
-     * are enabled.
-     */
-    @RequiredProperties({DOZE_MODE, BATTERY_SAVER_MODE})
-    @Test
-    public void testDozeAndBatterySaverMode_powerSaveWhitelists() throws Exception {
-        setBatterySaverMode(true);
-        setDozeMode(true);
-
-        try {
-            addPowerSaveModeWhitelist(TEST_APP2_PKG);
-            assertBackgroundNetworkAccess(true);
-
-            removePowerSaveModeWhitelist(TEST_APP2_PKG);
-            assertBackgroundNetworkAccess(false);
-
-            addPowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
-            assertBackgroundNetworkAccess(false);
-
-            removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
-            assertBackgroundNetworkAccess(false);
-        } finally {
-            setBatterySaverMode(false);
-            setDozeMode(false);
-        }
-    }
-
-    /**
-     * Tests that powersave whitelists works as expected when doze and appIdle modes
-     * are enabled.
-     */
-    @RequiredProperties({DOZE_MODE, APP_STANDBY_MODE})
-    @Test
-    public void testDozeAndAppIdle_powerSaveWhitelists() throws Exception {
-        setDozeMode(true);
-        setAppIdle(true);
-
-        try {
-            addPowerSaveModeWhitelist(TEST_APP2_PKG);
-            assertBackgroundNetworkAccess(true);
-
-            removePowerSaveModeWhitelist(TEST_APP2_PKG);
-            assertBackgroundNetworkAccess(false);
-
-            addPowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
-            assertBackgroundNetworkAccess(false);
-
-            removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
-            assertBackgroundNetworkAccess(false);
-        } finally {
-            setAppIdle(false);
-            setDozeMode(false);
-        }
-    }
-
-    @RequiredProperties({APP_STANDBY_MODE, DOZE_MODE})
-    @Test
-    public void testAppIdleAndDoze_tempPowerSaveWhitelists() throws Exception {
-        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);
-        }
-    }
-
-    @RequiredProperties({APP_STANDBY_MODE, BATTERY_SAVER_MODE})
-    @Test
-    public void testAppIdleAndBatterySaver_tempPowerSaveWhitelists() throws Exception {
-        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);
-        }
-    }
-
-    /**
-     * Tests that the app idle whitelist works as expected when doze and appIdle mode are enabled.
-     */
-    @RequiredProperties({DOZE_MODE, APP_STANDBY_MODE})
-    @Test
-    public void testDozeAndAppIdle_appIdleWhitelist() throws Exception {
-        setDozeMode(true);
-        setAppIdle(true);
-
-        try {
-            assertBackgroundNetworkAccess(false);
-
-            // UID still shouldn't have access because of Doze.
-            addAppIdleWhitelist(mUid);
-            assertBackgroundNetworkAccess(false);
-
-            removeAppIdleWhitelist(mUid);
-            assertBackgroundNetworkAccess(false);
-        } finally {
-            setAppIdle(false);
-            setDozeMode(false);
-        }
-    }
-
-    @RequiredProperties({APP_STANDBY_MODE, DOZE_MODE})
-    @Test
-    public void testAppIdleAndDoze_tempPowerSaveAndAppIdleWhitelists() throws Exception {
-        setDozeMode(true);
-        setAppIdle(true);
-
-        try {
-            assertBackgroundNetworkAccess(false);
-
-            addAppIdleWhitelist(mUid);
-            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);
-            removeAppIdleWhitelist(mUid);
-        }
-    }
-
-    @RequiredProperties({APP_STANDBY_MODE, BATTERY_SAVER_MODE})
-    @Test
-    public void testAppIdleAndBatterySaver_tempPowerSaveAndAppIdleWhitelists() throws Exception {
-        setBatterySaverMode(true);
-        setAppIdle(true);
-
-        try {
-            assertBackgroundNetworkAccess(false);
-
-            addAppIdleWhitelist(mUid);
-            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);
-            removeAppIdleWhitelist(mUid);
-        }
-    }
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyActivity.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyActivity.java
deleted file mode 100644
index 0d0bc58..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyActivity.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.WindowManager;
-
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-public class MyActivity extends Activity {
-    private final LinkedBlockingQueue<Integer> mResult = new LinkedBlockingQueue<>(1);
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
-                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
-                | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
-    }
-
-    @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (mResult.offer(resultCode) == false) {
-            throw new RuntimeException("Queue is full! This should never happen");
-        }
-    }
-
-    public Integer getResult(int timeoutMs) throws InterruptedException {
-        return mResult.poll(timeoutMs, TimeUnit.MILLISECONDS);
-    }
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyNotificationListenerService.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyNotificationListenerService.java
deleted file mode 100644
index 0132536..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyNotificationListenerService.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.net.hostside;
-
-import android.app.Notification;
-import android.app.PendingIntent;
-import android.app.PendingIntent.CanceledException;
-import android.app.RemoteInput;
-import android.content.ComponentName;
-import android.os.Bundle;
-import android.service.notification.NotificationListenerService;
-import android.service.notification.StatusBarNotification;
-import android.util.Log;
-
-/**
- * NotificationListenerService implementation that executes the notification actions once they're
- * created.
- */
-public class MyNotificationListenerService extends NotificationListenerService {
-    private static final String TAG = "MyNotificationListenerService";
-
-    @Override
-    public void onListenerConnected() {
-        Log.d(TAG, "onListenerConnected()");
-    }
-
-    @Override
-    public void onNotificationPosted(StatusBarNotification sbn) {
-        Log.d(TAG, "onNotificationPosted(): "  + sbn);
-        if (!sbn.getPackageName().startsWith(getPackageName())) {
-            Log.v(TAG, "ignoring notification from a different package");
-            return;
-        }
-        final PendingIntentSender sender = new PendingIntentSender();
-        final Notification notification = sbn.getNotification();
-        if (notification.contentIntent != null) {
-            sender.send("content", notification.contentIntent);
-        }
-        if (notification.deleteIntent != null) {
-            sender.send("delete", notification.deleteIntent);
-        }
-        if (notification.fullScreenIntent != null) {
-            sender.send("full screen", notification.fullScreenIntent);
-        }
-        if (notification.actions != null) {
-            for (Notification.Action action : notification.actions) {
-                sender.send("action", action.actionIntent);
-                sender.send("action extras", action.getExtras());
-                final RemoteInput[] remoteInputs = action.getRemoteInputs();
-                if (remoteInputs != null && remoteInputs.length > 0) {
-                    for (RemoteInput remoteInput : remoteInputs) {
-                        sender.send("remote input extras", remoteInput.getExtras());
-                    }
-                }
-            }
-        }
-        sender.send("notification extras", notification.extras);
-    }
-
-    static String getId() {
-        return String.format("%s/%s", MyNotificationListenerService.class.getPackage().getName(),
-                MyNotificationListenerService.class.getName());
-    }
-
-    static ComponentName getComponentName() {
-        return new ComponentName(MyNotificationListenerService.class.getPackage().getName(),
-                MyNotificationListenerService.class.getName());
-    }
-
-    private static final class PendingIntentSender {
-        private PendingIntent mSentIntent = null;
-        private String mReason = null;
-
-        private void send(String reason, PendingIntent pendingIntent) {
-            if (pendingIntent == null) {
-                // Could happen on action that only has extras
-                Log.v(TAG, "Not sending null pending intent for " + reason);
-                return;
-            }
-            if (mSentIntent != null || mReason != null) {
-                // Sanity check: make sure test case set up just one pending intent in the
-                // notification, otherwise it could pass because another pending intent caused the
-                // whitelisting.
-                throw new IllegalStateException("Already sent a PendingIntent (" + mSentIntent
-                        + ") for reason '" + mReason + "' when requested another for '" + reason
-                        + "' (" + pendingIntent + ")");
-            }
-            Log.i(TAG, "Sending pending intent for " + reason + ":" + pendingIntent);
-            try {
-                pendingIntent.send();
-                mSentIntent = pendingIntent;
-                mReason = reason;
-            } catch (CanceledException e) {
-                Log.w(TAG, "Pending intent " + pendingIntent + " canceled");
-            }
-        }
-
-        private void send(String reason, Bundle extras) {
-            if (extras != null) {
-                for (String key : extras.keySet()) {
-                    Object value = extras.get(key);
-                    if (value instanceof PendingIntent) {
-                        send(reason + " with key '" + key + "'", (PendingIntent) value);
-                    }
-                }
-            }
-        }
-
-    }
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyServiceClient.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyServiceClient.java
deleted file mode 100644
index 6546e26..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyServiceClient.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.ConditionVariable;
-import android.os.IBinder;
-import android.os.RemoteException;
-
-import com.android.cts.net.hostside.IMyService;
-
-public class MyServiceClient {
-    private static final int TIMEOUT_MS = 5000;
-    private static final String PACKAGE = MyServiceClient.class.getPackage().getName();
-    private static final String APP2_PACKAGE = PACKAGE + ".app2";
-    private static final String SERVICE_NAME = APP2_PACKAGE + ".MyService";
-
-    private Context mContext;
-    private ServiceConnection mServiceConnection;
-    private IMyService mService;
-
-    public MyServiceClient(Context context) {
-        mContext = context;
-    }
-
-    public void bind() {
-        if (mService != null) {
-            throw new IllegalStateException("Already bound");
-        }
-
-        final ConditionVariable cv = new ConditionVariable();
-        mServiceConnection = new ServiceConnection() {
-            @Override
-            public void onServiceConnected(ComponentName name, IBinder service) {
-                mService = IMyService.Stub.asInterface(service);
-                cv.open();
-            }
-            @Override
-            public void onServiceDisconnected(ComponentName name) {
-                mService = null;
-            }
-        };
-
-        final Intent intent = new Intent();
-        intent.setComponent(new ComponentName(APP2_PACKAGE, SERVICE_NAME));
-        // Needs to use BIND_NOT_FOREGROUND so app2 does not run in
-        // the same process state as app
-        mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE
-                | Context.BIND_NOT_FOREGROUND);
-        cv.block(TIMEOUT_MS);
-        if (mService == null) {
-            throw new IllegalStateException(
-                    "Could not bind to MyService service after " + TIMEOUT_MS + "ms");
-        }
-    }
-
-    public void unbind() {
-        if (mService != null) {
-            mContext.unbindService(mServiceConnection);
-        }
-    }
-
-    public void registerBroadcastReceiver() throws RemoteException {
-        mService.registerBroadcastReceiver();
-    }
-
-    public int getCounters(String receiverName, String action) throws RemoteException {
-        return mService.getCounters(receiverName, action);
-    }
-
-    public String checkNetworkStatus() throws RemoteException {
-        return mService.checkNetworkStatus();
-    }
-
-    public String getRestrictBackgroundStatus() throws RemoteException {
-        return mService.getRestrictBackgroundStatus();
-    }
-
-    public void sendNotification(int notificationId, String notificationType) throws RemoteException {
-        mService.sendNotification(notificationId, notificationType);
-    }
-
-    public void registerNetworkCallback(INetworkCallback cb) throws RemoteException {
-        mService.registerNetworkCallback(cb);
-    }
-
-    public void unregisterNetworkCallback() throws RemoteException {
-        mService.unregisterNetworkCallback();
-    }
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyVpnService.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyVpnService.java
deleted file mode 100644
index 7d3d4fc..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyVpnService.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-import android.content.Intent;
-import android.net.Network;
-import android.net.ProxyInfo;
-import android.net.VpnService;
-import android.os.ParcelFileDescriptor;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-
-public class MyVpnService extends VpnService {
-
-    private static String TAG = "MyVpnService";
-    private static int MTU = 1799;
-
-    public static final String ACTION_ESTABLISHED = "com.android.cts.net.hostside.ESTABNLISHED";
-    public static final String EXTRA_ALWAYS_ON = "is-always-on";
-    public static final String EXTRA_LOCKDOWN_ENABLED = "is-lockdown-enabled";
-
-    private ParcelFileDescriptor mFd = null;
-    private PacketReflector mPacketReflector = null;
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        String packageName = getPackageName();
-        String cmd = intent.getStringExtra(packageName + ".cmd");
-        if ("disconnect".equals(cmd)) {
-            stop();
-        } else if ("connect".equals(cmd)) {
-            start(packageName, intent);
-        }
-
-        return START_NOT_STICKY;
-    }
-
-    private void start(String packageName, Intent intent) {
-        Builder builder = new Builder();
-
-        String addresses = intent.getStringExtra(packageName + ".addresses");
-        if (addresses != null) {
-            String[] addressArray = addresses.split(",");
-            for (int i = 0; i < addressArray.length; i++) {
-                String[] prefixAndMask = addressArray[i].split("/");
-                try {
-                    InetAddress address = InetAddress.getByName(prefixAndMask[0]);
-                    int prefixLength = Integer.parseInt(prefixAndMask[1]);
-                    builder.addAddress(address, prefixLength);
-                } catch (UnknownHostException|NumberFormatException|
-                         ArrayIndexOutOfBoundsException e) {
-                    continue;
-                }
-            }
-        }
-
-        String routes = intent.getStringExtra(packageName + ".routes");
-        if (routes != null) {
-            String[] routeArray = routes.split(",");
-            for (int i = 0; i < routeArray.length; i++) {
-                String[] prefixAndMask = routeArray[i].split("/");
-                try {
-                    InetAddress address = InetAddress.getByName(prefixAndMask[0]);
-                    int prefixLength = Integer.parseInt(prefixAndMask[1]);
-                    builder.addRoute(address, prefixLength);
-                } catch (UnknownHostException|NumberFormatException|
-                         ArrayIndexOutOfBoundsException e) {
-                    continue;
-                }
-            }
-        }
-
-        String allowed = intent.getStringExtra(packageName + ".allowedapplications");
-        if (allowed != null) {
-            String[] packageArray = allowed.split(",");
-            for (int i = 0; i < packageArray.length; i++) {
-                String allowedPackage = packageArray[i];
-                if (!TextUtils.isEmpty(allowedPackage)) {
-                    try {
-                        builder.addAllowedApplication(allowedPackage);
-                    } catch(NameNotFoundException e) {
-                        continue;
-                    }
-                }
-            }
-        }
-
-        String disallowed = intent.getStringExtra(packageName + ".disallowedapplications");
-        if (disallowed != null) {
-            String[] packageArray = disallowed.split(",");
-            for (int i = 0; i < packageArray.length; i++) {
-                String disallowedPackage = packageArray[i];
-                if (!TextUtils.isEmpty(disallowedPackage)) {
-                    try {
-                        builder.addDisallowedApplication(disallowedPackage);
-                    } catch(NameNotFoundException e) {
-                        continue;
-                    }
-                }
-            }
-        }
-
-        ArrayList<Network> underlyingNetworks =
-                intent.getParcelableArrayListExtra(packageName + ".underlyingNetworks");
-        if (underlyingNetworks == null) {
-            // VPN tracks default network
-            builder.setUnderlyingNetworks(null);
-        } else {
-            builder.setUnderlyingNetworks(underlyingNetworks.toArray(new Network[0]));
-        }
-
-        boolean isAlwaysMetered = intent.getBooleanExtra(packageName + ".isAlwaysMetered", false);
-        builder.setMetered(isAlwaysMetered);
-
-        ProxyInfo vpnProxy = intent.getParcelableExtra(packageName + ".httpProxy");
-        builder.setHttpProxy(vpnProxy);
-        builder.setMtu(MTU);
-        builder.setBlocking(true);
-        builder.setSession("MyVpnService");
-
-        Log.i(TAG, "Establishing VPN,"
-                + " addresses=" + addresses
-                + " routes=" + routes
-                + " allowedApplications=" + allowed
-                + " disallowedApplications=" + disallowed);
-
-        mFd = builder.establish();
-        Log.i(TAG, "Established, fd=" + (mFd == null ? "null" : mFd.getFd()));
-
-        broadcastEstablished();
-
-        mPacketReflector = new PacketReflector(mFd.getFileDescriptor(), MTU);
-        mPacketReflector.start();
-    }
-
-    private void broadcastEstablished() {
-        final Intent bcIntent = new Intent(ACTION_ESTABLISHED);
-        bcIntent.putExtra(EXTRA_ALWAYS_ON, isAlwaysOn());
-        bcIntent.putExtra(EXTRA_LOCKDOWN_ENABLED, isLockdownEnabled());
-        sendBroadcast(bcIntent);
-    }
-
-    private void stop() {
-        if (mPacketReflector != null) {
-            mPacketReflector.interrupt();
-            mPacketReflector = null;
-        }
-        try {
-            if (mFd != null) {
-                Log.i(TAG, "Closing filedescriptor");
-                mFd.close();
-            }
-        } catch(IOException e) {
-        } finally {
-            mFd = null;
-        }
-    }
-
-    @Override
-    public void onDestroy() {
-        stop();
-        super.onDestroy();
-    }
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java
deleted file mode 100644
index 2ac29e7..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.canChangeActiveNetworkMeteredness;
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground;
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isActiveNetworkMetered;
-import static com.android.cts.net.hostside.Property.BATTERY_SAVER_MODE;
-import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
-
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.util.Log;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import java.util.Objects;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCase {
-    private Network mNetwork;
-    private final TestNetworkCallback mTestNetworkCallback = new TestNetworkCallback();
-    @Rule
-    public final MeterednessConfigurationRule mMeterednessConfiguration
-            = new MeterednessConfigurationRule();
-
-    enum CallbackState {
-        NONE,
-        AVAILABLE,
-        LOST,
-        BLOCKED_STATUS,
-        CAPABILITIES
-    }
-
-    private static class CallbackInfo {
-        public final CallbackState state;
-        public final Network network;
-        public final Object arg;
-
-        CallbackInfo(CallbackState s, Network n, Object o) {
-            state = s; network = n; arg = o;
-        }
-
-        public String toString() {
-            return String.format("%s (%s) (%s)", state, network, arg);
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (!(o instanceof CallbackInfo)) return false;
-            // Ignore timeMs, since it's unpredictable.
-            final CallbackInfo other = (CallbackInfo) o;
-            return (state == other.state) && Objects.equals(network, other.network)
-                    && Objects.equals(arg, other.arg);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(state, network, arg);
-        }
-    }
-
-    private class TestNetworkCallback extends INetworkCallback.Stub {
-        private static final int TEST_CONNECT_TIMEOUT_MS = 30_000;
-        private static final int TEST_CALLBACK_TIMEOUT_MS = 5_000;
-
-        private final LinkedBlockingQueue<CallbackInfo> mCallbacks = new LinkedBlockingQueue<>();
-
-        protected void setLastCallback(CallbackState state, Network network, Object o) {
-            mCallbacks.offer(new CallbackInfo(state, network, o));
-        }
-
-        CallbackInfo nextCallback(int timeoutMs) {
-            CallbackInfo cb = null;
-            try {
-                cb = mCallbacks.poll(timeoutMs, TimeUnit.MILLISECONDS);
-            } catch (InterruptedException e) {
-            }
-            if (cb == null) {
-                fail("Did not receive callback after " + timeoutMs + "ms");
-            }
-            return cb;
-        }
-
-        CallbackInfo expectCallback(CallbackState state, Network expectedNetwork, Object o) {
-            final CallbackInfo expected = new CallbackInfo(state, expectedNetwork, o);
-            final CallbackInfo actual = nextCallback(TEST_CALLBACK_TIMEOUT_MS);
-            assertEquals("Unexpected callback:", expected, actual);
-            return actual;
-        }
-
-        @Override
-        public void onAvailable(Network network) {
-            setLastCallback(CallbackState.AVAILABLE, network, null);
-        }
-
-        @Override
-        public void onLost(Network network) {
-            setLastCallback(CallbackState.LOST, network, null);
-        }
-
-        @Override
-        public void onBlockedStatusChanged(Network network, boolean blocked) {
-            setLastCallback(CallbackState.BLOCKED_STATUS, network, blocked);
-        }
-
-        @Override
-        public void onCapabilitiesChanged(Network network, NetworkCapabilities cap) {
-            setLastCallback(CallbackState.CAPABILITIES, network, cap);
-        }
-
-        public Network expectAvailableCallbackAndGetNetwork() {
-            final CallbackInfo cb = nextCallback(TEST_CONNECT_TIMEOUT_MS);
-            if (cb.state != CallbackState.AVAILABLE) {
-                fail("Network is not available. Instead obtained the following callback :"
-                        + cb);
-            }
-            return cb.network;
-        }
-
-        public void expectBlockedStatusCallback(Network expectedNetwork, boolean expectBlocked) {
-            expectCallback(CallbackState.BLOCKED_STATUS, expectedNetwork, expectBlocked);
-        }
-
-        public void expectBlockedStatusCallbackEventually(Network expectedNetwork,
-                boolean expectBlocked) {
-            final long deadline = System.currentTimeMillis() + TEST_CALLBACK_TIMEOUT_MS;
-            do {
-                final CallbackInfo cb = nextCallback((int) (deadline - System.currentTimeMillis()));
-                if (cb.state == CallbackState.BLOCKED_STATUS
-                        && cb.network.equals(expectedNetwork)) {
-                    assertEquals(expectBlocked, cb.arg);
-                    return;
-                }
-            } while (System.currentTimeMillis() <= deadline);
-            fail("Didn't receive onBlockedStatusChanged()");
-        }
-
-        public void expectCapabilitiesCallbackEventually(Network expectedNetwork, boolean hasCap,
-                int cap) {
-            final long deadline = System.currentTimeMillis() + TEST_CALLBACK_TIMEOUT_MS;
-            do {
-                final CallbackInfo cb = nextCallback((int) (deadline - System.currentTimeMillis()));
-                if (cb.state != CallbackState.CAPABILITIES
-                        || !expectedNetwork.equals(cb.network)
-                        || (hasCap != ((NetworkCapabilities) cb.arg).hasCapability(cap))) {
-                    Log.i("NetworkCallbackTest#expectCapabilitiesCallback",
-                            "Ignoring non-matching callback : " + cb);
-                    continue;
-                }
-                // Found a match, return
-                return;
-            } while (System.currentTimeMillis() <= deadline);
-            fail("Didn't receive the expected callback to onCapabilitiesChanged(). Check the "
-                    + "log for a list of received callbacks, if any.");
-        }
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-
-        assumeTrue(isActiveNetworkMetered(true) || canChangeActiveNetworkMeteredness());
-
-        registerBroadcastReceiver();
-
-        removeRestrictBackgroundWhitelist(mUid);
-        removeRestrictBackgroundBlacklist(mUid);
-        assertRestrictBackgroundChangedReceived(0);
-
-        // Initial state
-        setBatterySaverMode(false);
-        setRestrictBackground(false);
-
-        // Make wifi a metered network.
-        mMeterednessConfiguration.configureNetworkMeteredness(true);
-
-        // Register callback
-        registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback);
-        // Once the wifi is marked as metered, the wifi will reconnect. Wait for onAvailable()
-        // callback to ensure wifi is connected before the test and store the default network.
-        mNetwork = mTestNetworkCallback.expectAvailableCallbackAndGetNetwork();
-        // Check that the network is metered.
-        mTestNetworkCallback.expectCapabilitiesCallbackEventually(mNetwork,
-                false /* hasCapability */, NET_CAPABILITY_NOT_METERED);
-        mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        super.tearDown();
-
-        setRestrictBackground(false);
-        setBatterySaverMode(false);
-        unregisterNetworkCallback();
-    }
-
-    @RequiredProperties({DATA_SAVER_MODE})
-    @Test
-    public void testOnBlockedStatusChanged_dataSaver() throws Exception {
-        try {
-            // Enable restrict background
-            setRestrictBackground(true);
-            assertBackgroundNetworkAccess(false);
-            mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, true);
-
-            // Add to whitelist
-            addRestrictBackgroundWhitelist(mUid);
-            assertBackgroundNetworkAccess(true);
-            mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, false);
-
-            // Remove from whitelist
-            removeRestrictBackgroundWhitelist(mUid);
-            assertBackgroundNetworkAccess(false);
-            mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, true);
-        } finally {
-            mMeterednessConfiguration.resetNetworkMeteredness();
-        }
-
-        // Set to non-metered network
-        mMeterednessConfiguration.configureNetworkMeteredness(false);
-        mTestNetworkCallback.expectCapabilitiesCallbackEventually(mNetwork,
-                true /* hasCapability */, NET_CAPABILITY_NOT_METERED);
-        try {
-            assertBackgroundNetworkAccess(true);
-            mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, false);
-
-            // Disable restrict background, should not trigger callback
-            setRestrictBackground(false);
-            assertBackgroundNetworkAccess(true);
-        } finally {
-            mMeterednessConfiguration.resetNetworkMeteredness();
-        }
-    }
-
-    @RequiredProperties({BATTERY_SAVER_MODE})
-    @Test
-    public void testOnBlockedStatusChanged_powerSaver() throws Exception {
-        try {
-            // Enable Power Saver
-            setBatterySaverMode(true);
-            assertBackgroundNetworkAccess(false);
-            mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, true);
-
-            // Disable Power Saver
-            setBatterySaverMode(false);
-            assertBackgroundNetworkAccess(true);
-            mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, false);
-        } finally {
-            mMeterednessConfiguration.resetNetworkMeteredness();
-        }
-
-        // Set to non-metered network
-        mMeterednessConfiguration.configureNetworkMeteredness(false);
-        mTestNetworkCallback.expectCapabilitiesCallbackEventually(mNetwork,
-                true /* hasCapability */, NET_CAPABILITY_NOT_METERED);
-        try {
-            // Enable Power Saver
-            setBatterySaverMode(true);
-            assertBackgroundNetworkAccess(false);
-            mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, true);
-
-            // Disable Power Saver
-            setBatterySaverMode(false);
-            assertBackgroundNetworkAccess(true);
-            mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, false);
-        } finally {
-            mMeterednessConfiguration.resetNetworkMeteredness();
-        }
-    }
-
-    // TODO: 1. test against VPN lockdown.
-    //       2. test against multiple networks.
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestRunner.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestRunner.java
deleted file mode 100644
index f340907..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestRunner.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner;
-
-import org.junit.rules.RunRules;
-import org.junit.rules.TestRule;
-import org.junit.runners.model.FrameworkMethod;
-import org.junit.runners.model.InitializationError;
-import org.junit.runners.model.Statement;
-
-import java.util.List;
-
-/**
- * Custom runner to allow dumping logs after a test failure before the @After methods get to run.
- */
-public class NetworkPolicyTestRunner extends AndroidJUnit4ClassRunner {
-    private TestRule mDumpOnFailureRule = new DumpOnFailureRule();
-
-    public NetworkPolicyTestRunner(Class<?> klass) throws InitializationError {
-        super(klass);
-    }
-
-    @Override
-    public Statement methodInvoker(FrameworkMethod method, Object test) {
-        return new RunRules(super.methodInvoker(method, test), List.of(mDumpOnFailureRule),
-                describeChild(method));
-    }
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java
deleted file mode 100644
index 3807d79..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
-import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
-import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
-import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
-
-import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
-import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TAG;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.app.ActivityManager;
-import android.app.Instrumentation;
-import android.content.Context;
-import android.location.LocationManager;
-import android.net.ConnectivityManager;
-import android.net.ConnectivityManager.NetworkCallback;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.wifi.WifiManager;
-import android.os.Process;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Pair;
-
-import com.android.compatibility.common.util.AppStandbyUtils;
-import com.android.compatibility.common.util.BatteryUtils;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import androidx.test.platform.app.InstrumentationRegistry;
-
-public class NetworkPolicyTestUtils {
-
-    private static final int TIMEOUT_CHANGE_METEREDNESS_MS = 5000;
-
-    private static ConnectivityManager mCm;
-    private static WifiManager mWm;
-
-    private static Boolean mBatterySaverSupported;
-    private static Boolean mDataSaverSupported;
-    private static Boolean mDozeModeSupported;
-    private static Boolean mAppStandbySupported;
-
-    private NetworkPolicyTestUtils() {}
-
-    public static boolean isBatterySaverSupported() {
-        if (mBatterySaverSupported == null) {
-            mBatterySaverSupported = BatteryUtils.isBatterySaverSupported();
-        }
-        return mBatterySaverSupported;
-    }
-
-    /**
-     * As per CDD requirements, if the device doesn't support data saver mode then
-     * ConnectivityManager.getRestrictBackgroundStatus() will always return
-     * RESTRICT_BACKGROUND_STATUS_DISABLED. So, enable the data saver mode and check if
-     * ConnectivityManager.getRestrictBackgroundStatus() for an app in background returns
-     * RESTRICT_BACKGROUND_STATUS_DISABLED or not.
-     */
-    public static boolean isDataSaverSupported() {
-        if (mDataSaverSupported == null) {
-            assertMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED);
-            try {
-                setRestrictBackground(true);
-                mDataSaverSupported = !isMyRestrictBackgroundStatus(
-                        RESTRICT_BACKGROUND_STATUS_DISABLED);
-            } finally {
-                setRestrictBackground(false);
-            }
-        }
-        return mDataSaverSupported;
-    }
-
-    public static boolean isDozeModeSupported() {
-        if (mDozeModeSupported == null) {
-            final String result = executeShellCommand("cmd deviceidle enabled deep");
-            mDozeModeSupported = result.equals("1");
-        }
-        return mDozeModeSupported;
-    }
-
-    public static boolean isAppStandbySupported() {
-        if (mAppStandbySupported == null) {
-            mAppStandbySupported = AppStandbyUtils.isAppStandbyEnabled();
-        }
-        return mAppStandbySupported;
-    }
-
-    public static boolean isLowRamDevice() {
-        final ActivityManager am = (ActivityManager) getContext().getSystemService(
-                Context.ACTIVITY_SERVICE);
-        return am.isLowRamDevice();
-    }
-
-    public static boolean isLocationEnabled() {
-        final LocationManager lm = (LocationManager) getContext().getSystemService(
-                Context.LOCATION_SERVICE);
-        return lm.isLocationEnabled();
-    }
-
-    public static void setLocationEnabled(boolean enabled) {
-        final LocationManager lm = (LocationManager) getContext().getSystemService(
-                Context.LOCATION_SERVICE);
-        lm.setLocationEnabledForUser(enabled, Process.myUserHandle());
-        assertEquals("Couldn't change location enabled state", lm.isLocationEnabled(), enabled);
-        Log.d(TAG, "Changed location enabled state to " + enabled);
-    }
-
-    public static boolean isActiveNetworkMetered(boolean metered) {
-        return getConnectivityManager().isActiveNetworkMetered() == metered;
-    }
-
-    public static boolean canChangeActiveNetworkMeteredness() {
-        final Network activeNetwork = getConnectivityManager().getActiveNetwork();
-        final NetworkCapabilities networkCapabilities
-                = getConnectivityManager().getNetworkCapabilities(activeNetwork);
-        return networkCapabilities.hasTransport(TRANSPORT_WIFI);
-    }
-
-    public static Pair<String, Boolean> setupMeteredNetwork(boolean metered) throws Exception {
-        if (isActiveNetworkMetered(metered)) {
-            return null;
-        }
-        final boolean isLocationEnabled = isLocationEnabled();
-        try {
-            if (!isLocationEnabled) {
-                setLocationEnabled(true);
-            }
-            final String ssid = unquoteSSID(getWifiManager().getConnectionInfo().getSSID());
-            assertNotEquals(WifiManager.UNKNOWN_SSID, ssid);
-            setWifiMeteredStatus(ssid, metered);
-            return Pair.create(ssid, !metered);
-        } finally {
-            // Reset the location enabled state
-            if (!isLocationEnabled) {
-                setLocationEnabled(false);
-            }
-        }
-    }
-
-    public static void resetMeteredNetwork(String ssid, boolean metered) throws Exception {
-        setWifiMeteredStatus(ssid, metered);
-    }
-
-    public static void setWifiMeteredStatus(String ssid, boolean metered) throws Exception {
-        assertFalse("SSID should not be empty", TextUtils.isEmpty(ssid));
-        final String cmd = "cmd netpolicy set metered-network " + ssid + " " + metered;
-        executeShellCommand(cmd);
-        assertWifiMeteredStatus(ssid, metered);
-        assertActiveNetworkMetered(metered);
-    }
-
-    public static void assertWifiMeteredStatus(String ssid, boolean expectedMeteredStatus) {
-        final String result = executeShellCommand("cmd netpolicy list wifi-networks");
-        final String expectedLine = ssid + ";" + expectedMeteredStatus;
-        assertTrue("Expected line: " + expectedLine + "; Actual result: " + result,
-                result.contains(expectedLine));
-    }
-
-    // Copied from cts/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
-    public static void assertActiveNetworkMetered(boolean expectedMeteredStatus) 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 == expectedMeteredStatus) {
-                    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.
-        getConnectivityManager().registerDefaultNetworkCallback(networkCallback);
-        if (!latch.await(TIMEOUT_CHANGE_METEREDNESS_MS, TimeUnit.MILLISECONDS)) {
-            fail("Timed out waiting for active network metered status to change to "
-                    + expectedMeteredStatus + " ; network = "
-                    + getConnectivityManager().getActiveNetwork());
-        }
-        getConnectivityManager().unregisterNetworkCallback(networkCallback);
-    }
-
-    public static void setRestrictBackground(boolean enabled) {
-        executeShellCommand("cmd netpolicy set restrict-background " + enabled);
-        final String output = executeShellCommand("cmd netpolicy get restrict-background");
-        final String expectedSuffix = enabled ? "enabled" : "disabled";
-        assertTrue("output '" + output + "' should end with '" + expectedSuffix + "'",
-                output.endsWith(expectedSuffix));
-    }
-
-    public static boolean isMyRestrictBackgroundStatus(int expectedStatus) {
-        final int actualStatus = getConnectivityManager().getRestrictBackgroundStatus();
-        if (expectedStatus != actualStatus) {
-            Log.d(TAG, "MyRestrictBackgroundStatus: "
-                    + "Expected: " + restrictBackgroundValueToString(expectedStatus)
-                    + "; Actual: " + restrictBackgroundValueToString(actualStatus));
-            return false;
-        }
-        return true;
-    }
-
-    // Copied from cts/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
-    private static 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;
-        }
-    }
-
-    public static String restrictBackgroundValueToString(int status) {
-        switch (status) {
-            case RESTRICT_BACKGROUND_STATUS_DISABLED:
-                return "DISABLED";
-            case RESTRICT_BACKGROUND_STATUS_WHITELISTED:
-                return "WHITELISTED";
-            case RESTRICT_BACKGROUND_STATUS_ENABLED:
-                return "ENABLED";
-            default:
-                return "UNKNOWN_STATUS_" + status;
-        }
-    }
-
-    public static String executeShellCommand(String command) {
-        final String result = runShellCommand(command).trim();
-        Log.d(TAG, "Output of '" + command + "': '" + result + "'");
-        return result;
-    }
-
-    public static void assertMyRestrictBackgroundStatus(int expectedStatus) {
-        final int actualStatus = getConnectivityManager().getRestrictBackgroundStatus();
-        assertEquals(restrictBackgroundValueToString(expectedStatus),
-                restrictBackgroundValueToString(actualStatus));
-    }
-
-    public static ConnectivityManager getConnectivityManager() {
-        if (mCm == null) {
-            mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
-        }
-        return mCm;
-    }
-
-    public static WifiManager getWifiManager() {
-        if (mWm == null) {
-            mWm = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
-        }
-        return mWm;
-    }
-
-    public static Context getContext() {
-        return getInstrumentation().getContext();
-    }
-
-    public static Instrumentation getInstrumentation() {
-        return InstrumentationRegistry.getInstrumentation();
-    }
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/PacketReflector.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/PacketReflector.java
deleted file mode 100644
index 124c2c3..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/PacketReflector.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-import static android.system.OsConstants.ICMP6_ECHO_REPLY;
-import static android.system.OsConstants.ICMP6_ECHO_REQUEST;
-import static android.system.OsConstants.ICMP_ECHO;
-import static android.system.OsConstants.ICMP_ECHOREPLY;
-
-import android.system.ErrnoException;
-import android.system.Os;
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-
-public class PacketReflector extends Thread {
-
-    private static int IPV4_HEADER_LENGTH = 20;
-    private static int IPV6_HEADER_LENGTH = 40;
-
-    private static int IPV4_ADDR_OFFSET = 12;
-    private static int IPV6_ADDR_OFFSET = 8;
-    private static int IPV4_ADDR_LENGTH = 4;
-    private static int IPV6_ADDR_LENGTH = 16;
-
-    private static int IPV4_PROTO_OFFSET = 9;
-    private static int IPV6_PROTO_OFFSET = 6;
-
-    private static final byte IPPROTO_ICMP = 1;
-    private static final byte IPPROTO_TCP = 6;
-    private static final byte IPPROTO_UDP = 17;
-    private static final byte IPPROTO_ICMPV6 = 58;
-
-    private static int ICMP_HEADER_LENGTH = 8;
-    private static int TCP_HEADER_LENGTH = 20;
-    private static int UDP_HEADER_LENGTH = 8;
-
-    private static final byte ICMP_ECHO = 8;
-    private static final byte ICMP_ECHOREPLY = 0;
-
-    private static String TAG = "PacketReflector";
-
-    private FileDescriptor mFd;
-    private byte[] mBuf;
-
-    public PacketReflector(FileDescriptor fd, int mtu) {
-        super("PacketReflector");
-        mFd = fd;
-        mBuf = new byte[mtu];
-    }
-
-    private static void swapBytes(byte[] buf, int pos1, int pos2, int len) {
-        for (int i = 0; i < len; i++) {
-            byte b = buf[pos1 + i];
-            buf[pos1 + i] = buf[pos2 + i];
-            buf[pos2 + i] = b;
-        }
-    }
-
-    private static void swapAddresses(byte[] buf, int version) {
-        int addrPos, addrLen;
-        switch(version) {
-            case 4:
-                addrPos = IPV4_ADDR_OFFSET;
-                addrLen = IPV4_ADDR_LENGTH;
-                break;
-            case 6:
-                addrPos = IPV6_ADDR_OFFSET;
-                addrLen = IPV6_ADDR_LENGTH;
-                break;
-            default:
-                throw new IllegalArgumentException();
-        }
-        swapBytes(buf, addrPos, addrPos + addrLen, addrLen);
-    }
-
-    // Reflect TCP packets: swap the source and destination addresses, but don't change the ports.
-    // This is used by the test to "connect to itself" through the VPN.
-    private void processTcpPacket(byte[] buf, int version, int len, int hdrLen) {
-        if (len < hdrLen + TCP_HEADER_LENGTH) {
-            return;
-        }
-
-        // Swap src and dst IP addresses.
-        swapAddresses(buf, version);
-
-        // Send the packet back.
-        writePacket(buf, len);
-    }
-
-    // Echo UDP packets: swap source and destination addresses, and source and destination ports.
-    // This is used by the test to check that the bytes it sends are echoed back.
-    private void processUdpPacket(byte[] buf, int version, int len, int hdrLen) {
-        if (len < hdrLen + UDP_HEADER_LENGTH) {
-            return;
-        }
-
-        // Swap src and dst IP addresses.
-        swapAddresses(buf, version);
-
-        // Swap dst and src ports.
-        int portOffset = hdrLen;
-        swapBytes(buf, portOffset, portOffset + 2, 2);
-
-        // Send the packet back.
-        writePacket(buf, len);
-    }
-
-    private void processIcmpPacket(byte[] buf, int version, int len, int hdrLen) {
-        if (len < hdrLen + ICMP_HEADER_LENGTH) {
-            return;
-        }
-
-        byte type = buf[hdrLen];
-        if (!(version == 4 && type == ICMP_ECHO) &&
-            !(version == 6 && type == (byte) ICMP6_ECHO_REQUEST)) {
-            return;
-        }
-
-        // Save the ping packet we received.
-        byte[] request = buf.clone();
-
-        // Swap src and dst IP addresses, and send the packet back.
-        // This effectively pings the device to see if it replies.
-        swapAddresses(buf, version);
-        writePacket(buf, len);
-
-        // The device should have replied, and buf should now contain a ping response.
-        int received = readPacket(buf);
-        if (received != len) {
-            Log.i(TAG, "Reflecting ping did not result in ping response: " +
-                       "read=" + received + " expected=" + len);
-            return;
-        }
-
-        byte replyType = buf[hdrLen];
-        if ((type == ICMP_ECHO && replyType != ICMP_ECHOREPLY)
-                || (type == (byte) ICMP6_ECHO_REQUEST && replyType != (byte) ICMP6_ECHO_REPLY)) {
-            Log.i(TAG, "Received unexpected ICMP reply: original " + type
-                    + ", reply " + replyType);
-            return;
-        }
-
-        // Compare the response we got with the original packet.
-        // The only thing that should have changed are addresses, type and checksum.
-        // Overwrite them with the received bytes and see if the packet is otherwise identical.
-        request[hdrLen] = buf[hdrLen];          // Type
-        request[hdrLen + 2] = buf[hdrLen + 2];  // Checksum byte 1.
-        request[hdrLen + 3] = buf[hdrLen + 3];  // Checksum byte 2.
-
-        // Since Linux kernel 4.2, net.ipv6.auto_flowlabels is set by default, and therefore
-        // the request and reply may have different IPv6 flow label: ignore that as well.
-        if (version == 6) {
-            request[1] = (byte)(request[1] & 0xf0 | buf[1] & 0x0f);
-            request[2] = buf[2];
-            request[3] = buf[3];
-        }
-
-        for (int i = 0; i < len; i++) {
-            if (buf[i] != request[i]) {
-                Log.i(TAG, "Received non-matching packet when expecting ping response.");
-                return;
-            }
-        }
-
-        // Now swap the addresses again and reflect the packet. This sends a ping reply.
-        swapAddresses(buf, version);
-        writePacket(buf, len);
-    }
-
-    private void writePacket(byte[] buf, int len) {
-        try {
-            Os.write(mFd, buf, 0, len);
-        } catch (ErrnoException|IOException e) {
-            Log.e(TAG, "Error writing packet: " + e.getMessage());
-        }
-    }
-
-    private int readPacket(byte[] buf) {
-        int len;
-        try {
-            len = Os.read(mFd, buf, 0, buf.length);
-        } catch (ErrnoException|IOException e) {
-            Log.e(TAG, "Error reading packet: " + e.getMessage());
-            len = -1;
-        }
-        return len;
-    }
-
-    // Reads one packet from our mFd, and possibly writes the packet back.
-    private void processPacket() {
-        int len = readPacket(mBuf);
-        if (len < 1) {
-            return;
-        }
-
-        int version = mBuf[0] >> 4;
-        int addrPos, protoPos, hdrLen, addrLen;
-        if (version == 4) {
-            hdrLen = IPV4_HEADER_LENGTH;
-            protoPos = IPV4_PROTO_OFFSET;
-            addrPos = IPV4_ADDR_OFFSET;
-            addrLen = IPV4_ADDR_LENGTH;
-        } else if (version == 6) {
-            hdrLen = IPV6_HEADER_LENGTH;
-            protoPos = IPV6_PROTO_OFFSET;
-            addrPos = IPV6_ADDR_OFFSET;
-            addrLen = IPV6_ADDR_LENGTH;
-        } else {
-            return;
-        }
-
-        if (len < hdrLen) {
-            return;
-        }
-
-        byte proto = mBuf[protoPos];
-        switch (proto) {
-            case IPPROTO_ICMP:
-            case IPPROTO_ICMPV6:
-                processIcmpPacket(mBuf, version, len, hdrLen);
-                break;
-            case IPPROTO_TCP:
-                processTcpPacket(mBuf, version, len, hdrLen);
-                break;
-            case IPPROTO_UDP:
-                processUdpPacket(mBuf, version, len, hdrLen);
-                break;
-        }
-    }
-
-    public void run() {
-        Log.i(TAG, "PacketReflector starting fd=" + mFd + " valid=" + mFd.valid());
-        while (!interrupted() && mFd.valid()) {
-            processPacket();
-        }
-        Log.i(TAG, "PacketReflector exiting fd=" + mFd + " valid=" + mFd.valid());
-    }
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/Property.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/Property.java
deleted file mode 100644
index 18805f9..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/Property.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.net.hostside;
-
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.canChangeActiveNetworkMeteredness;
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isActiveNetworkMetered;
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isAppStandbySupported;
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isBatterySaverSupported;
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isDataSaverSupported;
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isDozeModeSupported;
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isLowRamDevice;
-
-public enum Property {
-    BATTERY_SAVER_MODE(1 << 0) {
-        public boolean isSupported() { return isBatterySaverSupported(); }
-    },
-
-    DATA_SAVER_MODE(1 << 1) {
-        public boolean isSupported() { return isDataSaverSupported(); }
-    },
-
-    NO_DATA_SAVER_MODE(~DATA_SAVER_MODE.getValue()) {
-        public boolean isSupported() { return !isDataSaverSupported(); }
-    },
-
-    DOZE_MODE(1 << 2) {
-        public boolean isSupported() { return isDozeModeSupported(); }
-    },
-
-    APP_STANDBY_MODE(1 << 3) {
-        public boolean isSupported() { return isAppStandbySupported(); }
-    },
-
-    NOT_LOW_RAM_DEVICE(1 << 4) {
-        public boolean isSupported() { return !isLowRamDevice(); }
-    },
-
-    METERED_NETWORK(1 << 5) {
-        public boolean isSupported() {
-            return isActiveNetworkMetered(true) || canChangeActiveNetworkMeteredness();
-        }
-    },
-
-    NON_METERED_NETWORK(~METERED_NETWORK.getValue()) {
-        public boolean isSupported() {
-            return isActiveNetworkMetered(false) || canChangeActiveNetworkMeteredness();
-        }
-    };
-
-    private int mValue;
-
-    Property(int value) { mValue = value; }
-
-    public int getValue() { return mValue; }
-
-    abstract boolean isSupported();
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RemoteSocketFactoryClient.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RemoteSocketFactoryClient.java
deleted file mode 100644
index 80f99b6..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RemoteSocketFactoryClient.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.ConditionVariable;
-import android.os.IBinder;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.system.ErrnoException;
-import android.system.Os;
-
-import com.android.cts.net.hostside.IRemoteSocketFactory;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-
-public class RemoteSocketFactoryClient {
-    private static final int TIMEOUT_MS = 5000;
-    private static final String PACKAGE = RemoteSocketFactoryClient.class.getPackage().getName();
-    private static final String APP2_PACKAGE = PACKAGE + ".app2";
-    private static final String SERVICE_NAME = APP2_PACKAGE + ".RemoteSocketFactoryService";
-
-    private Context mContext;
-    private ServiceConnection mServiceConnection;
-    private IRemoteSocketFactory mService;
-
-    public RemoteSocketFactoryClient(Context context) {
-        mContext = context;
-    }
-
-    public void bind() {
-        if (mService != null) {
-            throw new IllegalStateException("Already bound");
-        }
-
-        final ConditionVariable cv = new ConditionVariable();
-        mServiceConnection = new ServiceConnection() {
-            @Override
-            public void onServiceConnected(ComponentName name, IBinder service) {
-                mService = IRemoteSocketFactory.Stub.asInterface(service);
-                cv.open();
-            }
-            @Override
-            public void onServiceDisconnected(ComponentName name) {
-                mService = null;
-            }
-        };
-
-        final Intent intent = new Intent();
-        intent.setComponent(new ComponentName(APP2_PACKAGE, SERVICE_NAME));
-        mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
-        cv.block(TIMEOUT_MS);
-        if (mService == null) {
-            throw new IllegalStateException(
-                    "Could not bind to RemoteSocketFactory service after " + TIMEOUT_MS + "ms");
-        }
-    }
-
-    public void unbind() {
-        if (mService != null) {
-            mContext.unbindService(mServiceConnection);
-        }
-    }
-
-    public FileDescriptor openSocketFd(String host, int port, int timeoutMs)
-            throws RemoteException, ErrnoException, IOException {
-        // Dup the filedescriptor so ParcelFileDescriptor's finalizer doesn't garbage collect it
-        // and cause our fd to become invalid. http://b/35927643 .
-        ParcelFileDescriptor pfd = mService.openSocketFd(host, port, timeoutMs);
-        FileDescriptor fd = Os.dup(pfd.getFileDescriptor());
-        pfd.close();
-        return fd;
-    }
-
-    public String getPackageName() throws RemoteException {
-        return mService.getPackageName();
-    }
-
-    public int getUid() throws RemoteException {
-        return mService.getUid();
-    }
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredProperties.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredProperties.java
deleted file mode 100644
index 96838bb..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredProperties.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.net.hostside;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-@Retention(RUNTIME)
-@Target({METHOD, TYPE})
-@Inherited
-public @interface RequiredProperties {
-    Property[] value();
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java
deleted file mode 100644
index 01f9f3e..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.net.hostside;
-
-import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TAG;
-
-import android.text.TextUtils;
-import android.util.ArraySet;
-import android.util.Log;
-
-import com.android.compatibility.common.util.BeforeAfterRule;
-
-import org.junit.Assume;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-import java.util.ArrayList;
-import java.util.Collections;
-
-public class RequiredPropertiesRule extends BeforeAfterRule {
-
-    private static ArraySet<Property> mRequiredProperties;
-
-    @Override
-    public void onBefore(Statement base, Description description) {
-        mRequiredProperties = getAllRequiredProperties(description);
-
-        final String testName = description.getClassName() + "#" + description.getMethodName();
-        assertTestIsValid(testName, mRequiredProperties);
-        Log.i(TAG, "Running test " + testName + " with required properties: "
-                + propertiesToString(mRequiredProperties));
-    }
-
-    private ArraySet<Property> getAllRequiredProperties(Description description) {
-        final ArraySet<Property> allRequiredProperties = new ArraySet<>();
-        RequiredProperties requiredProperties = description.getAnnotation(RequiredProperties.class);
-        if (requiredProperties != null) {
-            Collections.addAll(allRequiredProperties, requiredProperties.value());
-        }
-
-        for (Class<?> clazz = description.getTestClass();
-                clazz != null; clazz = clazz.getSuperclass()) {
-            requiredProperties = clazz.getDeclaredAnnotation(RequiredProperties.class);
-            if (requiredProperties == null) {
-                continue;
-            }
-            for (Property requiredProperty : requiredProperties.value()) {
-                for (Property p : Property.values()) {
-                    if (p.getValue() == ~requiredProperty.getValue()
-                            && allRequiredProperties.contains(p)) {
-                        continue;
-                    }
-                }
-                allRequiredProperties.add(requiredProperty);
-            }
-        }
-        return allRequiredProperties;
-    }
-
-    private void assertTestIsValid(String testName, ArraySet<Property> requiredProperies) {
-        if (requiredProperies == null) {
-            return;
-        }
-        final ArrayList<Property> unsupportedProperties = new ArrayList<>();
-        for (Property property : requiredProperies) {
-            if (!property.isSupported()) {
-                unsupportedProperties.add(property);
-            }
-        }
-        Assume.assumeTrue("Unsupported properties: "
-                + propertiesToString(unsupportedProperties), unsupportedProperties.isEmpty());
-    }
-
-    public static ArraySet<Property> getRequiredProperties() {
-        return mRequiredProperties;
-    }
-
-    private static String propertiesToString(Iterable<Property> properties) {
-        return "[" + TextUtils.join(",", properties) + "]";
-    }
-}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
deleted file mode 100755
index a451ea8..0000000
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
+++ /dev/null
@@ -1,1090 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside;
-
-import static android.os.Process.INVALID_UID;
-import static android.system.OsConstants.*;
-
-import android.annotation.Nullable;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-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.NetworkRequest;
-import android.net.Proxy;
-import android.net.ProxyInfo;
-import android.net.VpnService;
-import android.net.wifi.WifiManager;
-import android.provider.Settings;
-import android.os.ParcelFileDescriptor;
-import android.os.Process;
-import android.os.SystemProperties;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject;
-import android.support.test.uiautomator.UiSelector;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.OsConstants;
-import android.system.StructPollfd;
-import android.test.InstrumentationTestCase;
-import android.test.MoreAsserts;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.compatibility.common.util.BlockingBroadcastReceiver;
-
-import java.io.Closeable;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.DatagramPacket;
-import java.net.DatagramSocket;
-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.net.UnknownHostException;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Objects;
-import java.util.Random;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Tests for the VpnService API.
- *
- * These tests establish a VPN via the VpnService API, and have the service reflect the packets back
- * to the device without causing any network traffic. This allows testing the local VPN data path
- * without a network connection or a VPN server.
- *
- * Note: in Lollipop, VPN functionality relies on kernel support for UID-based routing. If these
- * tests fail, it may be due to the lack of kernel support. The necessary patches can be
- * cherry-picked from the Android common kernel trees:
- *
- * android-3.10:
- *   https://android-review.googlesource.com/#/c/99220/
- *   https://android-review.googlesource.com/#/c/100545/
- *
- * android-3.4:
- *   https://android-review.googlesource.com/#/c/99225/
- *   https://android-review.googlesource.com/#/c/100557/
- *
- * To ensure that the kernel has the required commits, run the kernel unit
- * tests described at:
- *
- *   https://source.android.com/devices/tech/config/kernel_network_tests.html
- *
- */
-public class VpnTest extends InstrumentationTestCase {
-
-    // These are neither public nor @TestApi.
-    // TODO: add them to @TestApi.
-    private static final String PRIVATE_DNS_MODE_SETTING = "private_dns_mode";
-    private static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = "hostname";
-    private static final String PRIVATE_DNS_MODE_OPPORTUNISTIC = "opportunistic";
-    private static final String PRIVATE_DNS_SPECIFIER_SETTING = "private_dns_specifier";
-
-    public static String TAG = "VpnTest";
-    public static int TIMEOUT_MS = 3 * 1000;
-    public static int SOCKET_TIMEOUT_MS = 100;
-    public static String TEST_HOST = "connectivitycheck.gstatic.com";
-
-    private UiDevice mDevice;
-    private MyActivity mActivity;
-    private String mPackageName;
-    private ConnectivityManager mCM;
-    private WifiManager mWifiManager;
-    private RemoteSocketFactoryClient mRemoteSocketFactoryClient;
-
-    Network mNetwork;
-    NetworkCallback mCallback;
-    final Object mLock = new Object();
-    final Object mLockShutdown = new Object();
-
-    private String mOldPrivateDnsMode;
-    private String mOldPrivateDnsSpecifier;
-
-    private boolean supportedHardware() {
-        final PackageManager pm = getInstrumentation().getContext().getPackageManager();
-        return !pm.hasSystemFeature("android.hardware.type.watch");
-    }
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-
-        mNetwork = null;
-        mCallback = null;
-        storePrivateDnsSetting();
-
-        mDevice = UiDevice.getInstance(getInstrumentation());
-        mActivity = launchActivity(getInstrumentation().getTargetContext().getPackageName(),
-                MyActivity.class, null);
-        mPackageName = mActivity.getPackageName();
-        mCM = (ConnectivityManager) mActivity.getSystemService(Context.CONNECTIVITY_SERVICE);
-        mWifiManager = (WifiManager) mActivity.getSystemService(Context.WIFI_SERVICE);
-        mRemoteSocketFactoryClient = new RemoteSocketFactoryClient(mActivity);
-        mRemoteSocketFactoryClient.bind();
-        mDevice.waitForIdle();
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        restorePrivateDnsSetting();
-        mRemoteSocketFactoryClient.unbind();
-        if (mCallback != null) {
-            mCM.unregisterNetworkCallback(mCallback);
-        }
-        Log.i(TAG, "Stopping VPN");
-        stopVpn();
-        mActivity.finish();
-        super.tearDown();
-    }
-
-    private void prepareVpn() throws Exception {
-        final int REQUEST_ID = 42;
-
-        // Attempt to prepare.
-        Log.i(TAG, "Preparing VPN");
-        Intent intent = VpnService.prepare(mActivity);
-
-        if (intent != null) {
-            // Start the confirmation dialog and click OK.
-            mActivity.startActivityForResult(intent, REQUEST_ID);
-            mDevice.waitForIdle();
-
-            String packageName = intent.getComponent().getPackageName();
-            String resourceIdRegex = "android:id/button1$|button_start_vpn";
-            final UiObject okButton = new UiObject(new UiSelector()
-                    .className("android.widget.Button")
-                    .packageName(packageName)
-                    .resourceIdMatches(resourceIdRegex));
-            if (okButton.waitForExists(TIMEOUT_MS) == false) {
-                mActivity.finishActivity(REQUEST_ID);
-                fail("VpnService.prepare returned an Intent for '" + intent.getComponent() + "' " +
-                     "to display the VPN confirmation dialog, but this test could not find the " +
-                     "button to allow the VPN application to connect. Please ensure that the "  +
-                     "component displays a button with a resource ID matching the regexp: '" +
-                     resourceIdRegex + "'.");
-            }
-
-            // Click the button and wait for RESULT_OK.
-            okButton.click();
-            try {
-                int result = mActivity.getResult(TIMEOUT_MS);
-                if (result != MyActivity.RESULT_OK) {
-                    fail("The VPN confirmation dialog did not return RESULT_OK when clicking on " +
-                         "the button matching the regular expression '" + resourceIdRegex +
-                         "' of " + intent.getComponent() + "'. Please ensure that clicking on " +
-                         "that button allows the VPN application to connect. " +
-                         "Return value: " + result);
-                }
-            } catch (InterruptedException e) {
-                fail("VPN confirmation dialog did not return after " + TIMEOUT_MS + "ms");
-            }
-
-            // Now we should be prepared.
-            intent = VpnService.prepare(mActivity);
-            if (intent != null) {
-                fail("VpnService.prepare returned non-null even after the VPN dialog " +
-                     intent.getComponent() + "returned RESULT_OK.");
-            }
-        }
-    }
-
-    // TODO: Consider replacing arguments with a Builder.
-    private void startVpn(
-        String[] addresses, String[] routes, String allowedApplications,
-        String disallowedApplications, @Nullable ProxyInfo proxyInfo,
-        @Nullable ArrayList<Network> underlyingNetworks, boolean isAlwaysMetered) throws Exception {
-        prepareVpn();
-
-        // Register a callback so we will be notified when our VPN comes up.
-        final NetworkRequest request = new NetworkRequest.Builder()
-                .addTransportType(NetworkCapabilities.TRANSPORT_VPN)
-                .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
-                .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build();
-        mCallback = new NetworkCallback() {
-            public void onAvailable(Network network) {
-                synchronized (mLock) {
-                    Log.i(TAG, "Got available callback for network=" + network);
-                    mNetwork = network;
-                    mLock.notify();
-                }
-            }
-        };
-        mCM.registerNetworkCallback(request, mCallback);  // Unregistered in tearDown.
-
-        // Start the service and wait up for TIMEOUT_MS ms for the VPN to come up.
-        Intent intent = new Intent(mActivity, MyVpnService.class)
-                .putExtra(mPackageName + ".cmd", "connect")
-                .putExtra(mPackageName + ".addresses", TextUtils.join(",", addresses))
-                .putExtra(mPackageName + ".routes", TextUtils.join(",", routes))
-                .putExtra(mPackageName + ".allowedapplications", allowedApplications)
-                .putExtra(mPackageName + ".disallowedapplications", disallowedApplications)
-                .putExtra(mPackageName + ".httpProxy", proxyInfo)
-                .putParcelableArrayListExtra(
-                    mPackageName + ".underlyingNetworks", underlyingNetworks)
-                .putExtra(mPackageName + ".isAlwaysMetered", isAlwaysMetered);
-
-        mActivity.startService(intent);
-        synchronized (mLock) {
-            if (mNetwork == null) {
-                 Log.i(TAG, "bf mLock");
-                 mLock.wait(TIMEOUT_MS);
-                 Log.i(TAG, "af mLock");
-            }
-        }
-
-        if (mNetwork == null) {
-            fail("VPN did not become available after " + TIMEOUT_MS + "ms");
-        }
-
-        // Unfortunately, when the available callback fires, the VPN UID ranges are not yet
-        // configured. Give the system some time to do so. http://b/18436087 .
-        try { Thread.sleep(3000); } catch(InterruptedException e) {}
-    }
-
-    private void stopVpn() {
-        // Register a callback so we will be notified when our VPN comes up.
-        final NetworkRequest request = new NetworkRequest.Builder()
-                .addTransportType(NetworkCapabilities.TRANSPORT_VPN)
-                .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
-                .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build();
-        mCallback = new NetworkCallback() {
-            public void onLost(Network network) {
-                synchronized (mLockShutdown) {
-                    Log.i(TAG, "Got lost callback for network=" + network
-                            + ",mNetwork = " + mNetwork);
-                    if( mNetwork == network){
-                        mLockShutdown.notify();
-                    }
-                }
-            }
-       };
-        mCM.registerNetworkCallback(request, mCallback);  // Unregistered in tearDown.
-        // Simply calling mActivity.stopService() won't stop the service, because the system binds
-        // to the service for the purpose of sending it a revoke command if another VPN comes up,
-        // and stopping a bound service has no effect. Instead, "start" the service again with an
-        // Intent that tells it to disconnect.
-        Intent intent = new Intent(mActivity, MyVpnService.class)
-                .putExtra(mPackageName + ".cmd", "disconnect");
-        mActivity.startService(intent);
-        synchronized (mLockShutdown) {
-            try {
-                 Log.i(TAG, "bf mLockShutdown");
-                 mLockShutdown.wait(TIMEOUT_MS);
-                 Log.i(TAG, "af mLockShutdown");
-            } catch(InterruptedException e) {}
-        }
-    }
-
-    private static void closeQuietly(Closeable c) {
-        if (c != null) {
-            try {
-                c.close();
-            } catch (IOException e) {
-            }
-        }
-    }
-
-    private static void checkPing(String to) throws IOException, ErrnoException {
-        InetAddress address = InetAddress.getByName(to);
-        FileDescriptor s;
-        final int LENGTH = 64;
-        byte[] packet = new byte[LENGTH];
-        byte[] header;
-
-        // Construct a ping packet.
-        Random random = new Random();
-        random.nextBytes(packet);
-        if (address instanceof Inet6Address) {
-            s = Os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6);
-            header = new byte[] { (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00 };
-        } else {
-            // Note that this doesn't actually work due to http://b/18558481 .
-            s = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
-            header = new byte[] { (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x00 };
-        }
-        System.arraycopy(header, 0, packet, 0, header.length);
-
-        // Send the packet.
-        int port = random.nextInt(65534) + 1;
-        Os.connect(s, address, port);
-        Os.write(s, packet, 0, packet.length);
-
-        // Expect a reply.
-        StructPollfd pollfd = new StructPollfd();
-        pollfd.events = (short) POLLIN;  // "error: possible loss of precision"
-        pollfd.fd = s;
-        int ret = Os.poll(new StructPollfd[] { pollfd }, SOCKET_TIMEOUT_MS);
-        assertEquals("Expected reply after sending ping", 1, ret);
-
-        byte[] reply = new byte[LENGTH];
-        int read = Os.read(s, reply, 0, LENGTH);
-        assertEquals(LENGTH, read);
-
-        // Find out what the kernel set the ICMP ID to.
-        InetSocketAddress local = (InetSocketAddress) Os.getsockname(s);
-        port = local.getPort();
-        packet[4] = (byte) ((port >> 8) & 0xff);
-        packet[5] = (byte) (port & 0xff);
-
-        // Check the contents.
-        if (packet[0] == (byte) 0x80) {
-            packet[0] = (byte) 0x81;
-        } else {
-            packet[0] = 0;
-        }
-        // Zero out the checksum in the reply so it matches the uninitialized checksum in packet.
-        reply[2] = reply[3] = 0;
-        MoreAsserts.assertEquals(packet, reply);
-    }
-
-    // Writes data to out and checks that it appears identically on in.
-    private static void writeAndCheckData(
-            OutputStream out, InputStream in, byte[] data) throws IOException {
-        out.write(data, 0, data.length);
-        out.flush();
-
-        byte[] read = new byte[data.length];
-        int bytesRead = 0, totalRead = 0;
-        do {
-            bytesRead = in.read(read, totalRead, read.length - totalRead);
-            totalRead += bytesRead;
-        } while (bytesRead >= 0 && totalRead < data.length);
-        assertEquals(totalRead, data.length);
-        MoreAsserts.assertEquals(data, read);
-    }
-
-    private void checkTcpReflection(String to, String expectedFrom) throws IOException {
-        // Exercise TCP over the VPN by "connecting to ourselves". We open a server socket and a
-        // client socket, and connect the client socket to a remote host, with the port of the
-        // server socket. The PacketReflector reflects the packets, changing the source addresses
-        // but not the ports, so our client socket is connected to our server socket, though both
-        // sockets think their peers are on the "remote" IP address.
-
-        // Open a listening socket.
-        ServerSocket listen = new ServerSocket(0, 10, InetAddress.getByName("::"));
-
-        // Connect the client socket to it.
-        InetAddress toAddr = InetAddress.getByName(to);
-        Socket client = new Socket();
-        try {
-            client.connect(new InetSocketAddress(toAddr, listen.getLocalPort()), SOCKET_TIMEOUT_MS);
-            if (expectedFrom == null) {
-                closeQuietly(listen);
-                closeQuietly(client);
-                fail("Expected connection to fail, but it succeeded.");
-            }
-        } catch (IOException e) {
-            if (expectedFrom != null) {
-                closeQuietly(listen);
-                fail("Expected connection to succeed, but it failed.");
-            } else {
-                // We expected the connection to fail, and it did, so there's nothing more to test.
-                return;
-            }
-        }
-
-        // The connection succeeded, and we expected it to succeed. Send some data; if things are
-        // working, the data will be sent to the VPN, reflected by the PacketReflector, and arrive
-        // at our server socket. For good measure, send some data in the other direction.
-        Socket server = null;
-        try {
-            // Accept the connection on the server side.
-            listen.setSoTimeout(SOCKET_TIMEOUT_MS);
-            server = listen.accept();
-            checkConnectionOwnerUidTcp(client);
-            checkConnectionOwnerUidTcp(server);
-            // Check that the source and peer addresses are as expected.
-            assertEquals(expectedFrom, client.getLocalAddress().getHostAddress());
-            assertEquals(expectedFrom, server.getLocalAddress().getHostAddress());
-            assertEquals(
-                    new InetSocketAddress(toAddr, client.getLocalPort()),
-                    server.getRemoteSocketAddress());
-            assertEquals(
-                    new InetSocketAddress(toAddr, server.getLocalPort()),
-                    client.getRemoteSocketAddress());
-
-            // Now write some data.
-            final int LENGTH = 32768;
-            byte[] data = new byte[LENGTH];
-            new Random().nextBytes(data);
-
-            // Make sure our writes don't block or time out, because we're single-threaded and can't
-            // read and write at the same time.
-            server.setReceiveBufferSize(LENGTH * 2);
-            client.setSendBufferSize(LENGTH * 2);
-            client.setSoTimeout(SOCKET_TIMEOUT_MS);
-            server.setSoTimeout(SOCKET_TIMEOUT_MS);
-
-            // Send some data from client to server, then from server to client.
-            writeAndCheckData(client.getOutputStream(), server.getInputStream(), data);
-            writeAndCheckData(server.getOutputStream(), client.getInputStream(), data);
-        } finally {
-            closeQuietly(listen);
-            closeQuietly(client);
-            closeQuietly(server);
-        }
-    }
-
-    private void checkConnectionOwnerUidUdp(DatagramSocket s, boolean expectSuccess) {
-        final int expectedUid = expectSuccess ? Process.myUid() : INVALID_UID;
-        InetSocketAddress loc = new InetSocketAddress(s.getLocalAddress(), s.getLocalPort());
-        InetSocketAddress rem = new InetSocketAddress(s.getInetAddress(), s.getPort());
-        int uid = mCM.getConnectionOwnerUid(OsConstants.IPPROTO_UDP, loc, rem);
-        assertEquals(expectedUid, uid);
-    }
-
-    private void checkConnectionOwnerUidTcp(Socket s) {
-        final int expectedUid = Process.myUid();
-        InetSocketAddress loc = new InetSocketAddress(s.getLocalAddress(), s.getLocalPort());
-        InetSocketAddress rem = new InetSocketAddress(s.getInetAddress(), s.getPort());
-        int uid = mCM.getConnectionOwnerUid(OsConstants.IPPROTO_TCP, loc, rem);
-        assertEquals(expectedUid, uid);
-    }
-
-    private void checkUdpEcho(String to, String expectedFrom) throws IOException {
-        DatagramSocket s;
-        InetAddress address = InetAddress.getByName(to);
-        if (address instanceof Inet6Address) {  // http://b/18094870
-            s = new DatagramSocket(0, InetAddress.getByName("::"));
-        } else {
-            s = new DatagramSocket();
-        }
-        s.setSoTimeout(SOCKET_TIMEOUT_MS);
-
-        Random random = new Random();
-        byte[] data = new byte[random.nextInt(1650)];
-        random.nextBytes(data);
-        DatagramPacket p = new DatagramPacket(data, data.length);
-        s.connect(address, 7);
-
-        if (expectedFrom != null) {
-            assertEquals("Unexpected source address: ",
-                         expectedFrom, s.getLocalAddress().getHostAddress());
-        }
-
-        try {
-            if (expectedFrom != null) {
-                s.send(p);
-                checkConnectionOwnerUidUdp(s, true);
-                s.receive(p);
-                MoreAsserts.assertEquals(data, p.getData());
-            } else {
-                try {
-                    s.send(p);
-                    s.receive(p);
-                    fail("Received unexpected reply");
-                } catch (IOException expected) {
-                    checkConnectionOwnerUidUdp(s, false);
-                }
-            }
-        } finally {
-            s.close();
-        }
-    }
-
-    private void checkTrafficOnVpn() throws Exception {
-        checkUdpEcho("192.0.2.251", "192.0.2.2");
-        checkUdpEcho("2001:db8:dead:beef::f00", "2001:db8:1:2::ffe");
-        checkPing("2001:db8:dead:beef::f00");
-        checkTcpReflection("192.0.2.252", "192.0.2.2");
-        checkTcpReflection("2001:db8:dead:beef::f00", "2001:db8:1:2::ffe");
-    }
-
-    private void checkNoTrafficOnVpn() throws Exception {
-        checkUdpEcho("192.0.2.251", null);
-        checkUdpEcho("2001:db8:dead:beef::f00", null);
-        checkTcpReflection("192.0.2.252", null);
-        checkTcpReflection("2001:db8:dead:beef::f00", null);
-    }
-
-    private FileDescriptor openSocketFd(String host, int port, int timeoutMs) throws Exception {
-        Socket s = new Socket(host, port);
-        s.setSoTimeout(timeoutMs);
-        // Dup the filedescriptor so ParcelFileDescriptor's finalizer doesn't garbage collect it
-        // and cause our fd to become invalid. http://b/35927643 .
-        FileDescriptor fd = Os.dup(ParcelFileDescriptor.fromSocket(s).getFileDescriptor());
-        s.close();
-        return fd;
-    }
-
-    private FileDescriptor openSocketFdInOtherApp(
-            String host, int port, int timeoutMs) throws Exception {
-        Log.d(TAG, String.format("Creating test socket in UID=%d, my UID=%d",
-                mRemoteSocketFactoryClient.getUid(), Os.getuid()));
-        FileDescriptor fd = mRemoteSocketFactoryClient.openSocketFd(host, port, TIMEOUT_MS);
-        return fd;
-    }
-
-    private void sendRequest(FileDescriptor fd, String host) throws Exception {
-        String request = "GET /generate_204 HTTP/1.1\r\n" +
-                "Host: " + host + "\r\n" +
-                "Connection: keep-alive\r\n\r\n";
-        byte[] requestBytes = request.getBytes(StandardCharsets.UTF_8);
-        int ret = Os.write(fd, requestBytes, 0, requestBytes.length);
-        Log.d(TAG, "Wrote " + ret + "bytes");
-
-        String expected = "HTTP/1.1 204 No Content\r\n";
-        byte[] response = new byte[expected.length()];
-        Os.read(fd, response, 0, response.length);
-
-        String actual = new String(response, StandardCharsets.UTF_8);
-        assertEquals(expected, actual);
-        Log.d(TAG, "Got response: " + actual);
-    }
-
-    private void assertSocketStillOpen(FileDescriptor fd, String host) throws Exception {
-        try {
-            assertTrue(fd.valid());
-            sendRequest(fd, host);
-            assertTrue(fd.valid());
-        } finally {
-            Os.close(fd);
-        }
-    }
-
-    private void assertSocketClosed(FileDescriptor fd, String host) throws Exception {
-        try {
-            assertTrue(fd.valid());
-            sendRequest(fd, host);
-            fail("Socket opened before VPN connects should be closed when VPN connects");
-        } catch (ErrnoException expected) {
-            assertEquals(ECONNABORTED, expected.errno);
-            assertTrue(fd.valid());
-        } finally {
-            Os.close(fd);
-        }
-    }
-
-    private ContentResolver getContentResolver() {
-        return getInstrumentation().getContext().getContentResolver();
-    }
-
-    private boolean isPrivateDnsInStrictMode() {
-        return PRIVATE_DNS_MODE_PROVIDER_HOSTNAME.equals(
-                Settings.Global.getString(getContentResolver(), PRIVATE_DNS_MODE_SETTING));
-    }
-
-    private void storePrivateDnsSetting() {
-        mOldPrivateDnsMode = Settings.Global.getString(getContentResolver(),
-                PRIVATE_DNS_MODE_SETTING);
-        mOldPrivateDnsSpecifier = Settings.Global.getString(getContentResolver(),
-                PRIVATE_DNS_SPECIFIER_SETTING);
-    }
-
-    private void restorePrivateDnsSetting() {
-        Settings.Global.putString(getContentResolver(), PRIVATE_DNS_MODE_SETTING,
-                mOldPrivateDnsMode);
-        Settings.Global.putString(getContentResolver(), PRIVATE_DNS_SPECIFIER_SETTING,
-                mOldPrivateDnsSpecifier);
-    }
-
-    // TODO: replace with CtsNetUtils.awaitPrivateDnsSetting in Q or above.
-    private void expectPrivateDnsHostname(final String hostname) throws Exception {
-        final NetworkRequest request = new NetworkRequest.Builder()
-                .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
-                .build();
-        final CountDownLatch latch = new CountDownLatch(1);
-        final NetworkCallback callback = new NetworkCallback() {
-            @Override
-            public void onLinkPropertiesChanged(Network network, LinkProperties lp) {
-                if (network.equals(mNetwork) &&
-                        Objects.equals(lp.getPrivateDnsServerName(), hostname)) {
-                    latch.countDown();
-                }
-            }
-        };
-
-        mCM.registerNetworkCallback(request, callback);
-
-        try {
-            assertTrue("Private DNS hostname was not " + hostname + " after " + TIMEOUT_MS + "ms",
-                    latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        } finally {
-            mCM.unregisterNetworkCallback(callback);
-        }
-    }
-
-    private void setAndVerifyPrivateDns(boolean strictMode) throws Exception {
-        final ContentResolver cr = getInstrumentation().getContext().getContentResolver();
-        String privateDnsHostname;
-
-        if (strictMode) {
-            privateDnsHostname = "vpncts-nx.metric.gstatic.com";
-            Settings.Global.putString(cr, PRIVATE_DNS_SPECIFIER_SETTING, privateDnsHostname);
-            Settings.Global.putString(cr, PRIVATE_DNS_MODE_SETTING,
-                    PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
-        } else {
-            Settings.Global.putString(cr, PRIVATE_DNS_MODE_SETTING, PRIVATE_DNS_MODE_OPPORTUNISTIC);
-            privateDnsHostname = null;
-        }
-
-        expectPrivateDnsHostname(privateDnsHostname);
-
-        String randomName = "vpncts-" + new Random().nextInt(1000000000) + "-ds.metric.gstatic.com";
-        if (strictMode) {
-            // Strict mode private DNS is enabled. DNS lookups should fail, because the private DNS
-            // server name is invalid.
-            try {
-                InetAddress.getByName(randomName);
-                fail("VPN DNS lookup should fail with private DNS enabled");
-            } catch (UnknownHostException expected) {
-            }
-        } else {
-            // Strict mode private DNS is disabled. DNS lookup should succeed, because the VPN
-            // provides no DNS servers, and thus DNS falls through to the default network.
-            assertNotNull("VPN DNS lookup should succeed with private DNS disabled",
-                    InetAddress.getByName(randomName));
-        }
-    }
-
-    // Tests that strict mode private DNS is used on VPNs.
-    private void checkStrictModePrivateDns() throws Exception {
-        final boolean initialMode = isPrivateDnsInStrictMode();
-        setAndVerifyPrivateDns(!initialMode);
-        setAndVerifyPrivateDns(initialMode);
-    }
-
-    public void testDefault() throws Exception {
-        if (!supportedHardware()) return;
-        // If adb TCP port opened, this test may running by adb over network.
-        // All of socket would be destroyed in this test. So this test don't
-        // support adb over network, see b/119382723.
-        if (SystemProperties.getInt("persist.adb.tcp.port", -1) > -1
-                || SystemProperties.getInt("service.adb.tcp.port", -1) > -1) {
-            Log.i(TAG, "adb is running over the network, so skip this test");
-            return;
-        }
-
-        final BlockingBroadcastReceiver receiver = new BlockingBroadcastReceiver(
-                getInstrumentation().getTargetContext(), MyVpnService.ACTION_ESTABLISHED);
-        receiver.register();
-
-        FileDescriptor fd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS);
-
-        startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
-                 new String[] {"0.0.0.0/0", "::/0"},
-                 "", "", null, null /* underlyingNetworks */, false /* isAlwaysMetered */);
-
-        final Intent intent = receiver.awaitForBroadcast(TimeUnit.MINUTES.toMillis(1));
-        assertNotNull("Failed to receive broadcast from VPN service", intent);
-        assertFalse("Wrong VpnService#isAlwaysOn",
-                intent.getBooleanExtra(MyVpnService.EXTRA_ALWAYS_ON, true));
-        assertFalse("Wrong VpnService#isLockdownEnabled",
-                intent.getBooleanExtra(MyVpnService.EXTRA_LOCKDOWN_ENABLED, true));
-
-        assertSocketClosed(fd, TEST_HOST);
-
-        checkTrafficOnVpn();
-
-        checkStrictModePrivateDns();
-
-        receiver.unregisterQuietly();
-    }
-
-    public void testAppAllowed() throws Exception {
-        if (!supportedHardware()) return;
-
-        FileDescriptor fd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS);
-
-        // Shell app must not be put in here or it would kill the ADB-over-network use case
-        String allowedApps = mRemoteSocketFactoryClient.getPackageName() + "," + mPackageName;
-        startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
-                 new String[] {"192.0.2.0/24", "2001:db8::/32"},
-                 allowedApps, "", null, null /* underlyingNetworks */, false /* isAlwaysMetered */);
-
-        assertSocketClosed(fd, TEST_HOST);
-
-        checkTrafficOnVpn();
-
-        checkStrictModePrivateDns();
-    }
-
-    public void testAppDisallowed() throws Exception {
-        if (!supportedHardware()) return;
-
-        FileDescriptor localFd = openSocketFd(TEST_HOST, 80, TIMEOUT_MS);
-        FileDescriptor remoteFd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS);
-
-        String disallowedApps = mRemoteSocketFactoryClient.getPackageName() + "," + mPackageName;
-        // If adb TCP port opened, this test may running by adb over TCP.
-        // Add com.android.shell appllication into blacklist to exclude adb socket for VPN test,
-        // see b/119382723.
-        // Note: The test don't support running adb over network for root device
-        disallowedApps = disallowedApps + ",com.android.shell";
-        Log.i(TAG, "Append shell app to disallowedApps: " + disallowedApps);
-        startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
-                 new String[] {"192.0.2.0/24", "2001:db8::/32"},
-                 "", disallowedApps, null, null /* underlyingNetworks */,
-                 false /* isAlwaysMetered */);
-
-        assertSocketStillOpen(localFd, TEST_HOST);
-        assertSocketStillOpen(remoteFd, TEST_HOST);
-
-        checkNoTrafficOnVpn();
-    }
-
-    public void testGetConnectionOwnerUidSecurity() throws Exception {
-        if (!supportedHardware()) return;
-
-        DatagramSocket s;
-        InetAddress address = InetAddress.getByName("localhost");
-        s = new DatagramSocket();
-        s.setSoTimeout(SOCKET_TIMEOUT_MS);
-        s.connect(address, 7);
-        InetSocketAddress loc = new InetSocketAddress(s.getLocalAddress(), s.getLocalPort());
-        InetSocketAddress rem = new InetSocketAddress(s.getInetAddress(), s.getPort());
-        try {
-            int uid = mCM.getConnectionOwnerUid(OsConstants.IPPROTO_TCP, loc, rem);
-            fail("Only an active VPN app may call this API.");
-        } catch (SecurityException expected) {
-            return;
-        }
-    }
-
-    public void testSetProxy() throws  Exception {
-        if (!supportedHardware()) return;
-        ProxyInfo initialProxy = mCM.getDefaultProxy();
-        // Receiver for the proxy change broadcast.
-        BlockingBroadcastReceiver proxyBroadcastReceiver = new ProxyChangeBroadcastReceiver();
-        proxyBroadcastReceiver.register();
-
-        String allowedApps = mPackageName;
-        ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("10.0.0.1", 8888);
-        startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
-                new String[] {"0.0.0.0/0", "::/0"}, allowedApps, "",
-                testProxyInfo, null /* underlyingNetworks */, false /* isAlwaysMetered */);
-
-        // Check that the proxy change broadcast is received
-        try {
-            assertNotNull("No proxy change was broadcast when VPN is connected.",
-                    proxyBroadcastReceiver.awaitForBroadcast());
-        } finally {
-            proxyBroadcastReceiver.unregisterQuietly();
-        }
-
-        // Proxy is set correctly in network and in link properties.
-        assertNetworkHasExpectedProxy(testProxyInfo, mNetwork);
-        assertDefaultProxy(testProxyInfo);
-
-        proxyBroadcastReceiver = new ProxyChangeBroadcastReceiver();
-        proxyBroadcastReceiver.register();
-        stopVpn();
-        try {
-            assertNotNull("No proxy change was broadcast when VPN was disconnected.",
-                    proxyBroadcastReceiver.awaitForBroadcast());
-        } finally {
-            proxyBroadcastReceiver.unregisterQuietly();
-        }
-
-        // After disconnecting from VPN, the proxy settings are the ones of the initial network.
-        assertDefaultProxy(initialProxy);
-    }
-
-    public void testSetProxyDisallowedApps() throws Exception {
-        if (!supportedHardware()) return;
-        ProxyInfo initialProxy = mCM.getDefaultProxy();
-
-        // If adb TCP port opened, this test may running by adb over TCP.
-        // Add com.android.shell appllication into blacklist to exclude adb socket for VPN test,
-        // see b/119382723.
-        // Note: The test don't support running adb over network for root device
-        String disallowedApps = mPackageName + ",com.android.shell";
-        ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("10.0.0.1", 8888);
-        startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
-                new String[] {"0.0.0.0/0", "::/0"}, "", disallowedApps,
-                testProxyInfo, null /* underlyingNetworks */, false /* isAlwaysMetered */);
-
-        // The disallowed app does has the proxy configs of the default network.
-        assertNetworkHasExpectedProxy(initialProxy, mCM.getActiveNetwork());
-        assertDefaultProxy(initialProxy);
-    }
-
-    public void testNoProxy() throws Exception {
-        if (!supportedHardware()) return;
-        ProxyInfo initialProxy = mCM.getDefaultProxy();
-        BlockingBroadcastReceiver proxyBroadcastReceiver = new ProxyChangeBroadcastReceiver();
-        proxyBroadcastReceiver.register();
-        String allowedApps = mPackageName;
-        startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
-                new String[] {"0.0.0.0/0", "::/0"}, allowedApps, "", null,
-                null /* underlyingNetworks */, false /* isAlwaysMetered */);
-
-        try {
-            assertNotNull("No proxy change was broadcast.",
-                    proxyBroadcastReceiver.awaitForBroadcast());
-        } finally {
-            proxyBroadcastReceiver.unregisterQuietly();
-        }
-
-        // The VPN network has no proxy set.
-        assertNetworkHasExpectedProxy(null, mNetwork);
-
-        proxyBroadcastReceiver = new ProxyChangeBroadcastReceiver();
-        proxyBroadcastReceiver.register();
-        stopVpn();
-        try {
-            assertNotNull("No proxy change was broadcast.",
-                    proxyBroadcastReceiver.awaitForBroadcast());
-        } finally {
-            proxyBroadcastReceiver.unregisterQuietly();
-        }
-        // After disconnecting from VPN, the proxy settings are the ones of the initial network.
-        assertDefaultProxy(initialProxy);
-        assertNetworkHasExpectedProxy(initialProxy, mCM.getActiveNetwork());
-    }
-
-    public void testBindToNetworkWithProxy() throws Exception {
-        if (!supportedHardware()) return;
-        String allowedApps = mPackageName;
-        Network initialNetwork = mCM.getActiveNetwork();
-        ProxyInfo initialProxy = mCM.getDefaultProxy();
-        ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("10.0.0.1", 8888);
-        // Receiver for the proxy change broadcast.
-        BlockingBroadcastReceiver proxyBroadcastReceiver = new ProxyChangeBroadcastReceiver();
-        proxyBroadcastReceiver.register();
-        startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
-                new String[] {"0.0.0.0/0", "::/0"}, allowedApps, "",
-                testProxyInfo, null /* underlyingNetworks */, false /* isAlwaysMetered */);
-
-        assertDefaultProxy(testProxyInfo);
-        mCM.bindProcessToNetwork(initialNetwork);
-        try {
-            assertNotNull("No proxy change was broadcast.",
-                proxyBroadcastReceiver.awaitForBroadcast());
-        } finally {
-            proxyBroadcastReceiver.unregisterQuietly();
-        }
-        assertDefaultProxy(initialProxy);
-    }
-
-    public void testVpnMeterednessWithNoUnderlyingNetwork() throws Exception {
-        if (!supportedHardware()) {
-            return;
-        }
-        // VPN is not routing any traffic i.e. its underlying networks is an empty array.
-        ArrayList<Network> underlyingNetworks = new ArrayList<>();
-        String allowedApps = mPackageName;
-
-        startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
-                new String[] {"0.0.0.0/0", "::/0"}, allowedApps, "", null,
-                underlyingNetworks, false /* isAlwaysMetered */);
-
-        // VPN should now be the active network.
-        assertEquals(mNetwork, mCM.getActiveNetwork());
-        assertVpnTransportContains(NetworkCapabilities.TRANSPORT_VPN);
-        // VPN with no underlying networks should be metered by default.
-        assertTrue(isNetworkMetered(mNetwork));
-        assertTrue(mCM.isActiveNetworkMetered());
-    }
-
-    public void testVpnMeterednessWithNullUnderlyingNetwork() throws Exception {
-        if (!supportedHardware()) {
-            return;
-        }
-        Network underlyingNetwork = mCM.getActiveNetwork();
-        if (underlyingNetwork == null) {
-            Log.i(TAG, "testVpnMeterednessWithNullUnderlyingNetwork cannot execute"
-                    + " unless there is an active network");
-            return;
-        }
-        // VPN tracks platform default.
-        ArrayList<Network> underlyingNetworks = null;
-        String allowedApps = mPackageName;
-
-        startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
-                new String[] {"0.0.0.0/0", "::/0"}, allowedApps, "", null,
-                underlyingNetworks, false /*isAlwaysMetered */);
-
-        // Ensure VPN transports contains underlying network's transports.
-        assertVpnTransportContains(underlyingNetwork);
-        // Its meteredness should be same as that of underlying network.
-        assertEquals(isNetworkMetered(underlyingNetwork), isNetworkMetered(mNetwork));
-        // Meteredness based on VPN capabilities and CM#isActiveNetworkMetered should be in sync.
-        assertEquals(isNetworkMetered(mNetwork), mCM.isActiveNetworkMetered());
-    }
-
-    public void testVpnMeterednessWithNonNullUnderlyingNetwork() throws Exception {
-        if (!supportedHardware()) {
-            return;
-        }
-        Network underlyingNetwork = mCM.getActiveNetwork();
-        if (underlyingNetwork == null) {
-            Log.i(TAG, "testVpnMeterednessWithNonNullUnderlyingNetwork cannot execute"
-                    + " unless there is an active network");
-            return;
-        }
-        // VPN explicitly declares WiFi to be its underlying network.
-        ArrayList<Network> underlyingNetworks = new ArrayList<>(1);
-        underlyingNetworks.add(underlyingNetwork);
-        String allowedApps = mPackageName;
-
-        startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
-                new String[] {"0.0.0.0/0", "::/0"}, allowedApps, "", null,
-                underlyingNetworks, false /* isAlwaysMetered */);
-
-        // Ensure VPN transports contains underlying network's transports.
-        assertVpnTransportContains(underlyingNetwork);
-        // Its meteredness should be same as that of underlying network.
-        assertEquals(isNetworkMetered(underlyingNetwork), isNetworkMetered(mNetwork));
-        // Meteredness based on VPN capabilities and CM#isActiveNetworkMetered should be in sync.
-        assertEquals(isNetworkMetered(mNetwork), mCM.isActiveNetworkMetered());
-    }
-
-    public void testAlwaysMeteredVpnWithNullUnderlyingNetwork() throws Exception {
-        if (!supportedHardware()) {
-            return;
-        }
-        Network underlyingNetwork = mCM.getActiveNetwork();
-        if (underlyingNetwork == null) {
-            Log.i(TAG, "testAlwaysMeteredVpnWithNullUnderlyingNetwork cannot execute"
-                    + " unless there is an active network");
-            return;
-        }
-        // VPN tracks platform default.
-        ArrayList<Network> underlyingNetworks = null;
-        String allowedApps = mPackageName;
-        boolean isAlwaysMetered = true;
-
-        startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
-                new String[] {"0.0.0.0/0", "::/0"}, allowedApps, "", null,
-                underlyingNetworks, isAlwaysMetered);
-
-        // VPN's meteredness does not depend on underlying network since it is always metered.
-        assertTrue(isNetworkMetered(mNetwork));
-        assertTrue(mCM.isActiveNetworkMetered());
-    }
-
-    public void testAlwaysMeteredVpnWithNonNullUnderlyingNetwork() throws Exception {
-        if (!supportedHardware()) {
-            return;
-        }
-        Network underlyingNetwork = mCM.getActiveNetwork();
-        if (underlyingNetwork == null) {
-            Log.i(TAG, "testAlwaysMeteredVpnWithNonNullUnderlyingNetwork cannot execute"
-                    + " unless there is an active network");
-            return;
-        }
-        // VPN explicitly declares its underlying network.
-        ArrayList<Network> underlyingNetworks = new ArrayList<>(1);
-        underlyingNetworks.add(underlyingNetwork);
-        String allowedApps = mPackageName;
-        boolean isAlwaysMetered = true;
-
-        startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
-                new String[] {"0.0.0.0/0", "::/0"}, allowedApps, "", null,
-                underlyingNetworks, isAlwaysMetered);
-
-        // VPN's meteredness does not depend on underlying network since it is always metered.
-        assertTrue(isNetworkMetered(mNetwork));
-        assertTrue(mCM.isActiveNetworkMetered());
-    }
-
-    public void testB141603906() throws Exception {
-        final InetSocketAddress src = new InetSocketAddress(0);
-        final InetSocketAddress dst = new InetSocketAddress(0);
-        final int NUM_THREADS = 8;
-        final int NUM_SOCKETS = 5000;
-        final Thread[] threads = new Thread[NUM_THREADS];
-        startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
-                 new String[] {"0.0.0.0/0", "::/0"},
-                 "" /* allowedApplications */, "com.android.shell" /* disallowedApplications */,
-                null /* proxyInfo */, null /* underlyingNetworks */, false /* isAlwaysMetered */);
-
-        for (int i = 0; i < NUM_THREADS; i++) {
-            threads[i] = new Thread(() -> {
-                for (int j = 0; j < NUM_SOCKETS; j++) {
-                    mCM.getConnectionOwnerUid(IPPROTO_TCP, src, dst);
-                }
-            });
-        }
-        for (Thread thread : threads) {
-            thread.start();
-        }
-        for (Thread thread : threads) {
-            thread.join();
-        }
-        stopVpn();
-    }
-
-    private boolean isNetworkMetered(Network network) {
-        NetworkCapabilities nc = mCM.getNetworkCapabilities(network);
-        return !nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
-    }
-
-    private void assertVpnTransportContains(Network underlyingNetwork) {
-        int[] transports = mCM.getNetworkCapabilities(underlyingNetwork).getTransportTypes();
-        assertVpnTransportContains(transports);
-    }
-
-    private void assertVpnTransportContains(int... transports) {
-        NetworkCapabilities vpnCaps = mCM.getNetworkCapabilities(mNetwork);
-        for (int transport : transports) {
-            assertTrue(vpnCaps.hasTransport(transport));
-        }
-    }
-
-    private void assertDefaultProxy(ProxyInfo expected) {
-        assertEquals("Incorrect proxy config.", expected, mCM.getDefaultProxy());
-        String expectedHost = expected == null ? null : expected.getHost();
-        String expectedPort = expected == null ? null : String.valueOf(expected.getPort());
-        assertEquals("Incorrect proxy host system property.", expectedHost,
-            System.getProperty("http.proxyHost"));
-        assertEquals("Incorrect proxy port system property.", expectedPort,
-            System.getProperty("http.proxyPort"));
-    }
-
-    private void assertNetworkHasExpectedProxy(ProxyInfo expected, Network network) {
-        LinkProperties lp = mCM.getLinkProperties(network);
-        assertNotNull("The network link properties object is null.", lp);
-        assertEquals("Incorrect proxy config.", expected, lp.getHttpProxy());
-
-        assertEquals(expected, mCM.getProxyForNetwork(network));
-    }
-
-    class ProxyChangeBroadcastReceiver extends BlockingBroadcastReceiver {
-        private boolean received;
-
-        public ProxyChangeBroadcastReceiver() {
-            super(VpnTest.this.getInstrumentation().getContext(), Proxy.PROXY_CHANGE_ACTION);
-            received = false;
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (!received) {
-                // Do not call onReceive() more than once.
-                super.onReceive(context, intent);
-            }
-            received = true;
-        }
-    }
-}
diff --git a/tests/cts/hostside/app2/Android.bp b/tests/cts/hostside/app2/Android.bp
deleted file mode 100644
index a6e9b11..0000000
--- a/tests/cts/hostside/app2/Android.bp
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// Copyright (C) 2016 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-android_test_helper_app {
-    name: "CtsHostsideNetworkTestsApp2",
-    defaults: ["cts_support_defaults"],
-    sdk_version: "current",
-    static_libs: ["CtsHostsideNetworkTestsAidl"],
-    srcs: ["src/**/*.java"],
-    // Tag this module as a cts test artifact
-    test_suites: [
-        "cts",
-        "vts10",
-        "general-tests",
-    ],
-    certificate: ":cts-net-app",
-}
diff --git a/tests/cts/hostside/app2/AndroidManifest.xml b/tests/cts/hostside/app2/AndroidManifest.xml
deleted file mode 100644
index ad270b3..0000000
--- a/tests/cts/hostside/app2/AndroidManifest.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="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" />
-
-    <!--
-         This application is used to listen to RESTRICT_BACKGROUND_CHANGED intents and store
-         them in a shared preferences which is then read by the test app. These broadcasts are
-         handled by 2 listeners, one defined the manifest and another dynamically registered by
-         a service.
-
-         The manifest-defined listener also handles ordered broadcasts used to share data with the
-         test app.
-
-         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 android:usesCleartextTraffic="true">
-        <activity android:name=".MyActivity" android:exported="true"/>
-        <service android:name=".MyService" android:exported="true"/>
-        <service android:name=".MyForegroundService" android:exported="true"/>
-        <service android:name=".RemoteSocketFactoryService" android:exported="true"/>
-
-        <receiver android:name=".MyBroadcastReceiver" >
-            <intent-filter>
-                <action android:name="android.net.conn.RESTRICT_BACKGROUND_CHANGED" />
-                <action android:name="com.android.cts.net.hostside.app2.action.GET_COUNTERS" />
-                <action android:name="com.android.cts.net.hostside.app2.action.GET_RESTRICT_BACKGROUND_STATUS" />
-                <action android:name="com.android.cts.net.hostside.app2.action.CHECK_NETWORK" />
-                <action android:name="com.android.cts.net.hostside.app2.action.SEND_NOTIFICATION" />
-                <action android:name="com.android.cts.net.hostside.app2.action.SHOW_TOAST" />
-                </intent-filter>
-        </receiver>
-    </application>
-
-</manifest>
diff --git a/tests/cts/hostside/app2/res/drawable/ic_notification.png b/tests/cts/hostside/app2/res/drawable/ic_notification.png
deleted file mode 100644
index 6ae570b..0000000
--- a/tests/cts/hostside/app2/res/drawable/ic_notification.png
+++ /dev/null
Binary files differ
diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java
deleted file mode 100644
index 351733e..0000000
--- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.net.hostside.app2;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.cts.net.hostside.INetworkStateObserver;
-
-public final class Common {
-
-    static final String TAG = "CtsNetApp2";
-
-    // Constants below must match values defined on app's
-    // AbstractRestrictBackgroundNetworkTestCase.java
-    static final String MANIFEST_RECEIVER = "ManifestReceiver";
-    static final String DYNAMIC_RECEIVER = "DynamicReceiver";
-
-    static final String ACTION_RECEIVER_READY =
-            "com.android.cts.net.hostside.app2.action.RECEIVER_READY";
-    static final String ACTION_FINISH_ACTIVITY =
-            "com.android.cts.net.hostside.app2.action.FINISH_ACTIVITY";
-    static final String ACTION_SHOW_TOAST =
-            "com.android.cts.net.hostside.app2.action.SHOW_TOAST";
-
-    static final String NOTIFICATION_TYPE_CONTENT = "CONTENT";
-    static final String NOTIFICATION_TYPE_DELETE = "DELETE";
-    static final String NOTIFICATION_TYPE_FULL_SCREEN = "FULL_SCREEN";
-    static final String NOTIFICATION_TYPE_BUNDLE = "BUNDLE";
-    static final String NOTIFICATION_TYPE_ACTION = "ACTION";
-    static final String NOTIFICATION_TYPE_ACTION_BUNDLE = "ACTION_BUNDLE";
-    static final String NOTIFICATION_TYPE_ACTION_REMOTE_INPUT = "ACTION_REMOTE_INPUT";
-
-    static final String TEST_PKG = "com.android.cts.net.hostside";
-    static final String KEY_NETWORK_STATE_OBSERVER = TEST_PKG + ".observer";
-
-    static int getUid(Context context) {
-        final String packageName = context.getPackageName();
-        try {
-            return context.getPackageManager().getPackageUid(packageName, 0);
-        } catch (NameNotFoundException e) {
-            throw new IllegalStateException("Could not get UID for " + packageName, e);
-        }
-    }
-
-    static void notifyNetworkStateObserver(Context context, Intent intent) {
-        if (intent == null) {
-            return;
-        }
-        final Bundle extras = intent.getExtras();
-        if (extras == null) {
-            return;
-        }
-        final INetworkStateObserver observer = INetworkStateObserver.Stub.asInterface(
-                extras.getBinder(KEY_NETWORK_STATE_OBSERVER));
-        if (observer != null) {
-            try {
-                if (!observer.isForeground()) {
-                    Log.e(TAG, "App didn't come to foreground");
-                    observer.onNetworkStateChecked(null);
-                    return;
-                }
-            } catch (RemoteException e) {
-                Log.e(TAG, "Error occurred while reading the proc state: " + e);
-            }
-            AsyncTask.execute(() -> {
-                try {
-                    observer.onNetworkStateChecked(
-                            MyBroadcastReceiver.checkNetworkStatus(context));
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Error occurred while notifying the observer: " + e);
-                }
-            });
-        }
-    }
-}
diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java
deleted file mode 100644
index 286cc2f..0000000
--- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.net.hostside.app2;
-
-import static com.android.cts.net.hostside.app2.Common.ACTION_FINISH_ACTIVITY;
-import static com.android.cts.net.hostside.app2.Common.TAG;
-import static com.android.cts.net.hostside.app2.Common.TEST_PKG;
-
-import android.app.Activity;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.cts.net.hostside.INetworkStateObserver;
-
-/**
- * Activity used to bring process to foreground.
- */
-public class MyActivity extends Activity {
-
-    private BroadcastReceiver finishCommandReceiver = null;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        Log.d(TAG, "MyActivity.onCreate()");
-        Common.notifyNetworkStateObserver(this, getIntent());
-        finishCommandReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                Log.d(TAG, "Finishing MyActivity");
-                MyActivity.this.finish();
-            }
-        };
-        registerReceiver(finishCommandReceiver, new IntentFilter(ACTION_FINISH_ACTIVITY));
-    }
-
-    @Override
-    public void finish() {
-        if (finishCommandReceiver != null) {
-            unregisterReceiver(finishCommandReceiver);
-        }
-        super.finish();
-    }
-
-    @Override
-    protected void onStart() {
-        super.onStart();
-        Log.d(TAG, "MyActivity.onStart()");
-    }
-
-    @Override
-    protected void onDestroy() {
-        Log.d(TAG, "MyActivity.onDestroy()");
-        super.onDestroy();
-    }
-}
diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java
deleted file mode 100644
index aa54075..0000000
--- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside.app2;
-
-import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
-
-import static com.android.cts.net.hostside.app2.Common.ACTION_RECEIVER_READY;
-import static com.android.cts.net.hostside.app2.Common.ACTION_SHOW_TOAST;
-import static com.android.cts.net.hostside.app2.Common.MANIFEST_RECEIVER;
-import static com.android.cts.net.hostside.app2.Common.NOTIFICATION_TYPE_ACTION;
-import static com.android.cts.net.hostside.app2.Common.NOTIFICATION_TYPE_ACTION_BUNDLE;
-import static com.android.cts.net.hostside.app2.Common.NOTIFICATION_TYPE_ACTION_REMOTE_INPUT;
-import static com.android.cts.net.hostside.app2.Common.NOTIFICATION_TYPE_BUNDLE;
-import static com.android.cts.net.hostside.app2.Common.NOTIFICATION_TYPE_CONTENT;
-import static com.android.cts.net.hostside.app2.Common.NOTIFICATION_TYPE_DELETE;
-import static com.android.cts.net.hostside.app2.Common.NOTIFICATION_TYPE_FULL_SCREEN;
-import static com.android.cts.net.hostside.app2.Common.TAG;
-import static com.android.cts.net.hostside.app2.Common.getUid;
-
-import android.app.Notification;
-import android.app.Notification.Action;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.RemoteInput;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.os.Bundle;
-import android.util.Log;
-import android.widget.Toast;
-
-import java.net.HttpURLConnection;
-import java.net.URL;
-
-/**
- * Receiver used to:
- * <ol>
- *   <li>Count number of {@code RESTRICT_BACKGROUND_CHANGED} broadcasts received.
- *   <li>Show a toast.
- * </ol>
- */
-public class MyBroadcastReceiver extends BroadcastReceiver {
-
-    private static final int NETWORK_TIMEOUT_MS = 5 * 1000;
-
-    private final String mName;
-
-    public MyBroadcastReceiver() {
-        this(MANIFEST_RECEIVER);
-    }
-
-    MyBroadcastReceiver(String name) {
-        Log.d(TAG, "Constructing MyBroadcastReceiver named " + name);
-        mName = name;
-    }
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        Log.d(TAG, "onReceive() for " + mName + ": " + intent);
-        final String action = intent.getAction();
-        switch (action) {
-            case ACTION_RESTRICT_BACKGROUND_CHANGED:
-                increaseCounter(context, action);
-                break;
-            case ACTION_RECEIVER_READY:
-                final String message = mName + " is ready to rumble";
-                Log.d(TAG, message);
-                setResultData(message);
-                break;
-            case ACTION_SHOW_TOAST:
-                showToast(context);
-                break;
-            default:
-                Log.e(TAG, "received unexpected action: " + action);
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "[MyBroadcastReceiver: mName=" + mName + "]";
-    }
-
-    private void increaseCounter(Context context, String action) {
-        final SharedPreferences prefs = context.getApplicationContext()
-                .getSharedPreferences(mName, Context.MODE_PRIVATE);
-        final int value = prefs.getInt(action, 0) + 1;
-        Log.d(TAG, "increaseCounter('" + action + "'): setting '" + mName + "' to " + value);
-        prefs.edit().putInt(action, value).apply();
-    }
-
-    static int getCounter(Context context, String action, String receiverName) {
-        final SharedPreferences prefs = context.getSharedPreferences(receiverName,
-                Context.MODE_PRIVATE);
-        final int value = prefs.getInt(action, 0);
-        Log.d(TAG, "getCounter('" + action + "', '" + receiverName + "'): " + value);
-        return value;
-    }
-
-    static String getRestrictBackgroundStatus(Context context) {
-        final ConnectivityManager cm = (ConnectivityManager) context
-                .getSystemService(Context.CONNECTIVITY_SERVICE);
-        final int apiStatus = cm.getRestrictBackgroundStatus();
-        Log.d(TAG, "getRestrictBackgroundStatus: returning " + apiStatus);
-        return String.valueOf(apiStatus);
-    }
-
-    private static final String NETWORK_STATUS_TEMPLATE = "%s|%s|%s|%s|%s";
-    /**
-     * Checks whether the network is available and return a string which can then be send as a
-     * result data for the ordered broadcast.
-     *
-     * <p>
-     * The string has the following format:
-     *
-     * <p><pre><code>
-     * NetinfoState|NetinfoDetailedState|RealConnectionCheck|RealConnectionCheckDetails|Netinfo
-     * </code></pre>
-     *
-     * <p>Where:
-     *
-     * <ul>
-     * <li>{@code NetinfoState}: enum value of {@link NetworkInfo.State}.
-     * <li>{@code NetinfoDetailedState}: enum value of {@link NetworkInfo.DetailedState}.
-     * <li>{@code RealConnectionCheck}: boolean value of a real connection check (i.e., an attempt
-     *     to access an external website.
-     * <li>{@code RealConnectionCheckDetails}: if HTTP output core or exception string of the real
-     *     connection attempt
-     * <li>{@code Netinfo}: string representation of the {@link NetworkInfo}.
-     * </ul>
-     *
-     * For example, if the connection was established fine, the result would be something like:
-     * <p><pre><code>
-     * CONNECTED|CONNECTED|true|200|[type: WIFI[], state: CONNECTED/CONNECTED, reason: ...]
-     * </code></pre>
-     *
-     */
-    // TODO: now that it uses Binder, it counl return a Bundle with the data parts instead...
-    static String checkNetworkStatus(Context context) {
-        final ConnectivityManager cm =
-                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
-        // TODO: connect to a hostside server instead
-        final String address = "http://example.com";
-        final NetworkInfo networkInfo = cm.getActiveNetworkInfo();
-        Log.d(TAG, "Running checkNetworkStatus() on thread "
-                + Thread.currentThread().getName() + " for UID " + getUid(context)
-                + "\n\tactiveNetworkInfo: " + networkInfo + "\n\tURL: " + address);
-        boolean checkStatus = false;
-        String checkDetails = "N/A";
-        try {
-            final URL url = new URL(address);
-            final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
-            conn.setReadTimeout(NETWORK_TIMEOUT_MS);
-            conn.setConnectTimeout(NETWORK_TIMEOUT_MS / 2);
-            conn.setRequestMethod("GET");
-            conn.setDoInput(true);
-            conn.connect();
-            final int response = conn.getResponseCode();
-            checkStatus = true;
-            checkDetails = "HTTP response for " + address + ": " + response;
-        } catch (Exception e) {
-            checkStatus = false;
-            checkDetails = "Exception getting " + address + ": " + e;
-        }
-        Log.d(TAG, checkDetails);
-        final String state, detailedState;
-        if (networkInfo != null) {
-            state = networkInfo.getState().name();
-            detailedState = networkInfo.getDetailedState().name();
-        } else {
-            state = detailedState = "null";
-        }
-        final String status = String.format(NETWORK_STATUS_TEMPLATE, state, detailedState,
-                Boolean.valueOf(checkStatus), checkDetails, networkInfo);
-        Log.d(TAG, "Offering " + status);
-        return status;
-    }
-
-    /**
-     * Sends a system notification containing actions with pending intents to launch the app's
-     * main activitiy or service.
-     */
-    static void sendNotification(Context context, String channelId, int notificationId,
-            String notificationType ) {
-        Log.d(TAG, "sendNotification: id=" + notificationId + ", type=" + notificationType);
-        final Intent serviceIntent = new Intent(context, MyService.class);
-        final PendingIntent pendingIntent = PendingIntent.getService(context, 0, serviceIntent,
-                notificationId);
-        final Bundle bundle = new Bundle();
-        bundle.putCharSequence("parcelable", "I am not");
-
-        final Notification.Builder builder = new Notification.Builder(context, channelId)
-                .setSmallIcon(R.drawable.ic_notification);
-
-        Action action = null;
-        switch (notificationType) {
-            case NOTIFICATION_TYPE_CONTENT:
-                builder
-                    .setContentTitle("Light, Cameras...")
-                    .setContentIntent(pendingIntent);
-                break;
-            case NOTIFICATION_TYPE_DELETE:
-                builder.setDeleteIntent(pendingIntent);
-                break;
-            case NOTIFICATION_TYPE_FULL_SCREEN:
-                builder.setFullScreenIntent(pendingIntent, true);
-                break;
-            case NOTIFICATION_TYPE_BUNDLE:
-                bundle.putParcelable("Magnum P.I. (Pending Intent)", pendingIntent);
-                builder.setExtras(bundle);
-                break;
-            case NOTIFICATION_TYPE_ACTION:
-                action = new Action.Builder(
-                        R.drawable.ic_notification, "ACTION", pendingIntent)
-                        .build();
-                builder.addAction(action);
-                break;
-            case NOTIFICATION_TYPE_ACTION_BUNDLE:
-                bundle.putParcelable("Magnum A.P.I. (Action Pending Intent)", pendingIntent);
-                action = new Action.Builder(
-                        R.drawable.ic_notification, "ACTION WITH BUNDLE", null)
-                        .addExtras(bundle)
-                        .build();
-                builder.addAction(action);
-                break;
-            case NOTIFICATION_TYPE_ACTION_REMOTE_INPUT:
-                bundle.putParcelable("Magnum R.I. (Remote Input)", null);
-                final RemoteInput remoteInput = new RemoteInput.Builder("RI")
-                    .addExtras(bundle)
-                    .build();
-                action = new Action.Builder(
-                        R.drawable.ic_notification, "ACTION WITH REMOTE INPUT", pendingIntent)
-                        .addRemoteInput(remoteInput)
-                        .build();
-                builder.addAction(action);
-                break;
-            default:
-                Log.e(TAG, "Unknown notification type: " + notificationType);
-                return;
-        }
-
-        final Notification notification = builder.build();
-        ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE))
-            .notify(notificationId, notification);
-    }
-
-    private void showToast(Context context) {
-        Toast.makeText(context, "Toast from CTS test", Toast.LENGTH_SHORT).show();
-        setResultData("Shown");
-    }
-}
diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java
deleted file mode 100644
index ff4ba65..0000000
--- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.net.hostside.app2;
-
-import static com.android.cts.net.hostside.app2.Common.TAG;
-import static com.android.cts.net.hostside.app2.Common.TEST_PKG;
-
-import android.R;
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.app.Service;
-import android.content.Intent;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.cts.net.hostside.INetworkStateObserver;
-
-/**
- * Service used to change app state to FOREGROUND_SERVICE.
- */
-public class MyForegroundService extends Service {
-    private static final String NOTIFICATION_CHANNEL_ID = "cts/MyForegroundService";
-    private static final int FLAG_START_FOREGROUND = 1;
-    private static final int FLAG_STOP_FOREGROUND = 2;
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return null;
-    }
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        Log.v(TAG, "MyForegroundService.onStartCommand(): " + intent);
-        NotificationManager notificationManager = getSystemService(NotificationManager.class);
-        notificationManager.createNotificationChannel(new NotificationChannel(
-                NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_ID,
-                NotificationManager.IMPORTANCE_DEFAULT));
-        switch (intent.getFlags()) {
-            case FLAG_START_FOREGROUND:
-                Log.d(TAG, "Starting foreground");
-                startForeground(42, new Notification.Builder(this, NOTIFICATION_CHANNEL_ID)
-                        .setSmallIcon(R.drawable.ic_dialog_alert) // any icon is fine
-                        .build());
-                Common.notifyNetworkStateObserver(this, intent);
-                break;
-            case FLAG_STOP_FOREGROUND:
-                Log.d(TAG, "Stopping foreground");
-                stopForeground(true);
-                break;
-            default:
-                Log.wtf(TAG, "Invalid flag on intent " + intent);
-        }
-        return START_STICKY;
-    }
-}
diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java
deleted file mode 100644
index 590e17e..0000000
--- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.net.hostside.app2;
-
-import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
-
-import static com.android.cts.net.hostside.app2.Common.ACTION_RECEIVER_READY;
-import static com.android.cts.net.hostside.app2.Common.DYNAMIC_RECEIVER;
-import static com.android.cts.net.hostside.app2.Common.TAG;
-
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.ConnectivityManager;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.cts.net.hostside.IMyService;
-import com.android.cts.net.hostside.INetworkCallback;
-
-/**
- * Service used to dynamically register a broadcast receiver.
- */
-public class MyService extends Service {
-    private static final String NOTIFICATION_CHANNEL_ID = "MyService";
-
-    ConnectivityManager mCm;
-
-    private MyBroadcastReceiver mReceiver;
-    private ConnectivityManager.NetworkCallback mNetworkCallback;
-
-    // TODO: move MyBroadcast static functions here - they were kept there to make git diff easier.
-
-    private IMyService.Stub mBinder =
-        new IMyService.Stub() {
-
-        @Override
-        public void registerBroadcastReceiver() {
-            if (mReceiver != null) {
-                Log.d(TAG, "receiver already registered: " + mReceiver);
-                return;
-            }
-            final Context context = getApplicationContext();
-            mReceiver = new MyBroadcastReceiver(DYNAMIC_RECEIVER);
-            context.registerReceiver(mReceiver, new IntentFilter(ACTION_RECEIVER_READY));
-            context.registerReceiver(mReceiver,
-                    new IntentFilter(ACTION_RESTRICT_BACKGROUND_CHANGED));
-            Log.d(TAG, "receiver registered");
-        }
-
-        @Override
-        public int getCounters(String receiverName, String action) {
-            return MyBroadcastReceiver.getCounter(getApplicationContext(), action, receiverName);
-        }
-
-        @Override
-        public String checkNetworkStatus() {
-            return MyBroadcastReceiver.checkNetworkStatus(getApplicationContext());
-        }
-
-        @Override
-        public String getRestrictBackgroundStatus() {
-            return MyBroadcastReceiver.getRestrictBackgroundStatus(getApplicationContext());
-        }
-
-        @Override
-        public void sendNotification(int notificationId, String notificationType) {
-            MyBroadcastReceiver .sendNotification(getApplicationContext(), NOTIFICATION_CHANNEL_ID,
-                    notificationId, notificationType);
-        }
-
-        @Override
-        public void registerNetworkCallback(INetworkCallback cb) {
-            if (mNetworkCallback != null) {
-                Log.d(TAG, "unregister previous network callback: " + mNetworkCallback);
-                unregisterNetworkCallback();
-            }
-            Log.d(TAG, "registering network callback");
-
-            mNetworkCallback = new ConnectivityManager.NetworkCallback() {
-                @Override
-                public void onBlockedStatusChanged(Network network, boolean blocked) {
-                    try {
-                        cb.onBlockedStatusChanged(network, blocked);
-                    } catch (RemoteException e) {
-                        Log.d(TAG, "Cannot send onBlockedStatusChanged: " + e);
-                        unregisterNetworkCallback();
-                    }
-                }
-
-                @Override
-                public void onAvailable(Network network) {
-                    try {
-                        cb.onAvailable(network);
-                    } catch (RemoteException e) {
-                        Log.d(TAG, "Cannot send onAvailable: " + e);
-                        unregisterNetworkCallback();
-                    }
-                }
-
-                @Override
-                public void onLost(Network network) {
-                    try {
-                        cb.onLost(network);
-                    } catch (RemoteException e) {
-                        Log.d(TAG, "Cannot send onLost: " + e);
-                        unregisterNetworkCallback();
-                    }
-                }
-
-                @Override
-                public void onCapabilitiesChanged(Network network, NetworkCapabilities cap) {
-                    try {
-                        cb.onCapabilitiesChanged(network, cap);
-                    } catch (RemoteException e) {
-                        Log.d(TAG, "Cannot send onCapabilitiesChanged: " + e);
-                        unregisterNetworkCallback();
-                    }
-                }
-            };
-            mCm.registerNetworkCallback(makeWifiNetworkRequest(), mNetworkCallback);
-            try {
-                cb.asBinder().linkToDeath(() -> unregisterNetworkCallback(), 0);
-            } catch (RemoteException e) {
-                unregisterNetworkCallback();
-            }
-        }
-
-        @Override
-        public void unregisterNetworkCallback() {
-            Log.d(TAG, "unregistering network callback");
-            if (mNetworkCallback != null) {
-                mCm.unregisterNetworkCallback(mNetworkCallback);
-                mNetworkCallback = null;
-            }
-        }
-      };
-
-    private NetworkRequest makeWifiNetworkRequest() {
-        return new NetworkRequest.Builder()
-                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build();
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return mBinder;
-    }
-
-    @Override
-    public void onCreate() {
-        final Context context = getApplicationContext();
-        ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE))
-                .createNotificationChannel(new NotificationChannel(NOTIFICATION_CHANNEL_ID,
-                        NOTIFICATION_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT));
-        mCm = (ConnectivityManager) getApplicationContext()
-                .getSystemService(Context.CONNECTIVITY_SERVICE);
-    }
-
-    @Override
-    public void onDestroy() {
-        final Context context = getApplicationContext();
-        ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE))
-                .deleteNotificationChannel(NOTIFICATION_CHANNEL_ID);
-        if (mReceiver != null) {
-            Log.d(TAG, "onDestroy(): unregistering " + mReceiver);
-            getApplicationContext().unregisterReceiver(mReceiver);
-        }
-
-        super.onDestroy();
-    }
-}
diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/RemoteSocketFactoryService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/RemoteSocketFactoryService.java
deleted file mode 100644
index b1b7d77..0000000
--- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/RemoteSocketFactoryService.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net.hostside.app2;
-
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.os.IBinder;
-import android.os.ParcelFileDescriptor;
-import android.os.Process;
-import android.util.Log;
-
-import com.android.cts.net.hostside.IRemoteSocketFactory;
-
-import java.net.Socket;
-
-
-public class RemoteSocketFactoryService extends Service {
-
-    private static final String TAG = RemoteSocketFactoryService.class.getSimpleName();
-
-    private IRemoteSocketFactory.Stub mBinder = new IRemoteSocketFactory.Stub() {
-        @Override
-        public ParcelFileDescriptor openSocketFd(String host, int port, int timeoutMs) {
-            try {
-                Socket s = new Socket(host, port);
-                s.setSoTimeout(timeoutMs);
-                return ParcelFileDescriptor.fromSocket(s);
-            } catch (Exception e) {
-                throw new IllegalArgumentException(e);
-            }
-        }
-
-        @Override
-        public String getPackageName() {
-            return RemoteSocketFactoryService.this.getPackageName();
-        }
-
-        @Override
-        public int getUid() {
-            return Process.myUid();
-        }
-    };
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return mBinder;
-    }
-}
diff --git a/tests/cts/hostside/certs/Android.bp b/tests/cts/hostside/certs/Android.bp
deleted file mode 100644
index ab4cf34..0000000
--- a/tests/cts/hostside/certs/Android.bp
+++ /dev/null
@@ -1,4 +0,0 @@
-android_app_certificate {
-    name: "cts-net-app",
-    certificate: "cts-net-app",
-}
diff --git a/tests/cts/hostside/certs/README b/tests/cts/hostside/certs/README
deleted file mode 100644
index b660a82..0000000
--- a/tests/cts/hostside/certs/README
+++ /dev/null
@@ -1,2 +0,0 @@
-# Generated with:
-development/tools/make_key cts-net-app '/CN=cts-net-app'
diff --git a/tests/cts/hostside/certs/cts-net-app.pk8 b/tests/cts/hostside/certs/cts-net-app.pk8
deleted file mode 100644
index 1703e4e..0000000
--- a/tests/cts/hostside/certs/cts-net-app.pk8
+++ /dev/null
Binary files differ
diff --git a/tests/cts/hostside/certs/cts-net-app.x509.pem b/tests/cts/hostside/certs/cts-net-app.x509.pem
deleted file mode 100644
index a15ff48..0000000
--- a/tests/cts/hostside/certs/cts-net-app.x509.pem
+++ /dev/null
@@ -1,19 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDAjCCAeqgAwIBAgIJAMhWwIIqr1r6MA0GCSqGSIb3DQEBCwUAMBYxFDASBgNV
-BAMMC2N0cy1uZXQtYXBwMB4XDTE4MDYyMDAyMjAwN1oXDTQ1MTEwNTAyMjAwN1ow
-FjEUMBIGA1UEAwwLY3RzLW5ldC1hcHAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
-ggEKAoIBAQDefOayWQss1E+FQIONK6IhlXhe0BEyHshIrnPOOmuCPa/Svfbnmziy
-hr1KTjaQ3ET/mGShwlt6AUti7nKx9aB71IJp5mSBuwW62A8jvN3yNOo45YV8+n1o
-TrEoMWMf7hQmoOSqaSJ+VFuVms/kPSEh99okDgHCej6rsEkEcDoh6pJajQyUYDwR
-SNAF8SrqCDhqFbZW/LWedvuikCUlNtzuv7/GrcLcsiWEfHv7UOBKpMjLo9BhD1XF
-IefnxImcBQrQGMnE9TLixBiEeX5yauLgbZuxBqD/zsI2TH1FjxTeuJan83kLbqqH
-FgyvPaUjwckAdQPyom7ZUYFnBc0LQ9xzAgMBAAGjUzBRMB0GA1UdDgQWBBRZrBEw
-tAB2WNXj8dQ7ZOuJ34kY5DAfBgNVHSMEGDAWgBRZrBEwtAB2WNXj8dQ7ZOuJ34kY
-5DAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQDeI9AnLW6l/39y
-z96w/ldxZVFPzBRiFIsJsPHVyXlD5vUHZv/ju2jFn8TZSZR5TK0bzCEoVLp34Sho
-bbS0magP82yIvCRibyoyD+TDNnZkNJwjYnikE+/oyshTSQtpkn/rDA+0Y09BUC1E
-N2I6bV9pTXLFg7oah2FmqPRPzhgeYUKENgOQkrrjUCn6y0i/k374n7aftzdniSIz
-2kCRVEeN9gws6CnoMPx0vr32v/JVuPV6zfdJYadgj/eFRyTNE4msd9kE82Wc46eU
-YiI+LuXZ3ZMUNWGY7MK2pOUUS52JsBQ3K235dA5WaU4x8OBlY/WkNYX/eLbNs5jj
-FzLmhZZ1
------END CERTIFICATE-----
diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java
deleted file mode 100644
index 1312085..0000000
--- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.net;
-public class HostsideNetworkCallbackTests extends HostsideNetworkTestCase {
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        uninstallPackage(TEST_APP2_PKG, false);
-        installPackage(TEST_APP2_APK);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        uninstallPackage(TEST_APP2_PKG, true);
-    }
-
-    public void testOnBlockedStatusChanged_dataSaver() throws Exception {
-        runDeviceTests(TEST_PKG,
-                TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_dataSaver");
-    }
-
-    public void testOnBlockedStatusChanged_powerSaver() throws Exception {
-        runDeviceTests(TEST_PKG,
-                TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_powerSaver");
-    }
-}
-
diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java
deleted file mode 100644
index ce20379..0000000
--- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net;
-
-import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.TestResult.TestStatus;
-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;
-import com.android.tradefed.testtype.IBuildReceiver;
-
-import java.io.FileNotFoundException;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiReceiver,
-        IBuildReceiver {
-    protected static final boolean DEBUG = false;
-    protected static final String TAG = "HostsideNetworkTests";
-    protected static final String TEST_PKG = "com.android.cts.net.hostside";
-    protected static final String TEST_APK = "CtsHostsideNetworkTestsApp.apk";
-    protected static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2";
-    protected static final String TEST_APP2_APK = "CtsHostsideNetworkTestsApp2.apk";
-
-    private IAbi mAbi;
-    private IBuildInfo mCtsBuild;
-
-    @Override
-    public void setAbi(IAbi abi) {
-        mAbi = abi;
-    }
-
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mCtsBuild = buildInfo;
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        assertNotNull(mAbi);
-        assertNotNull(mCtsBuild);
-
-        uninstallPackage(TEST_PKG, false);
-        installPackage(TEST_APK);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-
-        uninstallPackage(TEST_PKG, true);
-    }
-
-    protected void installPackage(String apk) throws FileNotFoundException,
-            DeviceNotAvailableException {
-        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
-        assertNull(getDevice().installPackage(buildHelper.getTestFile(apk),
-                false /* reinstall */, true /* grantPermissions */));
-    }
-
-    protected void uninstallPackage(String packageName, boolean shouldSucceed)
-            throws DeviceNotAvailableException {
-        final String result = getDevice().uninstallPackage(packageName);
-        if (shouldSucceed) {
-            assertNull("uninstallPackage(" + packageName + ") failed: " + result, result);
-        }
-    }
-
-    protected void assertPackageUninstalled(String packageName) throws DeviceNotAvailableException,
-            InterruptedException {
-        final String command = "cmd package list packages " + packageName;
-        final int max_tries = 5;
-        for (int i = 1; i <= max_tries; i++) {
-            final String result = runCommand(command);
-            if (result.trim().isEmpty()) {
-                return;
-            }
-            // 'list packages' filters by substring, so we need to iterate with the results
-            // and check one by one, otherwise 'com.android.cts.net.hostside' could return
-            // 'com.android.cts.net.hostside.app2'
-            boolean found = false;
-            for (String line : result.split("[\\r\\n]+")) {
-                if (line.endsWith(packageName)) {
-                    found = true;
-                    break;
-                }
-            }
-            if (!found) {
-                return;
-            }
-            i++;
-            Log.v(TAG, "Package " + packageName + " not uninstalled yet (" + result
-                    + "); sleeping 1s before polling again");
-            Thread.sleep(1000);
-        }
-        fail("Package '" + packageName + "' not uinstalled after " + max_tries + " seconds");
-    }
-
-    protected void runDeviceTests(String packageName, String testClassName)
-            throws DeviceNotAvailableException {
-        runDeviceTests(packageName, testClassName, null);
-    }
-
-    protected void runDeviceTests(String packageName, String testClassName, String methodName)
-            throws DeviceNotAvailableException {
-        RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(packageName,
-                "androidx.test.runner.AndroidJUnitRunner", getDevice().getIDevice());
-
-        if (testClassName != null) {
-            if (methodName != null) {
-                testRunner.setMethodName(testClassName, methodName);
-            } else {
-                testRunner.setClassName(testClassName);
-            }
-        }
-
-        final CollectingTestListener listener = new CollectingTestListener();
-        getDevice().runInstrumentationTests(testRunner, listener);
-
-        final TestRunResult result = listener.getCurrentRunResults();
-        if (result.isRunFailure()) {
-            throw new AssertionError("Failed to successfully run device tests for "
-                    + result.getName() + ": " + result.getRunFailureMessage());
-        }
-
-        if (result.hasFailedTests()) {
-            // build a meaningful error message
-            StringBuilder errorBuilder = new StringBuilder("on-device tests failed:\n");
-            for (Map.Entry<TestDescription, TestResult> resultEntry :
-                result.getTestResults().entrySet()) {
-                if (!resultEntry.getValue().getStatus().equals(TestStatus.PASSED)) {
-                    errorBuilder.append(resultEntry.getKey().toString());
-                    errorBuilder.append(":\n");
-                    errorBuilder.append(resultEntry.getValue().getStackTrace());
-                }
-            }
-            throw new AssertionError(errorBuilder.toString());
-        }
-    }
-
-    private static final Pattern UID_PATTERN =
-            Pattern.compile(".*userId=([0-9]+)$", Pattern.MULTILINE);
-
-    protected int getUid(String packageName) throws DeviceNotAvailableException {
-        final String output = runCommand("dumpsys package " + packageName);
-        final Matcher matcher = UID_PATTERN.matcher(output);
-        while (matcher.find()) {
-            final String match = matcher.group(1);
-            return Integer.parseInt(match);
-        }
-        throw new RuntimeException("Did not find regexp '" + UID_PATTERN + "' on adb output\n"
-                + output);
-    }
-
-    protected String runCommand(String command) throws DeviceNotAvailableException {
-        Log.d(TAG, "Command: '" + command + "'");
-        final String output = getDevice().executeShellCommand(command);
-        if (DEBUG) Log.v(TAG, "Output: " + output.trim());
-        return output;
-    }
-}
diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
deleted file mode 100644
index 4598c39..0000000
--- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net;
-
-import com.android.ddmlib.Log;
-import com.android.tradefed.device.DeviceNotAvailableException;
-
-public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestCase {
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        uninstallPackage(TEST_APP2_PKG, false);
-        installPackage(TEST_APP2_APK);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-
-        uninstallPackage(TEST_APP2_PKG, true);
-    }
-
-    /**************************
-     * Data Saver Mode tests. *
-     **************************/
-
-    public void testDataSaverMode_disabled() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".DataSaverModeTest",
-                "testGetRestrictBackgroundStatus_disabled");
-    }
-
-    public void testDataSaverMode_whitelisted() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".DataSaverModeTest",
-                "testGetRestrictBackgroundStatus_whitelisted");
-    }
-
-    public void testDataSaverMode_enabled() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".DataSaverModeTest",
-                "testGetRestrictBackgroundStatus_enabled");
-    }
-
-    public void testDataSaverMode_blacklisted() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".DataSaverModeTest",
-                "testGetRestrictBackgroundStatus_blacklisted");
-    }
-
-    public void testDataSaverMode_reinstall() throws Exception {
-        final int oldUid = getUid(TEST_APP2_PKG);
-
-        // Make sure whitelist is revoked when package is removed
-        addRestrictBackgroundWhitelist(oldUid);
-
-        uninstallPackage(TEST_APP2_PKG, true);
-        assertPackageUninstalled(TEST_APP2_PKG);
-        assertRestrictBackgroundWhitelist(oldUid, false);
-
-        installPackage(TEST_APP2_APK);
-        final int newUid = getUid(TEST_APP2_PKG);
-        assertRestrictBackgroundWhitelist(oldUid, false);
-        assertRestrictBackgroundWhitelist(newUid, false);
-    }
-
-    public void testDataSaverMode_requiredWhitelistedPackages() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".DataSaverModeTest",
-                "testGetRestrictBackgroundStatus_requiredWhitelistedPackages");
-    }
-
-    public void testDataSaverMode_broadcastNotSentOnUnsupportedDevices() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".DataSaverModeTest",
-                "testBroadcastNotSentOnUnsupportedDevices");
-    }
-
-    /*****************************
-     * Battery Saver Mode tests. *
-     *****************************/
-
-    public void testBatterySaverModeMetered_disabled() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeMeteredTest",
-                "testBackgroundNetworkAccess_disabled");
-    }
-
-    public void testBatterySaverModeMetered_whitelisted() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeMeteredTest",
-                "testBackgroundNetworkAccess_whitelisted");
-    }
-
-    public void testBatterySaverModeMetered_enabled() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeMeteredTest",
-                "testBackgroundNetworkAccess_enabled");
-    }
-
-    public void testBatterySaverMode_reinstall() throws Exception {
-        if (!isDozeModeEnabled()) {
-            Log.w(TAG, "testBatterySaverMode_reinstall() skipped because device does not support "
-                    + "Doze Mode");
-            return;
-        }
-
-        addPowerSaveModeWhitelist(TEST_APP2_PKG);
-
-        uninstallPackage(TEST_APP2_PKG, true);
-        assertPackageUninstalled(TEST_APP2_PKG);
-        assertPowerSaveModeWhitelist(TEST_APP2_PKG, false);
-
-        installPackage(TEST_APP2_APK);
-        assertPowerSaveModeWhitelist(TEST_APP2_PKG, false);
-    }
-
-    public void testBatterySaverModeNonMetered_disabled() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeNonMeteredTest",
-                "testBackgroundNetworkAccess_disabled");
-    }
-
-    public void testBatterySaverModeNonMetered_whitelisted() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeNonMeteredTest",
-                "testBackgroundNetworkAccess_whitelisted");
-    }
-
-    public void testBatterySaverModeNonMetered_enabled() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeNonMeteredTest",
-                "testBackgroundNetworkAccess_enabled");
-    }
-
-    /*******************
-     * App idle tests. *
-     *******************/
-
-    public void testAppIdleMetered_disabled() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleMeteredTest",
-                "testBackgroundNetworkAccess_disabled");
-    }
-
-    public void testAppIdleMetered_whitelisted() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleMeteredTest",
-                "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");
-    }
-
-    public void testAppIdleMetered_idleWhitelisted() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleMeteredTest",
-                "testAppIdleNetworkAccess_idleWhitelisted");
-    }
-
-    // TODO: currently power-save mode and idle uses the same whitelist, so this test would be
-    // redundant (as it would be testing the same as testBatterySaverMode_reinstall())
-    //    public void testAppIdle_reinstall() throws Exception {
-    //    }
-
-    public void testAppIdleNonMetered_disabled() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleNonMeteredTest",
-                "testBackgroundNetworkAccess_disabled");
-    }
-
-    public void testAppIdleNonMetered_whitelisted() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleNonMeteredTest",
-                "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");
-    }
-
-    public void testAppIdleNonMetered_idleWhitelisted() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleNonMeteredTest",
-                "testAppIdleNetworkAccess_idleWhitelisted");
-    }
-
-    public void testAppIdleNonMetered_whenCharging() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleNonMeteredTest",
-                "testAppIdleNetworkAccess_whenCharging");
-    }
-
-    public void testAppIdleMetered_whenCharging() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleMeteredTest",
-                "testAppIdleNetworkAccess_whenCharging");
-    }
-
-    public void testAppIdle_toast() throws Exception {
-        // Check that showing a toast doesn't bring an app out of standby
-        runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleNonMeteredTest",
-                "testAppIdle_toast");
-    }
-
-    /********************
-     * Doze Mode tests. *
-     ********************/
-
-    public void testDozeModeMetered_disabled() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".DozeModeMeteredTest",
-                "testBackgroundNetworkAccess_disabled");
-    }
-
-    public void testDozeModeMetered_whitelisted() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".DozeModeMeteredTest",
-                "testBackgroundNetworkAccess_whitelisted");
-    }
-
-    public void testDozeModeMetered_enabled() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".DozeModeMeteredTest",
-                "testBackgroundNetworkAccess_enabled");
-    }
-
-    public void testDozeModeMetered_enabledButWhitelistedOnNotificationAction() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".DozeModeMeteredTest",
-                "testBackgroundNetworkAccess_enabledButWhitelistedOnNotificationAction");
-    }
-
-    // TODO: currently power-save mode and idle uses the same whitelist, so this test would be
-    // redundant (as it would be testing the same as testBatterySaverMode_reinstall())
-    //    public void testDozeMode_reinstall() throws Exception {
-    //    }
-
-    public void testDozeModeNonMetered_disabled() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".DozeModeNonMeteredTest",
-                "testBackgroundNetworkAccess_disabled");
-    }
-
-    public void testDozeModeNonMetered_whitelisted() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".DozeModeNonMeteredTest",
-                "testBackgroundNetworkAccess_whitelisted");
-    }
-
-    public void testDozeModeNonMetered_enabled() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".DozeModeNonMeteredTest",
-                "testBackgroundNetworkAccess_enabled");
-    }
-
-    public void testDozeModeNonMetered_enabledButWhitelistedOnNotificationAction()
-            throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".DozeModeNonMeteredTest",
-                "testBackgroundNetworkAccess_enabledButWhitelistedOnNotificationAction");
-    }
-
-    /**********************
-     * Mixed modes tests. *
-     **********************/
-
-    public void testDataAndBatterySaverModes_meteredNetwork() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".MixedModesTest",
-                "testDataAndBatterySaverModes_meteredNetwork");
-    }
-
-    public void testDataAndBatterySaverModes_nonMeteredNetwork() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".MixedModesTest",
-                "testDataAndBatterySaverModes_nonMeteredNetwork");
-    }
-
-    public void testDozeAndBatterySaverMode_powerSaveWhitelists() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".MixedModesTest",
-                "testDozeAndBatterySaverMode_powerSaveWhitelists");
-    }
-
-    public void testDozeAndAppIdle_powerSaveWhitelists() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".MixedModesTest",
-                "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");
-    }
-
-    public void testDozeAndAppIdle_appIdleWhitelist() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".MixedModesTest",
-                "testDozeAndAppIdle_appIdleWhitelist");
-    }
-
-    public void testAppIdleAndDoze_tempPowerSaveAndAppIdleWhitelists() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".MixedModesTest",
-                "testAppIdleAndDoze_tempPowerSaveAndAppIdleWhitelists");
-    }
-
-    public void testAppIdleAndBatterySaver_tempPowerSaveAndAppIdleWhitelists() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".MixedModesTest",
-                "testAppIdleAndBatterySaver_tempPowerSaveAndAppIdleWhitelists");
-    }
-
-    /*******************
-     * Helper methods. *
-     *******************/
-
-    private void assertRestrictBackgroundWhitelist(int uid, boolean expected) throws Exception {
-        final int max_tries = 5;
-        boolean actual = false;
-        for (int i = 1; i <= max_tries; i++) {
-            final String output = runCommand("cmd netpolicy list restrict-background-whitelist ");
-            actual = output.contains(Integer.toString(uid));
-            if (expected == actual) {
-                return;
-            }
-            Log.v(TAG, "whitelist check for uid " + uid + " doesn't match yet (expected "
-                    + expected + ", got " + actual + "); sleeping 1s before polling again");
-            Thread.sleep(1000);
-        }
-        fail("whitelist check for uid " + uid + " failed: expected "
-                + expected + ", got " + actual);
-    }
-
-    private void assertPowerSaveModeWhitelist(String packageName, boolean expected)
-            throws Exception {
-        // TODO: currently the power-save mode is behaving like idle, but once it changes, we'll
-        // need to use netpolicy for whitelisting
-        assertDelayedCommand("dumpsys deviceidle whitelist =" + packageName,
-                Boolean.toString(expected));
-    }
-
-    /**
-     * Asserts the result of a command, wait and re-running it a couple times if necessary.
-     */
-    private void assertDelayedCommand(String command, String expectedResult)
-            throws InterruptedException, DeviceNotAvailableException {
-        final int maxTries = 5;
-        for (int i = 1; i <= maxTries; i++) {
-            final String result = runCommand(command).trim();
-            if (result.equals(expectedResult)) return;
-            Log.v(TAG, "Command '" + command + "' returned '" + result + " instead of '"
-                    + expectedResult + "' on attempt #; sleeping 1s before polling again");
-            Thread.sleep(1000);
-        }
-        fail("Command '" + command + "' did not return '" + expectedResult + "' after " + maxTries
-                + " attempts");
-    }
-
-    protected void addRestrictBackgroundWhitelist(int uid) throws Exception {
-        runCommand("cmd netpolicy add restrict-background-whitelist " + uid);
-        assertRestrictBackgroundWhitelist(uid, true);
-    }
-
-    private void addPowerSaveModeWhitelist(String packageName) throws Exception {
-        Log.i(TAG, "Adding package " + packageName + " to power-save-mode whitelist");
-        // TODO: currently the power-save mode is behaving like idle, but once it changes, we'll
-        // need to use netpolicy for whitelisting
-        runCommand("dumpsys deviceidle whitelist +" + packageName);
-        assertPowerSaveModeWhitelist(packageName, true); // Sanity check
-    }
-
-    protected boolean isDozeModeEnabled() throws Exception {
-        final String result = runCommand("cmd deviceidle enabled deep").trim();
-        return result.equals("1");
-    }
-}
diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java
deleted file mode 100644
index 62925ad..0000000
--- a/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.net;
-
-public class HostsideVpnTests extends HostsideNetworkTestCase {
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        uninstallPackage(TEST_APP2_PKG, false);
-        installPackage(TEST_APP2_APK);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-
-        uninstallPackage(TEST_APP2_PKG, true);
-    }
-
-    public void testDefault() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testDefault");
-    }
-
-    public void testAppAllowed() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testAppAllowed");
-    }
-
-    public void testAppDisallowed() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testAppDisallowed");
-    }
-
-    public void testGetConnectionOwnerUidSecurity() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testGetConnectionOwnerUidSecurity");
-    }
-
-    public void testSetProxy() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testSetProxy");
-    }
-
-    public void testSetProxyDisallowedApps() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testSetProxyDisallowedApps");
-    }
-
-    public void testNoProxy() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testNoProxy");
-    }
-
-    public void testBindToNetworkWithProxy() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testBindToNetworkWithProxy");
-    }
-
-    public void testVpnMeterednessWithNoUnderlyingNetwork() throws Exception {
-        runDeviceTests(
-                TEST_PKG, TEST_PKG + ".VpnTest", "testVpnMeterednessWithNoUnderlyingNetwork");
-    }
-
-    public void testVpnMeterednessWithNullUnderlyingNetwork() throws Exception {
-        runDeviceTests(
-                TEST_PKG, TEST_PKG + ".VpnTest", "testVpnMeterednessWithNullUnderlyingNetwork");
-    }
-
-    public void testVpnMeterednessWithNonNullUnderlyingNetwork() throws Exception {
-        runDeviceTests(
-                TEST_PKG, TEST_PKG + ".VpnTest", "testVpnMeterednessWithNonNullUnderlyingNetwork");
-    }
-
-    public void testAlwaysMeteredVpnWithNullUnderlyingNetwork() throws Exception {
-        runDeviceTests(
-                TEST_PKG, TEST_PKG + ".VpnTest", "testAlwaysMeteredVpnWithNullUnderlyingNetwork");
-    }
-
-    public void testAlwaysMeteredVpnWithNonNullUnderlyingNetwork() throws Exception {
-        runDeviceTests(
-                TEST_PKG,
-                TEST_PKG + ".VpnTest",
-                "testAlwaysMeteredVpnWithNonNullUnderlyingNetwork");
-    }
-
-    public void testB141603906() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testB141603906");
-    }
-}
diff --git a/tests/cts/hostside/src/com/android/cts/net/NetworkPolicyTestsPreparer.java b/tests/cts/hostside/src/com/android/cts/net/NetworkPolicyTestsPreparer.java
deleted file mode 100644
index 23aca24..0000000
--- a/tests/cts/hostside/src/com/android/cts/net/NetworkPolicyTestsPreparer.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.net;
-
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.invoker.TestInformation;
-import com.android.tradefed.log.LogUtil;
-import com.android.tradefed.targetprep.ITargetPreparer;
-
-public class NetworkPolicyTestsPreparer implements ITargetPreparer {
-    private ITestDevice mDevice;
-    private boolean mOriginalAirplaneModeEnabled;
-    private String mOriginalAppStandbyEnabled;
-    private String mOriginalBatteryStatsConstants;
-    private final static String KEY_STABLE_CHARGING_DELAY_MS = "battery_charged_delay_ms";
-    private final static int DESIRED_STABLE_CHARGING_DELAY_MS = 0;
-
-    @Override
-    public void setUp(TestInformation testInformation) throws DeviceNotAvailableException {
-        mDevice = testInformation.getDevice();
-        mOriginalAppStandbyEnabled = getAppStandbyEnabled();
-        setAppStandbyEnabled("1");
-        LogUtil.CLog.d("Original app_standby_enabled: " + mOriginalAppStandbyEnabled);
-
-        mOriginalBatteryStatsConstants = getBatteryStatsConstants();
-        setBatteryStatsConstants(
-                KEY_STABLE_CHARGING_DELAY_MS + "=" + DESIRED_STABLE_CHARGING_DELAY_MS);
-        LogUtil.CLog.d("Original battery_saver_constants: " + mOriginalBatteryStatsConstants);
-
-        mOriginalAirplaneModeEnabled = getAirplaneModeEnabled();
-        // Turn off airplane mode in case another test left the device in that state.
-        setAirplaneModeEnabled(false);
-        LogUtil.CLog.d("Original airplane mode state: " + mOriginalAirplaneModeEnabled);
-    }
-
-    @Override
-    public void tearDown(TestInformation testInformation, Throwable e)
-            throws DeviceNotAvailableException {
-        setAirplaneModeEnabled(mOriginalAirplaneModeEnabled);
-        setAppStandbyEnabled(mOriginalAppStandbyEnabled);
-        setBatteryStatsConstants(mOriginalBatteryStatsConstants);
-    }
-
-    private void setAirplaneModeEnabled(boolean enable) throws DeviceNotAvailableException {
-        executeCmd("cmd connectivity airplane-mode " + (enable ? "enable" : "disable"));
-    }
-
-    private boolean getAirplaneModeEnabled() throws DeviceNotAvailableException {
-        return "enabled".equals(executeCmd("cmd connectivity airplane-mode").trim());
-    }
-
-    private void setAppStandbyEnabled(String appStandbyEnabled) throws DeviceNotAvailableException {
-        if ("null".equals(appStandbyEnabled)) {
-            executeCmd("settings delete global app_standby_enabled");
-        } else {
-            executeCmd("settings put global app_standby_enabled " + appStandbyEnabled);
-        }
-    }
-
-    private String getAppStandbyEnabled() throws DeviceNotAvailableException {
-        return executeCmd("settings get global app_standby_enabled").trim();
-    }
-
-    private void setBatteryStatsConstants(String batteryStatsConstants)
-            throws DeviceNotAvailableException {
-        executeCmd("settings put global battery_stats_constants \"" + batteryStatsConstants + "\"");
-    }
-
-    private String getBatteryStatsConstants() throws DeviceNotAvailableException {
-        return executeCmd("settings get global battery_stats_constants");
-    }
-
-    private String executeCmd(String cmd) throws DeviceNotAvailableException {
-        final String output = mDevice.executeShellCommand(cmd).trim();
-        LogUtil.CLog.d("Output for '%s': %s", cmd, output);
-        return output;
-    }
-}
diff --git a/tests/cts/hostside/src/com/android/cts/net/ProcNetTest.java b/tests/cts/hostside/src/com/android/cts/net/ProcNetTest.java
deleted file mode 100644
index 19e61c6..0000000
--- a/tests/cts/hostside/src/com/android/cts/net/ProcNetTest.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * 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.security.cts;
-
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.testtype.IDeviceTest;
-
-import java.lang.Integer;
-import java.lang.String;
-import java.util.Arrays;
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * Host-side tests for values in /proc/net.
- *
- * These tests analyze /proc/net to verify that certain networking properties are correct.
- */
-public class ProcNetTest extends DeviceTestCase implements IBuildReceiver, IDeviceTest {
-    private static final String SPI_TIMEOUT_SYSCTL = "/proc/sys/net/core/xfrm_acq_expires";
-    private static final int MIN_ACQ_EXPIRES = 3600;
-    // Global sysctls. Must be present and set to 1.
-    private static final String[] GLOBAL_SYSCTLS = {
-        "/proc/sys/net/ipv4/fwmark_reflect",
-        "/proc/sys/net/ipv6/fwmark_reflect",
-        "/proc/sys/net/ipv4/tcp_fwmark_accept",
-    };
-
-    // Per-interface IPv6 autoconf sysctls.
-    private static final String IPV6_SYSCTL_DIR = "/proc/sys/net/ipv6/conf";
-    private static final String AUTOCONF_SYSCTL = "accept_ra_rt_table";
-
-    // Expected values for MIN|MAX_PLEN.
-    private static final String ACCEPT_RA_RT_INFO_MIN_PLEN_STRING = "accept_ra_rt_info_min_plen";
-    private static final int ACCEPT_RA_RT_INFO_MIN_PLEN_VALUE = 48;
-    private static final String ACCEPT_RA_RT_INFO_MAX_PLEN_STRING = "accept_ra_rt_info_max_plen";
-    private static final int ACCEPT_RA_RT_INFO_MAX_PLEN_VALUE = 64;
-    // Expected values for RFC 7559 router soliciations.
-    // Maximum number of router solicitations to send. -1 means no limit.
-    private static final int IPV6_WIFI_ROUTER_SOLICITATIONS = -1;
-    private ITestDevice mDevice;
-    private IBuildInfo mBuild;
-    private String[] mSysctlDirs;
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setBuild(IBuildInfo build) {
-        mBuild = build;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setDevice(ITestDevice device) {
-        super.setDevice(device);
-        mDevice = device;
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mSysctlDirs = getSysctlDirs();
-    }
-
-    private String[] getSysctlDirs() throws Exception {
-        String interfaceDirs[] = mDevice.executeAdbCommand("shell", "ls", "-1",
-                IPV6_SYSCTL_DIR).split("\n");
-        List<String> interfaceDirsList = new ArrayList<String>(Arrays.asList(interfaceDirs));
-        interfaceDirsList.remove("all");
-        interfaceDirsList.remove("lo");
-        return interfaceDirsList.toArray(new String[interfaceDirsList.size()]);
-    }
-
-
-    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);
-    }
-
-    public int readIntFromPath(String path) throws Exception {
-        String mode = mDevice.executeAdbCommand("shell", "stat", "-c", "%a", path).trim();
-        String user = mDevice.executeAdbCommand("shell", "stat", "-c", "%u", path).trim();
-        String group = mDevice.executeAdbCommand("shell", "stat", "-c", "%g", path).trim();
-        assertEquals(mode, "644");
-        assertEquals(user, "0");
-        assertEquals(group, "0");
-        return Integer.parseInt(mDevice.executeAdbCommand("shell", "cat", path).trim());
-    }
-
-    /**
-     * Checks that SPI default timeouts are overridden, and set to a reasonable length of time
-     */
-    public void testMinAcqExpires() throws Exception {
-        int value = readIntFromPath(SPI_TIMEOUT_SYSCTL);
-        assertAtLeast(SPI_TIMEOUT_SYSCTL, value, MIN_ACQ_EXPIRES);
-    }
-
-    /**
-     * Checks that the sysctls for multinetwork kernel features are present and
-     * enabled.
-     */
-    public void testProcSysctls() throws Exception {
-        for (String sysctl : GLOBAL_SYSCTLS) {
-            int value = readIntFromPath(sysctl);
-            assertEquals(sysctl, 1, value);
-        }
-
-        for (String interfaceDir : mSysctlDirs) {
-            String path = IPV6_SYSCTL_DIR + "/" + interfaceDir + "/" + AUTOCONF_SYSCTL;
-            int value = readIntFromPath(path);
-            assertLess(path, value, 0);
-        }
-    }
-
-    /**
-     * Verify that accept_ra_rt_info_{min,max}_plen exists and is set to the expected value
-     */
-    public void testAcceptRaRtInfoMinMaxPlen() throws Exception {
-        for (String interfaceDir : mSysctlDirs) {
-            String path = IPV6_SYSCTL_DIR + "/" + interfaceDir + "/" + "accept_ra_rt_info_min_plen";
-            int value = readIntFromPath(path);
-            assertEquals(path, value, ACCEPT_RA_RT_INFO_MIN_PLEN_VALUE);
-            path = IPV6_SYSCTL_DIR + "/" + interfaceDir + "/" + "accept_ra_rt_info_max_plen";
-            value = readIntFromPath(path);
-            assertEquals(path, value, ACCEPT_RA_RT_INFO_MAX_PLEN_VALUE);
-        }
-    }
-
-    /**
-     * Verify that router_solicitations exists and is set to the expected value
-     * and verify that router_solicitation_max_interval exists and is in an acceptable interval.
-     */
-    public void testRouterSolicitations() throws Exception {
-        for (String interfaceDir : mSysctlDirs) {
-            String path = IPV6_SYSCTL_DIR + "/" + interfaceDir + "/" + "router_solicitations";
-            int value = readIntFromPath(path);
-            assertEquals(IPV6_WIFI_ROUTER_SOLICITATIONS, value);
-            path = IPV6_SYSCTL_DIR + "/" + interfaceDir + "/" + "router_solicitation_max_interval";
-            int interval = readIntFromPath(path);
-            final int lowerBoundSec = 15 * 60;
-            final int upperBoundSec = 60 * 60;
-            assertTrue(lowerBoundSec <= interval);
-            assertTrue(interval <= upperBoundSec);
-        }
-    }
-}
diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp
deleted file mode 100644
index 3b69602..0000000
--- a/tests/cts/net/Android.bp
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (C) 2008 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_defaults {
-    name: "CtsNetTestCasesDefaults",
-    defaults: ["cts_defaults"],
-
-    // Include both the 32 and 64 bit versions
-    compile_multilib: "both",
-
-    libs: [
-        "voip-common",
-        "android.test.base",
-    ],
-
-    jni_libs: [
-        "libcts_jni",
-        "libnativedns_jni",
-        "libnativemultinetwork_jni",
-        "libnativehelper_compat_libc++",
-    ],
-
-    srcs: [
-        "src/**/*.java",
-        "src/**/*.kt",
-    ],
-    jarjar_rules: "jarjar-rules-shared.txt",
-    static_libs: [
-        "FrameworksNetCommonTests",
-        "TestNetworkStackLib",
-        "core-tests-support",
-        "cts-net-utils",
-        "ctstestrunner-axt",
-        "junit",
-        "junit-params",
-        "net-utils-framework-common",
-        "truth-prebuilt",
-    ],
-
-    // uncomment when b/13249961 is fixed
-    // sdk_version: "current",
-    platform_apis: true,
-}
-
-// Networking CTS tests for development and release. These tests always target the platform SDK
-// version, and are subject to all the restrictions appropriate to that version. Before SDK
-// finalization, these tests have a min_sdk_version of 10000, and cannot be installed on release
-// devices.
-android_test {
-    name: "CtsNetTestCases",
-    defaults: ["CtsNetTestCasesDefaults"],
-    test_suites: [
-        "cts",
-        "vts10",
-        "general-tests",
-    ],
-    test_config_template: "AndroidTestTemplate.xml",
-}
-
-// Networking CTS tests that target the latest released SDK. These tests can be installed on release
-// devices at any point in the Android release cycle and are useful for qualifying mainline modules
-// on release devices.
-android_test {
-    name: "CtsNetTestCasesLatestSdk",
-    defaults: ["CtsNetTestCasesDefaults"],
-    jni_uses_sdk_apis: true,
-    min_sdk_version: "29",
-    target_sdk_version: "30",
-    test_suites: [
-        "general-tests",
-        "mts",
-    ],
-    test_config_template: "AndroidTestTemplate.xml",
-}
diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml
deleted file mode 100644
index a7e2bd7..0000000
--- a/tests/cts/net/AndroidManifest.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.net.cts"
-    android:targetSandboxVersion="2">
-
-    <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.ACCESS_BACKGROUND_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.CONNECTIVITY_USE_RESTRICTED_NETWORKS" />
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.RECORD_AUDIO" />
-    <uses-permission android:name="android.permission.WAKE_LOCK" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
-    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
-
-    <!-- This test also uses signature permissions through adopting the shell identity.
-         The permissions acquired that way include (probably not exhaustive) :
-             android.permission.MANAGE_TEST_NETWORKS
-    -->
-
-    <application android:usesCleartextTraffic="true">
-        <uses-library android:name="android.test.runner" />
-        <uses-library android:name="org.apache.http.legacy" android:required="false" />
-    </application>
-
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="android.net.cts"
-                     android:label="CTS tests of android.net">
-        <meta-data android:name="listener"
-            android:value="com.android.cts.runner.CtsTestRunListener" />
-    </instrumentation>
-
-</manifest>
-
diff --git a/tests/cts/net/AndroidTestTemplate.xml b/tests/cts/net/AndroidTestTemplate.xml
deleted file mode 100644
index 4e93751..0000000
--- a/tests/cts/net/AndroidTestTemplate.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<!-- Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="Test config for {MODULE}">
-    <option name="test-suite-tag" value="cts" />
-    <option name="config-descriptor:metadata" key="component" value="networking" />
-    <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="config-descriptor:metadata" key="mainline-param" value="CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk" />
-    <option name="not-shardable" value="true" />
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="{MODULE}.apk" />
-    </target_preparer>
-    <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" />
-        <option name="isolated-storage" value="false" />
-    </test>
-</configuration>
diff --git a/tests/cts/net/OWNERS b/tests/cts/net/OWNERS
deleted file mode 100644
index d558556..0000000
--- a/tests/cts/net/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Bug component: 31808
-lorenzo@google.com
-satk@google.com
diff --git a/tests/cts/net/TEST_MAPPING b/tests/cts/net/TEST_MAPPING
deleted file mode 100644
index 3162e22..0000000
--- a/tests/cts/net/TEST_MAPPING
+++ /dev/null
@@ -1,23 +0,0 @@
-{
-  // TODO: move to mainline-presubmit once supported
-  "postsubmit": [
-    {
-      "name": "CtsNetTestCasesLatestSdk",
-      "options": [
-        {
-          "exclude-annotation": "com.android.testutils.SkipPresubmit"
-        }
-      ]
-    }
-  ],
-  "mainline-presubmit": [
-    {
-      "name": "CtsNetTestCasesLatestSdk[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk]",
-      "options": [
-        {
-          "exclude-annotation": "com.android.testutils.SkipPresubmit"
-        }
-      ]
-    }
-  ]
-}
diff --git a/tests/cts/net/api23Test/Android.bp b/tests/cts/net/api23Test/Android.bp
deleted file mode 100644
index 0ce9826..0000000
--- a/tests/cts/net/api23Test/Android.bp
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-android_test {
-    name: "CtsNetApi23TestCases",
-    defaults: ["cts_defaults"],
-
-    // Include both the 32 and 64 bit versions
-    compile_multilib: "both",
-
-    libs: [
-        "android.test.base",
-    ],
-
-    srcs: [
-        "src/**/*.java",
-        "src/**/*.kt",
-    ],
-
-    static_libs: [
-        "core-tests-support",
-        "compatibility-device-util-axt",
-        "cts-net-utils",
-        "ctstestrunner-axt",
-        "ctstestserver",
-        "mockwebserver",
-        "junit",
-        "junit-params",
-        "truth-prebuilt",
-    ],
-
-    platform_apis: true,
-
-    // Tag this module as a cts test artifact
-    test_suites: [
-        "cts",
-        "vts10",
-        "general-tests",
-    ],
-
-}
diff --git a/tests/cts/net/api23Test/AndroidManifest.xml b/tests/cts/net/api23Test/AndroidManifest.xml
deleted file mode 100644
index 4889660..0000000
--- a/tests/cts/net/api23Test/AndroidManifest.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.net.cts.api23test">
-
-    <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.ACCESS_FINE_LOCATION" />
-    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
-    <uses-permission android:name="android.permission.INTERNET" />
-
-    <application android:usesCleartextTraffic="true">
-        <uses-library android:name="android.test.runner" />
-
-        <receiver android:name=".ConnectivityReceiver">
-            <intent-filter>
-                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
-            </intent-filter>
-        </receiver>
-    </application>
-
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="android.net.cts.api23test"
-                     android:label="CTS tests of android.net">
-        <meta-data android:name="listener"
-            android:value="com.android.cts.runner.CtsTestRunListener" />
-    </instrumentation>
-</manifest>
-
diff --git a/tests/cts/net/api23Test/AndroidTest.xml b/tests/cts/net/api23Test/AndroidTest.xml
deleted file mode 100644
index 8042d50..0000000
--- a/tests/cts/net/api23Test/AndroidTest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!-- Copyright (C) 2019 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="Config for CTS Net API23 test cases">
-    <option name="test-suite-tag" value="cts" />
-    <option name="config-descriptor:metadata" key="component" value="networking" />
-    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
-    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
-    <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
-    <option name="not-shardable" value="true" />
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsNetApi23TestCases.apk" />
-        <option name="test-file-name" value="CtsNetTestAppForApi23.apk" />
-    </target_preparer>
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.net.cts.api23test" />
-        <option name="hidden-api-checks" value="false" />
-    </test>
-</configuration>
diff --git a/tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityManagerApi23Test.java b/tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityManagerApi23Test.java
deleted file mode 100644
index cdb66e3..0000000
--- a/tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityManagerApi23Test.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts.api23test;
-
-import static android.content.pm.PackageManager.FEATURE_WIFI;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.net.ConnectivityManager;
-import android.net.cts.util.CtsNetUtils;
-import android.os.Looper;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-public class ConnectivityManagerApi23Test extends AndroidTestCase {
-    private static final String TAG = ConnectivityManagerApi23Test.class.getSimpleName();
-    private static final int SEND_BROADCAST_TIMEOUT = 30000;
-    // Intent string to get the number of wifi CONNECTIVITY_ACTION callbacks the test app has seen
-    public static final String GET_WIFI_CONNECTIVITY_ACTION_COUNT =
-            "android.net.cts.appForApi23.getWifiConnectivityActionCount";
-    // Action sent to ConnectivityActionReceiver when a network callback is sent via PendingIntent.
-
-    private Context mContext;
-    private PackageManager mPackageManager;
-    private CtsNetUtils mCtsNetUtils;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        Looper.prepare();
-        mContext = getContext();
-        mPackageManager = mContext.getPackageManager();
-        mCtsNetUtils = new CtsNetUtils(mContext);
-    }
-
-    /**
-     * Tests reporting of connectivity changed.
-     */
-    public void testConnectivityChanged_manifestRequestOnly_shouldNotReceiveIntent() {
-        if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
-            Log.i(TAG, "testConnectivityChanged_manifestRequestOnly_shouldNotReceiveIntent cannot execute unless device supports WiFi");
-            return;
-        }
-        ConnectivityReceiver.prepare();
-
-        mCtsNetUtils.toggleWifi();
-
-        // The connectivity broadcast has been sent; push through a terminal broadcast
-        // to wait for in the receive to confirm it didn't see the connectivity change.
-        Intent finalIntent = new Intent(ConnectivityReceiver.FINAL_ACTION);
-        finalIntent.setClass(mContext, ConnectivityReceiver.class);
-        mContext.sendBroadcast(finalIntent);
-        assertFalse(ConnectivityReceiver.waitForBroadcast());
-    }
-
-    public void testConnectivityChanged_manifestRequestOnlyPreN_shouldReceiveIntent()
-            throws InterruptedException {
-        if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
-            Log.i(TAG, "testConnectivityChanged_manifestRequestOnlyPreN_shouldReceiveIntent cannot"
-                    + "execute unless device supports WiFi");
-            return;
-        }
-        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);
-
-        mCtsNetUtils.toggleWifi();
-
-        Intent getConnectivityCount = new Intent(GET_WIFI_CONNECTIVITY_ACTION_COUNT);
-        assertEquals(2, sendOrderedBroadcastAndReturnResultCode(
-                getConnectivityCount, SEND_BROADCAST_TIMEOUT));
-    }
-
-    public void testConnectivityChanged_whenRegistered_shouldReceiveIntent() {
-        if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
-            Log.i(TAG, "testConnectivityChanged_whenRegistered_shouldReceiveIntent cannot execute unless device supports WiFi");
-            return;
-        }
-        ConnectivityReceiver.prepare();
-        ConnectivityReceiver receiver = new ConnectivityReceiver();
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
-        mContext.registerReceiver(receiver, filter);
-
-        mCtsNetUtils.toggleWifi();
-        Intent finalIntent = new Intent(ConnectivityReceiver.FINAL_ACTION);
-        finalIntent.setClass(mContext, ConnectivityReceiver.class);
-        mContext.sendBroadcast(finalIntent);
-
-        assertTrue(ConnectivityReceiver.waitForBroadcast());
-    }
-
-    private int sendOrderedBroadcastAndReturnResultCode(
-            Intent intent, int timeoutMs) throws InterruptedException {
-        final LinkedBlockingQueue<Integer> result = new LinkedBlockingQueue<>(1);
-        mContext.sendOrderedBroadcast(intent, null, new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                result.offer(getResultCode());
-            }
-        }, null, 0, null, null);
-
-        Integer resultCode = result.poll(timeoutMs, TimeUnit.MILLISECONDS);
-        assertNotNull("Timed out (more than " + timeoutMs +
-                " milliseconds) waiting for result code for broadcast", resultCode);
-        return resultCode;
-    }
-
-}
\ No newline at end of file
diff --git a/tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityReceiver.java b/tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityReceiver.java
deleted file mode 100644
index 9d2b8ad..0000000
--- a/tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityReceiver.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2016 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.api23test;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.util.Log;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-public class ConnectivityReceiver extends BroadcastReceiver {
-    static boolean sReceivedConnectivity;
-    static boolean sReceivedFinal;
-    static CountDownLatch sLatch;
-
-    static void prepare() {
-        synchronized (ConnectivityReceiver.class) {
-            sReceivedConnectivity = sReceivedFinal = false;
-            sLatch = new CountDownLatch(1);
-        }
-    }
-
-    static boolean waitForBroadcast() {
-        try {
-            sLatch.await(30, TimeUnit.SECONDS);
-        } catch (InterruptedException e) {
-            throw new IllegalStateException(e);
-        }
-        synchronized (ConnectivityReceiver.class) {
-            sLatch = null;
-            if (!sReceivedFinal) {
-                throw new IllegalStateException("Never received final broadcast");
-            }
-            return sReceivedConnectivity;
-        }
-    }
-
-    static final String FINAL_ACTION = "android.net.cts.action.FINAL";
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        Log.i("ConnectivityReceiver", "Received: " + intent.getAction());
-        if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
-            sReceivedConnectivity = true;
-        } else if (FINAL_ACTION.equals(intent.getAction())) {
-            sReceivedFinal = true;
-            if (sLatch != null) {
-                sLatch.countDown();
-            }
-        }
-    }
-}
diff --git a/tests/cts/net/appForApi23/Android.bp b/tests/cts/net/appForApi23/Android.bp
deleted file mode 100644
index 399c199..0000000
--- a/tests/cts/net/appForApi23/Android.bp
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (C) 2016 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-android_test {
-    name: "CtsNetTestAppForApi23",
-    defaults: ["cts_defaults"],
-
-    // Include both the 32 and 64 bit versions
-    compile_multilib: "both",
-
-    srcs: ["src/**/*.java"],
-
-    sdk_version: "23",
-
-    // Tag this module as a cts test artifact
-    test_suites: [
-        "cts",
-        "vts10",
-        "general-tests",
-    ],
-
-}
diff --git a/tests/cts/net/appForApi23/AndroidManifest.xml b/tests/cts/net/appForApi23/AndroidManifest.xml
deleted file mode 100644
index ed4cedb..0000000
--- a/tests/cts/net/appForApi23/AndroidManifest.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.net.cts.appForApi23">
-
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-    <uses-permission android:name="android.permission.INTERNET" />
-
-    <application>
-        <receiver android:name=".ConnectivityReceiver">
-            <intent-filter>
-                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
-            </intent-filter>
-            <intent-filter>
-                <action android:name="android.net.cts.appForApi23.getWifiConnectivityActionCount" />
-            </intent-filter>
-        </receiver>
-
-        <activity android:name=".ConnectivityListeningActivity"
-                  android:label="ConnectivityListeningActivity"
-                  android:exported="true">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-        </activity>
-
-    </application>
-
-</manifest>
-
diff --git a/tests/cts/net/appForApi23/src/android/net/cts/appForApi23/ConnectivityListeningActivity.java b/tests/cts/net/appForApi23/src/android/net/cts/appForApi23/ConnectivityListeningActivity.java
deleted file mode 100644
index 24fb68e8..0000000
--- a/tests/cts/net/appForApi23/src/android/net/cts/appForApi23/ConnectivityListeningActivity.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2016 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.appForApi23;
-
-import android.app.Activity;
-
-// Stub activity used to start the app
-public class ConnectivityListeningActivity extends Activity {
-}
\ No newline at end of file
diff --git a/tests/cts/net/appForApi23/src/android/net/cts/appForApi23/ConnectivityReceiver.java b/tests/cts/net/appForApi23/src/android/net/cts/appForApi23/ConnectivityReceiver.java
deleted file mode 100644
index 8039a4f..0000000
--- a/tests/cts/net/appForApi23/src/android/net/cts/appForApi23/ConnectivityReceiver.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2016 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.appForApi23;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.net.ConnectivityManager;
-
-public class ConnectivityReceiver extends BroadcastReceiver {
-    public static String GET_WIFI_CONNECTIVITY_ACTION_COUNT =
-            "android.net.cts.appForApi23.getWifiConnectivityActionCount";
-
-    private static int sWifiConnectivityActionCount = 0;
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
-            int networkType = intent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, 0);
-            if (networkType == ConnectivityManager.TYPE_WIFI) {
-                sWifiConnectivityActionCount++;
-            }
-        }
-        if (GET_WIFI_CONNECTIVITY_ACTION_COUNT.equals(intent.getAction())) {
-            setResultCode(sWifiConnectivityActionCount);
-        }
-    }
-}
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
deleted file mode 100644
index 19628d1..0000000
--- a/tests/cts/net/assets/network_watchlist_config_empty_for_test.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?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
deleted file mode 100644
index 835ae0f..0000000
--- a/tests/cts/net/assets/network_watchlist_config_for_test.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?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/jarjar-rules-shared.txt b/tests/cts/net/jarjar-rules-shared.txt
deleted file mode 100644
index 11dba74..0000000
--- a/tests/cts/net/jarjar-rules-shared.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-# Module library in frameworks/libs/net
-rule com.android.net.module.util.** android.net.cts.util.@1
\ No newline at end of file
diff --git a/tests/cts/net/jni/Android.bp b/tests/cts/net/jni/Android.bp
deleted file mode 100644
index 3953aeb..0000000
--- a/tests/cts/net/jni/Android.bp
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (C) 2013 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.
-
-cc_library_shared {
-    name: "libnativedns_jni",
-
-    srcs: ["NativeDnsJni.c"],
-    sdk_version: "current",
-
-    shared_libs: [
-        "libnativehelper_compat_libc++",
-        "liblog",
-    ],
-    stl: "libc++_static",
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-        "-Wno-unused-parameter",
-    ],
-
-}
-
-cc_library_shared {
-    name: "libnativemultinetwork_jni",
-
-    srcs: ["NativeMultinetworkJni.cpp"],
-    sdk_version: "current",
-    cflags: [
-        "-Wall",
-        "-Werror",
-        "-Wno-format",
-    ],
-    shared_libs: [
-        "libandroid",
-        "libnativehelper_compat_libc++",
-        "liblog",
-    ],
-    stl: "libc++_static",
-}
diff --git a/tests/cts/net/jni/NativeDnsJni.c b/tests/cts/net/jni/NativeDnsJni.c
deleted file mode 100644
index 4ec800e..0000000
--- a/tests/cts/net/jni/NativeDnsJni.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <arpa/inet.h>
-#include <jni.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <android/log.h>
-
-#define LOG_TAG "NativeDns-JNI"
-#define LOGD(fmt, ...) \
-        __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, fmt, ##__VA_ARGS__)
-
-const char *GoogleDNSIpV4Address="8.8.8.8";
-const char *GoogleDNSIpV4Address2="8.8.4.4";
-const char *GoogleDNSIpV6Address="2001:4860:4860::8888";
-const char *GoogleDNSIpV6Address2="2001:4860:4860::8844";
-
-JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclass class)
-{
-    const char *node = "www.google.com";
-    char *service = NULL;
-    struct addrinfo *answer;
-
-    int res = getaddrinfo(node, service, NULL, &answer);
-    LOGD("getaddrinfo(www.google.com) gave res=%d (%s)", res, gai_strerror(res));
-    if (res != 0) return JNI_FALSE;
-
-    // check for v4 & v6
-    {
-        int foundv4 = 0;
-        int foundv6 = 0;
-        struct addrinfo *current = answer;
-        while (current != NULL) {
-            char buf[256];
-            if (current->ai_addr->sa_family == AF_INET) {
-                inet_ntop(current->ai_family, &((struct sockaddr_in *)current->ai_addr)->sin_addr,
-                        buf, sizeof(buf));
-                foundv4 = 1;
-                LOGD("  %s", buf);
-            } else if (current->ai_addr->sa_family == AF_INET6) {
-                inet_ntop(current->ai_family, &((struct sockaddr_in6 *)current->ai_addr)->sin6_addr,
-                        buf, sizeof(buf));
-                foundv6 = 1;
-                LOGD("  %s", buf);
-            }
-            current = current->ai_next;
-        }
-
-        freeaddrinfo(answer);
-        answer = NULL;
-        if (foundv4 != 1 && foundv6 != 1) {
-            LOGD("getaddrinfo(www.google.com) didn't find either v4 or v6 address");
-            return JNI_FALSE;
-        }
-    }
-
-    node = "ipv6.google.com";
-    res = getaddrinfo(node, service, NULL, &answer);
-    LOGD("getaddrinfo(ipv6.google.com) gave res=%d", res);
-    if (res != 0) return JNI_FALSE;
-
-    {
-        int foundv4 = 0;
-        int foundv6 = 0;
-        struct addrinfo *current = answer;
-        while (current != NULL) {
-            char buf[256];
-            if (current->ai_addr->sa_family == AF_INET) {
-                inet_ntop(current->ai_family, &((struct sockaddr_in *)current->ai_addr)->sin_addr,
-                        buf, sizeof(buf));
-                LOGD("  %s", buf);
-                foundv4 = 1;
-            } else if (current->ai_addr->sa_family == AF_INET6) {
-                inet_ntop(current->ai_family, &((struct sockaddr_in6 *)current->ai_addr)->sin6_addr,
-                        buf, sizeof(buf));
-                LOGD("  %s", buf);
-                foundv6 = 1;
-            }
-            current = current->ai_next;
-        }
-
-        freeaddrinfo(answer);
-        answer = NULL;
-        if (foundv4 == 1 || foundv6 != 1) {
-            LOGD("getaddrinfo(ipv6.google.com) didn't find only v6");
-            return JNI_FALSE;
-        }
-    }
-
-    // getnameinfo
-    struct sockaddr_in sa4;
-    sa4.sin_family = AF_INET;
-    sa4.sin_port = 0;
-    inet_pton(AF_INET, GoogleDNSIpV4Address, &(sa4.sin_addr));
-
-    struct sockaddr_in6 sa6;
-    sa6.sin6_family = AF_INET6;
-    sa6.sin6_port = 0;
-    sa6.sin6_flowinfo = 0;
-    sa6.sin6_scope_id = 0;
-    inet_pton(AF_INET6, GoogleDNSIpV6Address2, &(sa6.sin6_addr));
-
-    char buf[NI_MAXHOST];
-    int flags = NI_NAMEREQD;
-
-    res = getnameinfo((const struct sockaddr*)&sa4, sizeof(sa4), buf, sizeof(buf), NULL, 0, flags);
-    if (res != 0) {
-        LOGD("getnameinfo(%s (GoogleDNS) ) gave error %d (%s)", GoogleDNSIpV4Address, res,
-            gai_strerror(res));
-        return JNI_FALSE;
-    }
-    if (strstr(buf, "google.com") == NULL && strstr(buf, "dns.google") == NULL) {
-        LOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com or dns.google: %s",
-            GoogleDNSIpV4Address, buf);
-        return JNI_FALSE;
-    }
-
-    memset(buf, 0, sizeof(buf));
-    res = getnameinfo((const struct sockaddr*)&sa6, sizeof(sa6), buf, sizeof(buf), NULL, 0, flags);
-    if (res != 0) {
-        LOGD("getnameinfo(%s (GoogleDNS) ) gave error %d (%s)", GoogleDNSIpV6Address2,
-            res, gai_strerror(res));
-        return JNI_FALSE;
-    }
-    if (strstr(buf, "google.com") == NULL && strstr(buf, "dns.google") == NULL) {
-        LOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com or dns.google: %s",
-            GoogleDNSIpV6Address2, buf);
-        return JNI_FALSE;
-    }
-
-    // gethostbyname
-    struct hostent *my_hostent = gethostbyname("www.youtube.com");
-    if (my_hostent == NULL) {
-        LOGD("gethostbyname(www.youtube.com) gave null response");
-        return JNI_FALSE;
-    }
-    if ((my_hostent->h_addr_list == NULL) || (*my_hostent->h_addr_list == NULL)) {
-        LOGD("gethostbyname(www.youtube.com) gave 0 addresses");
-        return JNI_FALSE;
-    }
-    {
-        char **current = my_hostent->h_addr_list;
-        while (*current != NULL) {
-            char buf[256];
-            inet_ntop(my_hostent->h_addrtype, *current, buf, sizeof(buf));
-            LOGD("gethostbyname(www.youtube.com) gave %s", buf);
-            current++;
-        }
-    }
-
-    // gethostbyaddr
-    char addr6[16];
-    inet_pton(AF_INET6, GoogleDNSIpV6Address, addr6);
-    my_hostent = gethostbyaddr(addr6, sizeof(addr6), AF_INET6);
-    if (my_hostent == NULL) {
-        LOGD("gethostbyaddr(%s (GoogleDNS) ) gave null response", GoogleDNSIpV6Address);
-        return JNI_FALSE;
-    }
-
-    LOGD("gethostbyaddr(%s (GoogleDNS) ) gave %s for name", GoogleDNSIpV6Address,
-        my_hostent->h_name ? my_hostent->h_name : "null");
-
-    if (my_hostent->h_name == NULL) return JNI_FALSE;
-    return JNI_TRUE;
-}
diff --git a/tests/cts/net/jni/NativeMultinetworkJni.cpp b/tests/cts/net/jni/NativeMultinetworkJni.cpp
deleted file mode 100644
index 60e31bc..0000000
--- a/tests/cts/net/jni/NativeMultinetworkJni.cpp
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#define LOG_TAG "MultinetworkApiTest"
-
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <jni.h>
-#include <netdb.h>
-#include <poll.h> /* poll */
-#include <resolv.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-
-#include <string>
-
-#include <android/log.h>
-#include <android/multinetwork.h>
-#include <nativehelper/JNIHelp.h>
-
-#define LOGD(fmt, ...) \
-        __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, fmt, ##__VA_ARGS__)
-
-#define EXPECT_GE(env, actual, expected, msg)                        \
-    do {                                                             \
-        if (actual < expected) {                                     \
-            jniThrowExceptionFmt(env, "java/lang/AssertionError",    \
-                    "%s:%d: %s EXPECT_GE: expected %d, got %d",      \
-                    __FILE__, __LINE__, msg, expected, actual);      \
-        }                                                            \
-    } while (0)
-
-#define EXPECT_GT(env, actual, expected, msg)                        \
-    do {                                                             \
-        if (actual <= expected) {                                    \
-            jniThrowExceptionFmt(env, "java/lang/AssertionError",    \
-                    "%s:%d: %s EXPECT_GT: expected %d, got %d",      \
-                    __FILE__, __LINE__, msg, expected, actual);      \
-        }                                                            \
-    } while (0)
-
-#define EXPECT_EQ(env, expected, actual, msg)                        \
-    do {                                                             \
-        if (actual != expected) {                                    \
-            jniThrowExceptionFmt(env, "java/lang/AssertionError",    \
-                    "%s:%d: %s EXPECT_EQ: expected %d, got %d",      \
-                    __FILE__, __LINE__, msg, expected, actual);      \
-        }                                                            \
-    } while (0)
-
-static const int MAXPACKET = 8 * 1024;
-static const int TIMEOUT_MS = 15000;
-static const char kHostname[] = "connectivitycheck.android.com";
-static const char kNxDomainName[] = "test1-nx.metric.gstatic.com";
-static const char kGoogleName[] = "www.google.com";
-
-int makeQuery(const char* name, int qtype, uint8_t* buf, size_t buflen) {
-    return res_mkquery(ns_o_query, name, ns_c_in, qtype, NULL, 0, NULL, buf, buflen);
-}
-
-int getAsyncResponse(JNIEnv* env, int fd, int timeoutMs, int* rcode, uint8_t* buf, size_t bufLen) {
-    struct pollfd wait_fd = { .fd = fd, .events = POLLIN };
-
-    poll(&wait_fd, 1, timeoutMs);
-    if (wait_fd.revents & POLLIN) {
-        int n = android_res_nresult(fd, rcode, buf, bufLen);
-        // Verify that android_res_nresult() closed the fd
-        char dummy;
-        EXPECT_EQ(env, -1, read(fd, &dummy, sizeof(dummy)), "res_nresult check for closing fd");
-        EXPECT_EQ(env, EBADF, errno, "res_nresult check for errno");
-        return n;
-    }
-
-    return -ETIMEDOUT;
-}
-
-int extractIpAddressAnswers(uint8_t* buf, size_t bufLen, int family) {
-    ns_msg handle;
-    if (ns_initparse((const uint8_t*) buf, bufLen, &handle) < 0) {
-        return -errno;
-    }
-    const int ancount = ns_msg_count(handle, ns_s_an);
-    // Answer count = 0 is valid(e.g. response of query with root)
-    if (!ancount) {
-        return 0;
-    }
-    ns_rr rr;
-    bool hasValidAns = false;
-    for (int i = 0; i < ancount; i++) {
-        if (ns_parserr(&handle, ns_s_an, i, &rr) < 0) {
-            // If there is no valid answer, test will fail.
-            continue;
-        }
-        const uint8_t* rdata = ns_rr_rdata(rr);
-        char buffer[INET6_ADDRSTRLEN];
-        if (inet_ntop(family, (const char*) rdata, buffer, sizeof(buffer)) == NULL) {
-            return -errno;
-        }
-        hasValidAns = true;
-    }
-    return hasValidAns ? 0 : -EBADMSG;
-}
-
-int expectAnswersValid(JNIEnv* env, int fd, int family, int expectedRcode) {
-    int rcode = -1;
-    uint8_t buf[MAXPACKET] = {};
-    int res = getAsyncResponse(env, fd, TIMEOUT_MS, &rcode, buf, MAXPACKET);
-    if (res < 0) {
-        return res;
-    }
-
-    EXPECT_EQ(env, expectedRcode, rcode, "rcode is not expected");
-
-    if (expectedRcode == ns_r_noerror && res > 0) {
-        return extractIpAddressAnswers(buf, res, family);
-    }
-    return 0;
-}
-
-int expectAnswersNotValid(JNIEnv* env, int fd, int expectedErrno) {
-    int rcode = -1;
-    uint8_t buf[MAXPACKET] = {};
-    int res = getAsyncResponse(env, fd, TIMEOUT_MS, &rcode, buf, MAXPACKET);
-    if (res != expectedErrno) {
-        LOGD("res:%d, expectedErrno = %d", res, expectedErrno);
-        return (res > 0) ? -EREMOTEIO : res;
-    }
-    return 0;
-}
-
-extern "C"
-JNIEXPORT void Java_android_net_cts_MultinetworkApiTest_runResNqueryCheck(
-        JNIEnv* env, jclass, jlong nethandle) {
-    net_handle_t handle = (net_handle_t) nethandle;
-
-    // V4
-    int fd = android_res_nquery(handle, kHostname, ns_c_in, ns_t_a, 0);
-    EXPECT_GE(env, fd, 0, "v4 res_nquery");
-    EXPECT_EQ(env, 0, expectAnswersValid(env, fd, AF_INET, ns_r_noerror),
-            "v4 res_nquery check answers");
-
-    // V6
-    fd = android_res_nquery(handle, kHostname, ns_c_in, ns_t_aaaa, 0);
-    EXPECT_GE(env, fd, 0, "v6 res_nquery");
-    EXPECT_EQ(env, 0, expectAnswersValid(env, fd, AF_INET, ns_r_noerror),
-            "v6 res_nquery check answers");
-}
-
-extern "C"
-JNIEXPORT void Java_android_net_cts_MultinetworkApiTest_runResNsendCheck(
-        JNIEnv* env, jclass, jlong nethandle) {
-    net_handle_t handle = (net_handle_t) nethandle;
-    // V4
-    uint8_t buf1[MAXPACKET] = {};
-
-    int len1 = makeQuery(kGoogleName, ns_t_a, buf1, sizeof(buf1));
-    EXPECT_GT(env, len1, 0, "v4 res_mkquery 1st");
-
-    uint8_t buf2[MAXPACKET] = {};
-    int len2 = makeQuery(kHostname, ns_t_a, buf2, sizeof(buf2));
-    EXPECT_GT(env, len2, 0, "v4 res_mkquery 2nd");
-
-    int fd1 = android_res_nsend(handle, buf1, len1, 0);
-    EXPECT_GE(env, fd1, 0, "v4 res_nsend 1st");
-    int fd2 = android_res_nsend(handle, buf2, len2, 0);
-    EXPECT_GE(env, fd2, 0, "v4 res_nsend 2nd");
-
-    EXPECT_EQ(env, 0, expectAnswersValid(env, fd2, AF_INET, ns_r_noerror),
-            "v4 res_nsend 2nd check answers");
-    EXPECT_EQ(env, 0, expectAnswersValid(env, fd1, AF_INET, ns_r_noerror),
-            "v4 res_nsend 1st check answers");
-
-    // V6
-    memset(buf1, 0, sizeof(buf1));
-    memset(buf2, 0, sizeof(buf2));
-    len1 = makeQuery(kGoogleName, ns_t_aaaa, buf1, sizeof(buf1));
-    EXPECT_GT(env, len1, 0, "v6 res_mkquery 1st");
-    len2 = makeQuery(kHostname, ns_t_aaaa, buf2, sizeof(buf2));
-    EXPECT_GT(env, len2, 0, "v6 res_mkquery 2nd");
-
-    fd1 = android_res_nsend(handle, buf1, len1, 0);
-    EXPECT_GE(env, fd1, 0, "v6 res_nsend 1st");
-    fd2 = android_res_nsend(handle, buf2, len2, 0);
-    EXPECT_GE(env, fd2, 0, "v6 res_nsend 2nd");
-
-    EXPECT_EQ(env, 0, expectAnswersValid(env, fd2, AF_INET6, ns_r_noerror),
-            "v6 res_nsend 2nd check answers");
-    EXPECT_EQ(env, 0, expectAnswersValid(env, fd1, AF_INET6, ns_r_noerror),
-            "v6 res_nsend 1st check answers");
-}
-
-extern "C"
-JNIEXPORT void Java_android_net_cts_MultinetworkApiTest_runResNnxDomainCheck(
-        JNIEnv* env, jclass, jlong nethandle) {
-    net_handle_t handle = (net_handle_t) nethandle;
-
-    // res_nquery V4 NXDOMAIN
-    int fd = android_res_nquery(handle, kNxDomainName, ns_c_in, ns_t_a, 0);
-    EXPECT_GE(env, fd, 0, "v4 res_nquery NXDOMAIN");
-    EXPECT_EQ(env, 0, expectAnswersValid(env, fd, AF_INET, ns_r_nxdomain),
-            "v4 res_nquery NXDOMAIN check answers");
-
-    // res_nquery V6 NXDOMAIN
-    fd = android_res_nquery(handle, kNxDomainName, ns_c_in, ns_t_aaaa, 0);
-    EXPECT_GE(env, fd, 0, "v6 res_nquery NXDOMAIN");
-    EXPECT_EQ(env, 0, expectAnswersValid(env, fd, AF_INET6, ns_r_nxdomain),
-            "v6 res_nquery NXDOMAIN check answers");
-
-    uint8_t buf[MAXPACKET] = {};
-    // res_nsend V4 NXDOMAIN
-    int len = makeQuery(kNxDomainName, ns_t_a, buf, sizeof(buf));
-    EXPECT_GT(env, len, 0, "v4 res_mkquery NXDOMAIN");
-    fd = android_res_nsend(handle, buf, len, 0);
-    EXPECT_GE(env, fd, 0, "v4 res_nsend NXDOMAIN");
-    EXPECT_EQ(env, 0, expectAnswersValid(env, fd, AF_INET, ns_r_nxdomain),
-            "v4 res_nsend NXDOMAIN check answers");
-
-    // res_nsend V6 NXDOMAIN
-    memset(buf, 0, sizeof(buf));
-    len = makeQuery(kNxDomainName, ns_t_aaaa, buf, sizeof(buf));
-    EXPECT_GT(env, len, 0, "v6 res_mkquery NXDOMAIN");
-    fd = android_res_nsend(handle, buf, len, 0);
-    EXPECT_GE(env, fd, 0, "v6 res_nsend NXDOMAIN");
-    EXPECT_EQ(env, 0, expectAnswersValid(env, fd, AF_INET6, ns_r_nxdomain),
-            "v6 res_nsend NXDOMAIN check answers");
-}
-
-
-extern "C"
-JNIEXPORT void Java_android_net_cts_MultinetworkApiTest_runResNcancelCheck(
-        JNIEnv* env, jclass, jlong nethandle) {
-    net_handle_t handle = (net_handle_t) nethandle;
-
-    int fd = android_res_nquery(handle, kGoogleName, ns_c_in, ns_t_a, 0);
-    errno = 0;
-    android_res_cancel(fd);
-    int err = errno;
-    EXPECT_EQ(env, 0, err, "res_cancel");
-    // DO NOT call cancel or result with the same fd more than once,
-    // otherwise it will hit fdsan double-close fd.
-}
-
-extern "C"
-JNIEXPORT void Java_android_net_cts_MultinetworkApiTest_runResNapiMalformedCheck(
-        JNIEnv* env, jclass, jlong nethandle) {
-    net_handle_t handle = (net_handle_t) nethandle;
-
-    // It is the equivalent of "dig . a", Query with an empty name.
-    int fd = android_res_nquery(handle, "", ns_c_in, ns_t_a, 0);
-    EXPECT_GE(env, fd, 0, "res_nquery root");
-    EXPECT_EQ(env, 0, expectAnswersValid(env, fd, AF_INET, ns_r_noerror),
-            "res_nquery root check answers");
-
-    // Label limit 63
-    std::string exceedingLabelQuery = "www." + std::string(70, 'g') + ".com";
-    // Name limit 255
-    std::string exceedingDomainQuery = "www." + std::string(255, 'g') + ".com";
-
-    fd = android_res_nquery(handle, exceedingLabelQuery.c_str(), ns_c_in, ns_t_a, 0);
-    EXPECT_EQ(env, -EMSGSIZE, fd, "res_nquery exceedingLabelQuery");
-    fd = android_res_nquery(handle, exceedingDomainQuery.c_str(), ns_c_in, ns_t_aaaa, 0);
-    EXPECT_EQ(env, -EMSGSIZE, fd, "res_nquery exceedingDomainQuery");
-
-    uint8_t buf[10] = {};
-    // empty BLOB
-    fd = android_res_nsend(handle, buf, 10, 0);
-    EXPECT_GE(env, fd, 0, "res_nsend empty BLOB");
-    EXPECT_EQ(env, 0, expectAnswersNotValid(env, fd, -EINVAL),
-            "res_nsend empty BLOB check answers");
-
-    uint8_t largeBuf[2 * MAXPACKET] = {};
-    // A buffer larger than 8KB
-    fd = android_res_nsend(handle, largeBuf, sizeof(largeBuf), 0);
-    EXPECT_EQ(env, -EMSGSIZE, fd, "res_nsend buffer larger than 8KB");
-
-    // 5000 bytes filled with 0. This returns EMSGSIZE because FrameworkListener limits the size of
-    // commands to 4096 bytes.
-    fd = android_res_nsend(handle, largeBuf, 5000, 0);
-    EXPECT_EQ(env, -EMSGSIZE, fd, "res_nsend 5000 bytes filled with 0");
-
-    // 500 bytes filled with 0
-    fd = android_res_nsend(handle, largeBuf, 500, 0);
-    EXPECT_GE(env, fd, 0, "res_nsend 500 bytes filled with 0");
-    EXPECT_EQ(env, 0, expectAnswersNotValid(env, fd, -EINVAL),
-            "res_nsend 500 bytes filled with 0 check answers");
-
-    // 5000 bytes filled with 0xFF
-    uint8_t ffBuf[5001] = {};
-    memset(ffBuf, 0xFF, sizeof(ffBuf));
-    ffBuf[5000] = '\0';
-    fd = android_res_nsend(handle, ffBuf, sizeof(ffBuf), 0);
-    EXPECT_EQ(env, -EMSGSIZE, fd, "res_nsend 5000 bytes filled with 0xFF");
-
-    // 500 bytes filled with 0xFF
-    ffBuf[500] = '\0';
-    fd = android_res_nsend(handle, ffBuf, 501, 0);
-    EXPECT_GE(env, fd, 0, "res_nsend 500 bytes filled with 0xFF");
-    EXPECT_EQ(env, 0, expectAnswersNotValid(env, fd, -EINVAL),
-            "res_nsend 500 bytes filled with 0xFF check answers");
-}
-
-extern "C"
-JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runGetaddrinfoCheck(
-        JNIEnv*, jclass, jlong nethandle) {
-    net_handle_t handle = (net_handle_t) nethandle;
-    struct addrinfo *res = NULL;
-
-    errno = 0;
-    int rval = android_getaddrinfofornetwork(handle, kHostname, NULL, NULL, &res);
-    const int saved_errno = errno;
-    freeaddrinfo(res);
-
-    LOGD("android_getaddrinfofornetwork(%" PRIu64 ", %s) returned rval=%d errno=%d",
-          handle, kHostname, rval, saved_errno);
-    return rval == 0 ? 0 : -saved_errno;
-}
-
-extern "C"
-JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runSetprocnetwork(
-        JNIEnv*, jclass, jlong nethandle) {
-    net_handle_t handle = (net_handle_t) nethandle;
-
-    errno = 0;
-    int rval = android_setprocnetwork(handle);
-    const int saved_errno = errno;
-    LOGD("android_setprocnetwork(%" PRIu64 ") returned rval=%d errno=%d",
-          handle, rval, saved_errno);
-    return rval == 0 ? 0 : -saved_errno;
-}
-
-extern "C"
-JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runSetsocknetwork(
-        JNIEnv*, jclass, jlong nethandle) {
-    net_handle_t handle = (net_handle_t) nethandle;
-
-    errno = 0;
-    int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
-    if (fd < 0) {
-        LOGD("socket() failed, errno=%d", errno);
-        return -errno;
-    }
-
-    errno = 0;
-    int rval = android_setsocknetwork(handle, fd);
-    const int saved_errno = errno;
-    LOGD("android_setprocnetwork(%" PRIu64 ", %d) returned rval=%d errno=%d",
-          handle, fd, rval, saved_errno);
-    close(fd);
-    return rval == 0 ? 0 : -saved_errno;
-}
-
-// Use sizeof("x") - 1 because we need a compile-time constant, and strlen("x")
-// isn't guaranteed to fold to a constant.
-static const int kSockaddrStrLen = INET6_ADDRSTRLEN + sizeof("[]:65535") - 1;
-
-void sockaddr_ntop(const struct sockaddr *sa, socklen_t salen, char *dst, const size_t size) {
-    char addrstr[INET6_ADDRSTRLEN];
-    char portstr[sizeof("65535")];
-    char buf[kSockaddrStrLen+1];
-
-    int ret = getnameinfo(sa, salen,
-                          addrstr, sizeof(addrstr),
-                          portstr, sizeof(portstr),
-                          NI_NUMERICHOST | NI_NUMERICSERV);
-    if (ret == 0) {
-        snprintf(buf, sizeof(buf),
-                 (sa->sa_family == AF_INET6) ? "[%s]:%s" : "%s:%s",
-                 addrstr, portstr);
-    } else {
-        sprintf(buf, "???");
-    }
-
-    strlcpy(dst, buf, size);
-}
-
-extern "C"
-JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck(
-        JNIEnv*, jclass, jlong nethandle) {
-    const struct addrinfo kHints = {
-        .ai_flags = AI_ADDRCONFIG,
-        .ai_family = AF_UNSPEC,
-        .ai_socktype = SOCK_DGRAM,
-        .ai_protocol = IPPROTO_UDP,
-    };
-    struct addrinfo *res = NULL;
-    net_handle_t handle = (net_handle_t) nethandle;
-
-    static const char kPort[] = "443";
-    int rval = android_getaddrinfofornetwork(handle, kHostname, kPort, &kHints, &res);
-    if (rval != 0) {
-        LOGD("android_getaddrinfofornetwork(%llu, %s) returned rval=%d errno=%d",
-              handle, kHostname, rval, errno);
-        freeaddrinfo(res);
-        return -errno;
-    }
-
-    // Rely upon getaddrinfo sorting the best destination to the front.
-    int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
-    if (fd < 0) {
-        LOGD("socket(%d, %d, %d) failed, errno=%d",
-              res->ai_family, res->ai_socktype, res->ai_protocol, errno);
-        freeaddrinfo(res);
-        return -errno;
-    }
-
-    rval = android_setsocknetwork(handle, fd);
-    LOGD("android_setprocnetwork(%llu, %d) returned rval=%d errno=%d",
-          handle, fd, rval, errno);
-    if (rval != 0) {
-        close(fd);
-        freeaddrinfo(res);
-        return -errno;
-    }
-
-    char addrstr[kSockaddrStrLen+1];
-    sockaddr_ntop(res->ai_addr, res->ai_addrlen, addrstr, sizeof(addrstr));
-    LOGD("Attempting connect() to %s ...", addrstr);
-
-    rval = connect(fd, res->ai_addr, res->ai_addrlen);
-    if (rval != 0) {
-        close(fd);
-        freeaddrinfo(res);
-        return -errno;
-    }
-    freeaddrinfo(res);
-
-    struct sockaddr_storage src_addr;
-    socklen_t src_addrlen = sizeof(src_addr);
-    if (getsockname(fd, (struct sockaddr *)&src_addr, &src_addrlen) != 0) {
-        close(fd);
-        return -errno;
-    }
-    sockaddr_ntop((const struct sockaddr *)&src_addr, sizeof(src_addr), addrstr, sizeof(addrstr));
-    LOGD("... from %s", addrstr);
-
-    // Don't let reads or writes block indefinitely.
-    const struct timeval timeo = { 2, 0 };  // 2 seconds
-    setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));
-    setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo));
-
-    // For reference see:
-    //     https://datatracker.ietf.org/doc/html/draft-ietf-quic-invariants
-    uint8_t quic_packet[1200] = {
-        0xc0,                    // long header
-        0xaa, 0xda, 0xca, 0xca,  // reserved-space version number
-        0x08,                    // destination connection ID length
-        0, 0, 0, 0, 0, 0, 0, 0,  // 64bit connection ID
-        0x00,                    // source connection ID length
-    };
-
-    arc4random_buf(quic_packet + 6, 8);  // random connection ID
-
-    uint8_t response[1500];
-    ssize_t sent, rcvd;
-    static const int MAX_RETRIES = 5;
-    int i, errnum = 0;
-
-    for (i = 0; i < MAX_RETRIES; i++) {
-        sent = send(fd, quic_packet, sizeof(quic_packet), 0);
-        if (sent < (ssize_t)sizeof(quic_packet)) {
-            errnum = errno;
-            LOGD("send(QUIC packet) returned sent=%zd, errno=%d", sent, errnum);
-            close(fd);
-            return -errnum;
-        }
-
-        rcvd = recv(fd, response, sizeof(response), 0);
-        if (rcvd > 0) {
-            break;
-        } else {
-            errnum = errno;
-            LOGD("[%d/%d] recv(QUIC response) returned rcvd=%zd, errno=%d",
-                  i + 1, MAX_RETRIES, rcvd, errnum);
-        }
-    }
-    if (rcvd < 15) {
-        LOGD("QUIC UDP %s: sent=%zd but rcvd=%zd, errno=%d", kPort, sent, rcvd, errnum);
-        if (rcvd <= 0) {
-            LOGD("Does this network block UDP port %s?", kPort);
-        }
-        close(fd);
-        return -EPROTO;
-    }
-
-    int conn_id_cmp = memcmp(quic_packet + 6, response + 7, 8);
-    if (conn_id_cmp != 0) {
-        LOGD("sent and received connection IDs do not match");
-        close(fd);
-        return -EPROTO;
-    }
-
-    // TODO: Replace this quick 'n' dirty test with proper QUIC-capable code.
-
-    close(fd);
-    return 0;
-}
diff --git a/tests/cts/net/native/dns/Android.bp b/tests/cts/net/native/dns/Android.bp
deleted file mode 100644
index 1704a2b..0000000
--- a/tests/cts/net/native/dns/Android.bp
+++ /dev/null
@@ -1,40 +0,0 @@
-cc_defaults {
-    name: "dns_async_defaults",
-
-    cflags: [
-        "-fstack-protector-all",
-        "-g",
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-        "-Wnullable-to-nonnull-conversion",
-        "-Wsign-compare",
-        "-Wthread-safety",
-        "-Wunused-parameter",
-    ],
-    srcs: [
-        "NativeDnsAsyncTest.cpp",
-    ],
-    shared_libs: [
-        "libandroid",
-        "liblog",
-        "libutils",
-    ],
-}
-
-cc_test {
-    name: "CtsNativeNetDnsTestCases",
-    defaults: ["dns_async_defaults"],
-    multilib: {
-        lib32: {
-            suffix: "32",
-        },
-        lib64: {
-            suffix: "64",
-        },
-    },
-    test_suites: [
-        "cts",
-        "mts",
-    ],
-}
diff --git a/tests/cts/net/native/dns/AndroidTest.xml b/tests/cts/net/native/dns/AndroidTest.xml
deleted file mode 100644
index 6d03c23..0000000
--- a/tests/cts/net/native/dns/AndroidTest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 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.
--->
-<configuration description="Config for CTS Native Network dns test cases">
-    <option name="test-suite-tag" value="cts" />
-    <option name="config-descriptor:metadata" key="component" value="networking" />
-    <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
-    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
-    <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
-        <option name="cleanup" value="true" />
-        <option name="push" value="CtsNativeNetDnsTestCases->/data/local/tmp/CtsNativeNetDnsTestCases" />
-        <option name="append-bitness" value="true" />
-    </target_preparer>
-    <test class="com.android.tradefed.testtype.GTest" >
-        <option name="native-test-device-path" value="/data/local/tmp" />
-        <option name="module-name" value="CtsNativeNetDnsTestCases" />
-        <option name="runtime-hint" value="1m" />
-    </test>
-</configuration>
diff --git a/tests/cts/net/native/dns/NativeDnsAsyncTest.cpp b/tests/cts/net/native/dns/NativeDnsAsyncTest.cpp
deleted file mode 100644
index e501475..0000000
--- a/tests/cts/net/native/dns/NativeDnsAsyncTest.cpp
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * 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.
- */
-
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-#include <error.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <netinet/in.h>
-#include <poll.h> /* poll */
-#include <resolv.h>
-#include <string.h>
-#include <sys/socket.h>
-
-#include <android/multinetwork.h>
-#include <gtest/gtest.h>
-
-namespace {
-constexpr int MAXPACKET = 8 * 1024;
-constexpr int PTON_MAX = 16;
-constexpr int TIMEOUT_MS = 10000;
-
-int getAsyncResponse(int fd, int timeoutMs, int* rcode, uint8_t* buf, size_t bufLen) {
-    struct pollfd wait_fd[1];
-    wait_fd[0].fd = fd;
-    wait_fd[0].events = POLLIN;
-    short revents;
-    int ret;
-    ret = poll(wait_fd, 1, timeoutMs);
-    revents = wait_fd[0].revents;
-    if (revents & POLLIN) {
-        int n = android_res_nresult(fd, rcode, buf, bufLen);
-        // Verify that android_res_nresult() closed the fd
-        char dummy;
-        EXPECT_EQ(-1, read(fd, &dummy, sizeof dummy));
-        EXPECT_EQ(EBADF, errno);
-        return n;
-    }
-
-    return -1;
-}
-
-std::vector<std::string> extractIpAddressAnswers(uint8_t* buf, size_t bufLen, int ipType) {
-    ns_msg handle;
-    if (ns_initparse((const uint8_t*) buf, bufLen, &handle) < 0) {
-        return {};
-    }
-    const int ancount = ns_msg_count(handle, ns_s_an);
-    ns_rr rr;
-    std::vector<std::string> answers;
-    for (int i = 0; i < ancount; i++) {
-        if (ns_parserr(&handle, ns_s_an, i, &rr) < 0) {
-            continue;
-        }
-        const uint8_t* rdata = ns_rr_rdata(rr);
-        char buffer[INET6_ADDRSTRLEN];
-        if (inet_ntop(ipType, (const char*) rdata, buffer, sizeof(buffer))) {
-            answers.push_back(buffer);
-        }
-    }
-    return answers;
-}
-
-void expectAnswersValid(int fd, int ipType, int expectedRcode) {
-    int rcode = -1;
-    uint8_t buf[MAXPACKET] = {};
-    int res = getAsyncResponse(fd, TIMEOUT_MS, &rcode, buf, MAXPACKET);
-    EXPECT_GE(res, 0);
-    EXPECT_EQ(rcode, expectedRcode);
-
-    if (expectedRcode == ns_r_noerror) {
-        auto answers = extractIpAddressAnswers(buf, res, ipType);
-        EXPECT_GE(answers.size(), 0U);
-        for (auto &answer : answers) {
-            char pton[PTON_MAX];
-            EXPECT_EQ(1, inet_pton(ipType, answer.c_str(), pton));
-        }
-    }
-}
-
-void expectAnswersNotValid(int fd, int expectedErrno) {
-    int rcode = -1;
-    uint8_t buf[MAXPACKET] = {};
-    int res = getAsyncResponse(fd, TIMEOUT_MS, &rcode, buf, MAXPACKET);
-    EXPECT_EQ(expectedErrno, res);
-}
-
-} // namespace
-
-TEST (NativeDnsAsyncTest, Async_Query) {
-    // V4
-    int fd1 = android_res_nquery(
-            NETWORK_UNSPECIFIED, "www.google.com", ns_c_in, ns_t_a, 0);
-    EXPECT_GE(fd1, 0);
-    int fd2 = android_res_nquery(
-            NETWORK_UNSPECIFIED, "www.youtube.com", ns_c_in, ns_t_a, 0);
-    EXPECT_GE(fd2, 0);
-    expectAnswersValid(fd2, AF_INET, ns_r_noerror);
-    expectAnswersValid(fd1, AF_INET, ns_r_noerror);
-
-    // V6
-    fd1 = android_res_nquery(
-            NETWORK_UNSPECIFIED, "www.google.com", ns_c_in, ns_t_aaaa, 0);
-    EXPECT_GE(fd1, 0);
-    fd2 = android_res_nquery(
-            NETWORK_UNSPECIFIED, "www.youtube.com", ns_c_in, ns_t_aaaa, 0);
-    EXPECT_GE(fd2, 0);
-    expectAnswersValid(fd2, AF_INET6, ns_r_noerror);
-    expectAnswersValid(fd1, AF_INET6, ns_r_noerror);
-}
-
-TEST (NativeDnsAsyncTest, Async_Send) {
-    // V4
-    uint8_t buf1[MAXPACKET] = {};
-    int len1 = res_mkquery(ns_o_query, "www.googleapis.com",
-            ns_c_in, ns_t_a, nullptr, 0, nullptr, buf1, sizeof(buf1));
-    EXPECT_GT(len1, 0);
-
-    uint8_t buf2[MAXPACKET] = {};
-    int len2 = res_mkquery(ns_o_query, "play.googleapis.com",
-            ns_c_in, ns_t_a, nullptr, 0, nullptr, buf2, sizeof(buf2));
-    EXPECT_GT(len2, 0);
-
-    int fd1 = android_res_nsend(NETWORK_UNSPECIFIED, buf1, len1, 0);
-    EXPECT_GE(fd1, 0);
-    int fd2 = android_res_nsend(NETWORK_UNSPECIFIED, buf2, len2, 0);
-    EXPECT_GE(fd2, 0);
-
-    expectAnswersValid(fd2, AF_INET, ns_r_noerror);
-    expectAnswersValid(fd1, AF_INET, ns_r_noerror);
-
-    // V6
-    memset(buf1, 0, sizeof(buf1));
-    memset(buf2, 0, sizeof(buf2));
-    len1 = res_mkquery(ns_o_query, "www.googleapis.com",
-            ns_c_in, ns_t_aaaa, nullptr, 0, nullptr, buf1, sizeof(buf1));
-    EXPECT_GT(len1, 0);
-    len2 = res_mkquery(ns_o_query, "play.googleapis.com",
-            ns_c_in, ns_t_aaaa, nullptr, 0, nullptr, buf2, sizeof(buf2));
-    EXPECT_GT(len2, 0);
-
-    fd1 = android_res_nsend(NETWORK_UNSPECIFIED, buf1, len1, 0);
-    EXPECT_GE(fd1, 0);
-    fd2 = android_res_nsend(NETWORK_UNSPECIFIED, buf2, len2, 0);
-    EXPECT_GE(fd2, 0);
-
-    expectAnswersValid(fd2, AF_INET6, ns_r_noerror);
-    expectAnswersValid(fd1, AF_INET6, ns_r_noerror);
-}
-
-TEST (NativeDnsAsyncTest, Async_NXDOMAIN) {
-    uint8_t buf[MAXPACKET] = {};
-    int len = res_mkquery(ns_o_query, "test1-nx.metric.gstatic.com",
-            ns_c_in, ns_t_a, nullptr, 0, nullptr, buf, sizeof(buf));
-    EXPECT_GT(len, 0);
-    int fd1 = android_res_nsend(NETWORK_UNSPECIFIED, buf, len, ANDROID_RESOLV_NO_CACHE_LOOKUP);
-    EXPECT_GE(fd1, 0);
-
-    len = res_mkquery(ns_o_query, "test2-nx.metric.gstatic.com",
-            ns_c_in, ns_t_a, nullptr, 0, nullptr, buf, sizeof(buf));
-    EXPECT_GT(len, 0);
-    int fd2 = android_res_nsend(NETWORK_UNSPECIFIED, buf, len, ANDROID_RESOLV_NO_CACHE_LOOKUP);
-    EXPECT_GE(fd2, 0);
-
-    expectAnswersValid(fd2, AF_INET, ns_r_nxdomain);
-    expectAnswersValid(fd1, AF_INET, ns_r_nxdomain);
-
-    fd1 = android_res_nquery(
-            NETWORK_UNSPECIFIED, "test3-nx.metric.gstatic.com",
-            ns_c_in, ns_t_aaaa, ANDROID_RESOLV_NO_CACHE_LOOKUP);
-    EXPECT_GE(fd1, 0);
-    fd2 = android_res_nquery(
-            NETWORK_UNSPECIFIED, "test4-nx.metric.gstatic.com",
-            ns_c_in, ns_t_aaaa, ANDROID_RESOLV_NO_CACHE_LOOKUP);
-    EXPECT_GE(fd2, 0);
-    expectAnswersValid(fd2, AF_INET6, ns_r_nxdomain);
-    expectAnswersValid(fd1, AF_INET6, ns_r_nxdomain);
-}
-
-TEST (NativeDnsAsyncTest, Async_Cancel) {
-    int fd = android_res_nquery(
-            NETWORK_UNSPECIFIED, "www.google.com", ns_c_in, ns_t_a, 0);
-    errno = 0;
-    android_res_cancel(fd);
-    int err = errno;
-    EXPECT_EQ(err, 0);
-    // DO NOT call cancel or result with the same fd more than once,
-    // otherwise it will hit fdsan double-close fd.
-}
-
-TEST (NativeDnsAsyncTest, Async_Query_MALFORMED) {
-    // Empty string to create BLOB and query, we will get empty result and rcode = 0
-    // on DNSTLS.
-    int fd = android_res_nquery(
-            NETWORK_UNSPECIFIED, "", ns_c_in, ns_t_a, 0);
-    EXPECT_GE(fd, 0);
-    expectAnswersValid(fd, AF_INET, ns_r_noerror);
-
-    std::string exceedingLabelQuery = "www." + std::string(70, 'g') + ".com";
-    std::string exceedingDomainQuery = "www." + std::string(255, 'g') + ".com";
-
-    fd = android_res_nquery(NETWORK_UNSPECIFIED,
-            exceedingLabelQuery.c_str(), ns_c_in, ns_t_a, 0);
-    EXPECT_EQ(-EMSGSIZE, fd);
-    fd = android_res_nquery(NETWORK_UNSPECIFIED,
-            exceedingDomainQuery.c_str(), ns_c_in, ns_t_a, 0);
-    EXPECT_EQ(-EMSGSIZE, fd);
-}
-
-TEST (NativeDnsAsyncTest, Async_Send_MALFORMED) {
-    uint8_t buf[10] = {};
-    // empty BLOB
-    int fd = android_res_nsend(NETWORK_UNSPECIFIED, buf, 10, 0);
-    EXPECT_GE(fd, 0);
-    expectAnswersNotValid(fd, -EINVAL);
-
-    std::vector<uint8_t> largeBuf(2 * MAXPACKET, 0);
-    // A buffer larger than 8KB
-    fd = android_res_nsend(
-            NETWORK_UNSPECIFIED, largeBuf.data(), largeBuf.size(), 0);
-    EXPECT_EQ(-EMSGSIZE, fd);
-
-    // 5000 bytes filled with 0. This returns EMSGSIZE because FrameworkListener limits the size of
-    // commands to 4096 bytes.
-    fd = android_res_nsend(NETWORK_UNSPECIFIED, largeBuf.data(), 5000, 0);
-    EXPECT_EQ(-EMSGSIZE, fd);
-
-    // 500 bytes filled with 0
-    fd = android_res_nsend(NETWORK_UNSPECIFIED, largeBuf.data(), 500, 0);
-    EXPECT_GE(fd, 0);
-    expectAnswersNotValid(fd, -EINVAL);
-
-    // 5000 bytes filled with 0xFF
-    std::vector<uint8_t> ffBuf(5000, 0xFF);
-    fd = android_res_nsend(
-            NETWORK_UNSPECIFIED, ffBuf.data(), ffBuf.size(), 0);
-    EXPECT_EQ(-EMSGSIZE, fd);
-
-    // 500 bytes filled with 0xFF
-    fd = android_res_nsend(NETWORK_UNSPECIFIED, ffBuf.data(), 500, 0);
-    EXPECT_GE(fd, 0);
-    expectAnswersNotValid(fd, -EINVAL);
-}
diff --git a/tests/cts/net/native/qtaguid/Android.bp b/tests/cts/net/native/qtaguid/Android.bp
deleted file mode 100644
index 23a0cf7..0000000
--- a/tests/cts/net/native/qtaguid/Android.bp
+++ /dev/null
@@ -1,53 +0,0 @@
-// 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.
-
-// Build the unit tests.
-
-cc_test {
-    name: "CtsNativeNetTestCases",
-
-    compile_multilib: "both",
-    multilib: {
-        lib32: {
-            suffix: "32",
-        },
-        lib64: {
-            suffix: "64",
-        },
-    },
-
-    srcs: ["src/NativeQtaguidTest.cpp"],
-
-    shared_libs: [
-        "libutils",
-        "liblog",
-    ],
-
-    static_libs: [
-        "libgtest",
-        "libqtaguid",
-    ],
-
-    // Tag this module as a cts test artifact
-    test_suites: [
-        "cts",
-        "vts10",
-    ],
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-    ],
-
-}
diff --git a/tests/cts/net/native/qtaguid/AndroidTest.xml b/tests/cts/net/native/qtaguid/AndroidTest.xml
deleted file mode 100644
index fa4b2cf..0000000
--- a/tests/cts/net/native/qtaguid/AndroidTest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 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.
--->
-<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" />
-    <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
-    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
-    <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
-        <option name="cleanup" value="true" />
-        <option name="push" value="CtsNativeNetTestCases->/data/local/tmp/CtsNativeNetTestCases" />
-        <option name="append-bitness" value="true" />
-    </target_preparer>
-    <test class="com.android.tradefed.testtype.GTest" >
-        <option name="native-test-device-path" value="/data/local/tmp" />
-        <option name="module-name" value="CtsNativeNetTestCases" />
-        <option name="runtime-hint" value="1m" />
-    </test>
-</configuration>
diff --git a/tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp b/tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp
deleted file mode 100644
index 7dc6240..0000000
--- a/tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * 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.
- */
-
-#include <arpa/inet.h>
-#include <error.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/socket.h>
-
-#include <gtest/gtest.h>
-#include <qtaguid/qtaguid.h>
-
-int canAccessQtaguidFile() {
-    int fd = open("/proc/net/xt_qtaguid/ctrl", O_RDONLY | O_CLOEXEC);
-    close(fd);
-    return fd != -1;
-}
-
-#define SKIP_IF_QTAGUID_NOT_SUPPORTED()                                                       \
-  do {                                                                                        \
-    int res = canAccessQtaguidFile();                                                      \
-    ASSERT_LE(0, res);                                                                        \
-    if (!res) {                                                                               \
-          GTEST_LOG_(INFO) << "This test is skipped since kernel may not have the module\n";  \
-          return;                                                                             \
-    }                                                                                         \
-  } while (0)
-
-int getCtrlSkInfo(int tag, uid_t uid, uint64_t* sk_addr, int* ref_cnt) {
-    FILE *fp;
-    fp = fopen("/proc/net/xt_qtaguid/ctrl", "r");
-    if (!fp)
-        return -ENOENT;
-    uint64_t full_tag = (uint64_t)tag << 32 | uid;
-    char pattern[40];
-    snprintf(pattern, sizeof(pattern), " tag=0x%" PRIx64 " (uid=%" PRIu32 ")", full_tag, uid);
-
-    size_t len;
-    char *line_buffer = NULL;
-    while(getline(&line_buffer, &len, fp) != -1) {
-        if (strstr(line_buffer, pattern) == NULL)
-            continue;
-        int res;
-        pid_t dummy_pid;
-        uint64_t k_tag;
-        uint32_t k_uid;
-        const int TOTAL_PARAM = 5;
-        res = sscanf(line_buffer, "sock=%" PRIx64 " tag=0x%" PRIx64 " (uid=%" PRIu32 ") "
-                     "pid=%u f_count=%u", sk_addr, &k_tag, &k_uid,
-                     &dummy_pid, ref_cnt);
-        if (!(res == TOTAL_PARAM && k_tag == full_tag && k_uid == uid))
-            return -EINVAL;
-        free(line_buffer);
-        return 0;
-    }
-    free(line_buffer);
-    return -ENOENT;
-}
-
-void checkNoSocketPointerLeaks(int family) {
-    int sockfd = socket(family, SOCK_STREAM, 0);
-    uid_t uid = getuid();
-    int tag = arc4random();
-    int ref_cnt;
-    uint64_t sk_addr;
-    uint64_t expect_addr = 0;
-
-    EXPECT_EQ(0, legacy_tagSocket(sockfd, tag, uid));
-    EXPECT_EQ(0, getCtrlSkInfo(tag, uid, &sk_addr, &ref_cnt));
-    EXPECT_EQ(expect_addr, sk_addr);
-    close(sockfd);
-    EXPECT_EQ(-ENOENT, getCtrlSkInfo(tag, uid, &sk_addr, &ref_cnt));
-}
-
-TEST (NativeQtaguidTest, close_socket_without_untag) {
-    SKIP_IF_QTAGUID_NOT_SUPPORTED();
-
-    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
-    uid_t uid = getuid();
-    int tag = arc4random();
-    int ref_cnt;
-    uint64_t dummy_sk;
-    EXPECT_EQ(0, legacy_tagSocket(sockfd, tag, uid));
-    EXPECT_EQ(0, getCtrlSkInfo(tag, uid, &dummy_sk, &ref_cnt));
-    EXPECT_EQ(2, ref_cnt);
-    close(sockfd);
-    EXPECT_EQ(-ENOENT, getCtrlSkInfo(tag, uid, &dummy_sk, &ref_cnt));
-}
-
-TEST (NativeQtaguidTest, close_socket_without_untag_ipv6) {
-    SKIP_IF_QTAGUID_NOT_SUPPORTED();
-
-    int sockfd = socket(AF_INET6, SOCK_STREAM, 0);
-    uid_t uid = getuid();
-    int tag = arc4random();
-    int ref_cnt;
-    uint64_t dummy_sk;
-    EXPECT_EQ(0, legacy_tagSocket(sockfd, tag, uid));
-    EXPECT_EQ(0, getCtrlSkInfo(tag, uid, &dummy_sk, &ref_cnt));
-    EXPECT_EQ(2, ref_cnt);
-    close(sockfd);
-    EXPECT_EQ(-ENOENT, getCtrlSkInfo(tag, uid, &dummy_sk, &ref_cnt));
-}
-
-TEST (NativeQtaguidTest, no_socket_addr_leak) {
-  SKIP_IF_QTAGUID_NOT_SUPPORTED();
-
-  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/AirplaneModeTest.java b/tests/cts/net/src/android/net/cts/AirplaneModeTest.java
deleted file mode 100644
index 524e549..0000000
--- a/tests/cts/net/src/android/net/cts/AirplaneModeTest.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2016 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.content.ContentResolver;
-import android.content.Context;
-import android.platform.test.annotations.AppModeFull;
-import android.provider.Settings;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import java.lang.Thread;
-
-@AppModeFull(reason = "WRITE_SECURE_SETTINGS permission can't be granted to instant apps")
-public class AirplaneModeTest extends AndroidTestCase {
-    private static final String TAG = "AirplaneModeTest";
-    private static final String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
-    private static final String FEATURE_WIFI = "android.hardware.wifi";
-    private static final int TIMEOUT_MS = 10 * 1000;
-    private boolean mHasFeature;
-    private Context mContext;
-    private ContentResolver resolver;
-
-    public void setup() {
-        mContext= getContext();
-        resolver = mContext.getContentResolver();
-        mHasFeature = (mContext.getPackageManager().hasSystemFeature(FEATURE_BLUETOOTH)
-                       || mContext.getPackageManager().hasSystemFeature(FEATURE_WIFI));
-    }
-
-    public void testAirplaneMode() {
-        setup();
-        if (!mHasFeature) {
-            Log.i(TAG, "The device doesn't support network bluetooth or wifi feature");
-            return;
-        }
-
-        for (int testCount = 0; testCount < 2; testCount++) {
-            if (!doOneTest()) {
-                fail("Airplane mode failed to change in " + TIMEOUT_MS + "msec");
-                return;
-            }
-        }
-    }
-
-    private boolean doOneTest() {
-        boolean airplaneModeOn = isAirplaneModeOn();
-        setAirplaneModeOn(!airplaneModeOn);
-
-        try {
-            Thread.sleep(TIMEOUT_MS);
-        } catch (InterruptedException e) {
-            Log.e(TAG, "Sleep time interrupted.", e);
-        }
-
-        if (airplaneModeOn == isAirplaneModeOn()) {
-            return false;
-        }
-        return true;
-    }
-
-    private void setAirplaneModeOn(boolean enabling) {
-        // Change the system setting for airplane mode
-        Settings.Global.putInt(resolver, Settings.Global.AIRPLANE_MODE_ON, enabling ? 1 : 0);
-    }
-
-    private boolean isAirplaneModeOn() {
-        // Read the system setting for airplane mode
-        return Settings.Global.getInt(mContext.getContentResolver(),
-                                      Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt b/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt
deleted file mode 100644
index eb5048f..0000000
--- a/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts
-
-import android.Manifest.permission.CONNECTIVITY_INTERNAL
-import android.Manifest.permission.NETWORK_SETTINGS
-import android.Manifest.permission.READ_DEVICE_CONFIG
-import android.content.pm.PackageManager.FEATURE_TELEPHONY
-import android.content.pm.PackageManager.FEATURE_WIFI
-import android.net.ConnectivityManager
-import android.net.ConnectivityManager.NetworkCallback
-import android.net.Network
-import android.net.NetworkCapabilities
-import android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL
-import android.net.NetworkCapabilities.TRANSPORT_WIFI
-import android.net.NetworkRequest
-import android.net.Uri
-import android.net.cts.NetworkValidationTestUtil.clearValidationTestUrlsDeviceConfig
-import android.net.cts.NetworkValidationTestUtil.setHttpUrlDeviceConfig
-import android.net.cts.NetworkValidationTestUtil.setHttpsUrlDeviceConfig
-import android.net.cts.NetworkValidationTestUtil.setUrlExpirationDeviceConfig
-import android.net.cts.util.CtsNetUtils
-import android.net.util.NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTPS_URL
-import android.net.util.NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTP_URL
-import android.net.wifi.WifiManager
-import android.os.Build
-import android.platform.test.annotations.AppModeFull
-import android.provider.DeviceConfig
-import android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY
-import android.text.TextUtils
-import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
-import androidx.test.runner.AndroidJUnit4
-import com.android.testutils.TestHttpServer
-import com.android.testutils.TestHttpServer.Request
-import com.android.testutils.isDevSdkInRange
-import com.android.testutils.runAsShell
-import fi.iki.elonen.NanoHTTPD.Response.Status
-import junit.framework.AssertionFailedError
-import org.junit.After
-import org.junit.Assume.assumeTrue
-import org.junit.Before
-import org.junit.runner.RunWith
-import java.util.concurrent.CompletableFuture
-import java.util.concurrent.TimeUnit
-import java.util.concurrent.TimeoutException
-import kotlin.test.Test
-import kotlin.test.assertNotEquals
-import kotlin.test.assertNotNull
-import kotlin.test.assertTrue
-
-private const val TEST_HTTPS_URL_PATH = "/https_path"
-private const val TEST_HTTP_URL_PATH = "/http_path"
-private const val TEST_PORTAL_URL_PATH = "/portal_path"
-
-private const val LOCALHOST_HOSTNAME = "localhost"
-
-// Re-connecting to the AP, obtaining an IP address, revalidating can take a long time
-private const val WIFI_CONNECT_TIMEOUT_MS = 120_000L
-private const val TEST_TIMEOUT_MS = 10_000L
-
-private fun <T> CompletableFuture<T>.assertGet(timeoutMs: Long, message: String): T {
-    try {
-        return get(timeoutMs, TimeUnit.MILLISECONDS)
-    } catch (e: TimeoutException) {
-        throw AssertionFailedError(message)
-    }
-}
-
-@AppModeFull(reason = "WRITE_DEVICE_CONFIG permission can't be granted to instant apps")
-@RunWith(AndroidJUnit4::class)
-class CaptivePortalTest {
-    private val context: android.content.Context by lazy { getInstrumentation().context }
-    private val wm by lazy { context.getSystemService(WifiManager::class.java) }
-    private val cm by lazy { context.getSystemService(ConnectivityManager::class.java) }
-    private val pm by lazy { context.packageManager }
-    private val utils by lazy { CtsNetUtils(context) }
-
-    private val server = TestHttpServer("localhost")
-
-    @Before
-    fun setUp() {
-        runAsShell(READ_DEVICE_CONFIG) {
-            // Verify that the test URLs are not normally set on the device, but do not fail if the
-            // test URLs are set to what this test uses (URLs on localhost), in case the test was
-            // interrupted manually and rerun.
-            assertEmptyOrLocalhostUrl(TEST_CAPTIVE_PORTAL_HTTPS_URL)
-            assertEmptyOrLocalhostUrl(TEST_CAPTIVE_PORTAL_HTTP_URL)
-        }
-        clearValidationTestUrlsDeviceConfig()
-        server.start()
-    }
-
-    @After
-    fun tearDown() {
-        clearValidationTestUrlsDeviceConfig()
-        if (pm.hasSystemFeature(FEATURE_WIFI)) {
-            reconnectWifi()
-        }
-        server.stop()
-    }
-
-    private fun assertEmptyOrLocalhostUrl(urlKey: String) {
-        val url = DeviceConfig.getProperty(NAMESPACE_CONNECTIVITY, urlKey)
-        assertTrue(TextUtils.isEmpty(url) || LOCALHOST_HOSTNAME == Uri.parse(url).host,
-                "$urlKey must not be set in production scenarios (current value: $url)")
-    }
-
-    @Test
-    fun testCaptivePortalIsNotDefaultNetwork() {
-        assumeTrue(pm.hasSystemFeature(FEATURE_TELEPHONY))
-        assumeTrue(pm.hasSystemFeature(FEATURE_WIFI))
-        utils.ensureWifiConnected()
-        utils.connectToCell()
-
-        // Have network validation use a local server that serves a HTTPS error / HTTP redirect
-        server.addResponse(Request(TEST_PORTAL_URL_PATH), Status.OK,
-                content = "Test captive portal content")
-        server.addResponse(Request(TEST_HTTPS_URL_PATH), Status.INTERNAL_ERROR)
-        server.addResponse(Request(TEST_HTTP_URL_PATH), Status.REDIRECT,
-                locationHeader = makeUrl(TEST_PORTAL_URL_PATH))
-        setHttpsUrlDeviceConfig(makeUrl(TEST_HTTPS_URL_PATH))
-        setHttpUrlDeviceConfig(makeUrl(TEST_HTTP_URL_PATH))
-        // URL expiration needs to be in the next 10 minutes
-        setUrlExpirationDeviceConfig(System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(9))
-
-        // Wait for a captive portal to be detected on the network
-        val wifiNetworkFuture = CompletableFuture<Network>()
-        val wifiCb = object : NetworkCallback() {
-            override fun onCapabilitiesChanged(
-                network: Network,
-                nc: NetworkCapabilities
-            ) {
-                if (nc.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) {
-                    wifiNetworkFuture.complete(network)
-                }
-            }
-        }
-        cm.requestNetwork(NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(), wifiCb)
-
-        try {
-            reconnectWifi()
-            val network = wifiNetworkFuture.assertGet(WIFI_CONNECT_TIMEOUT_MS,
-                    "Captive portal not detected after ${WIFI_CONNECT_TIMEOUT_MS}ms")
-
-            val wifiDefaultMessage = "Wifi should not be the default network when a captive " +
-                    "portal was detected and another network (mobile data) can provide internet " +
-                    "access."
-            assertNotEquals(network, cm.activeNetwork, wifiDefaultMessage)
-
-            val startPortalAppPermission =
-                    if (isDevSdkInRange(0, Build.VERSION_CODES.Q)) CONNECTIVITY_INTERNAL
-                    else NETWORK_SETTINGS
-            runAsShell(startPortalAppPermission) { cm.startCaptivePortalApp(network) }
-
-            // Expect the portal content to be fetched at some point after detecting the portal.
-            // Some implementations may fetch the URL before startCaptivePortalApp is called.
-            assertNotNull(server.requestsRecord.poll(TEST_TIMEOUT_MS, pos = 0) {
-                it.path == TEST_PORTAL_URL_PATH
-            }, "The captive portal login page was still not fetched ${TEST_TIMEOUT_MS}ms " +
-                    "after startCaptivePortalApp.")
-
-            assertNotEquals(network, cm.activeNetwork, wifiDefaultMessage)
-        } finally {
-            cm.unregisterNetworkCallback(wifiCb)
-            server.stop()
-            // disconnectFromCell should be called after connectToCell
-            utils.disconnectFromCell()
-        }
-    }
-
-    /**
-     * Create a URL string that, when fetched, will hit the test server with the given URL [path].
-     */
-    private fun makeUrl(path: String) = "http://localhost:${server.listeningPort}" + path
-
-    private fun reconnectWifi() {
-        utils.ensureWifiDisconnected(null /* wifiNetworkToCheck */)
-        utils.ensureWifiConnected()
-    }
-}
\ No newline at end of file
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
deleted file mode 100644
index 54509cd..0000000
--- a/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-import static android.content.pm.PackageManager.FEATURE_TELEPHONY;
-import static android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback;
-import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
-import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_ATTEMPTED_BITMASK;
-import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_SUCCEEDED_BITMASK;
-import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_VALIDATION_RESULT;
-import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.NETWORK_VALIDATION_RESULT_VALID;
-import static android.net.ConnectivityDiagnosticsManager.DataStallReport;
-import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_DNS_EVENTS;
-import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_TCP_METRICS;
-import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_DNS_CONSECUTIVE_TIMEOUTS;
-import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS;
-import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_PACKET_FAIL_RATE;
-import static android.net.ConnectivityDiagnosticsManager.persistableBundleEquals;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.net.NetworkCapabilities.TRANSPORT_TEST;
-import static android.net.cts.util.CtsNetUtils.TestNetworkCallback;
-
-import static com.android.compatibility.common.util.SystemUtil.callWithShellPermissionIdentity;
-import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
-
-import android.annotation.NonNull;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.net.ConnectivityDiagnosticsManager;
-import android.net.ConnectivityManager;
-import android.net.LinkAddress;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.net.TestNetworkInterface;
-import android.net.TestNetworkManager;
-import android.os.Binder;
-import android.os.Build;
-import android.os.IBinder;
-import android.os.ParcelFileDescriptor;
-import android.os.PersistableBundle;
-import android.os.Process;
-import android.platform.test.annotations.AppModeFull;
-import android.telephony.CarrierConfigManager;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.util.Pair;
-
-import androidx.test.InstrumentationRegistry;
-
-import com.android.internal.telephony.uicc.IccUtils;
-import com.android.internal.util.ArrayUtils;
-import com.android.net.module.util.ArrayTrackRecord;
-import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
-import com.android.testutils.DevSdkIgnoreRunner;
-import com.android.testutils.SkipPresubmit;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.security.MessageDigest;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-
-@RunWith(DevSdkIgnoreRunner.class)
-@IgnoreUpTo(Build.VERSION_CODES.Q) // ConnectivityDiagnosticsManager did not exist in Q
-@AppModeFull(reason = "CHANGE_NETWORK_STATE, MANAGE_TEST_NETWORKS not grantable to instant apps")
-public class ConnectivityDiagnosticsManagerTest {
-    private static final int CALLBACK_TIMEOUT_MILLIS = 5000;
-    private static final int NO_CALLBACK_INVOKED_TIMEOUT = 500;
-    private static final long TIMESTAMP = 123456789L;
-    private static final int DNS_CONSECUTIVE_TIMEOUTS = 5;
-    private static final int COLLECTION_PERIOD_MILLIS = 5000;
-    private static final int FAIL_RATE_PERCENTAGE = 100;
-    private static final int UNKNOWN_DETECTION_METHOD = 4;
-    private static final int FILTERED_UNKNOWN_DETECTION_METHOD = 0;
-    private static final int CARRIER_CONFIG_CHANGED_BROADCAST_TIMEOUT = 5000;
-    private static final int DELAY_FOR_ADMIN_UIDS_MILLIS = 2000;
-
-    private static final Executor INLINE_EXECUTOR = x -> x.run();
-
-    private static final NetworkRequest TEST_NETWORK_REQUEST =
-            new NetworkRequest.Builder()
-                    .addTransportType(TRANSPORT_TEST)
-                    .removeCapability(NET_CAPABILITY_TRUSTED)
-                    .removeCapability(NET_CAPABILITY_NOT_VPN)
-                    .build();
-
-    private static final String SHA_256 = "SHA-256";
-
-    private static final NetworkRequest CELLULAR_NETWORK_REQUEST =
-            new NetworkRequest.Builder()
-                    .addTransportType(TRANSPORT_CELLULAR)
-                    .addCapability(NET_CAPABILITY_INTERNET)
-                    .build();
-
-    private static final IBinder BINDER = new Binder();
-
-    private Context mContext;
-    private ConnectivityManager mConnectivityManager;
-    private ConnectivityDiagnosticsManager mCdm;
-    private CarrierConfigManager mCarrierConfigManager;
-    private PackageManager mPackageManager;
-    private TelephonyManager mTelephonyManager;
-
-    // Callback used to keep TestNetworks up when there are no other outstanding NetworkRequests
-    // for it.
-    private TestNetworkCallback mTestNetworkCallback;
-    private Network mTestNetwork;
-    private ParcelFileDescriptor mTestNetworkFD;
-
-    private List<TestConnectivityDiagnosticsCallback> mRegisteredCallbacks;
-
-    @Before
-    public void setUp() throws Exception {
-        mContext = InstrumentationRegistry.getContext();
-        mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
-        mCdm = mContext.getSystemService(ConnectivityDiagnosticsManager.class);
-        mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
-        mPackageManager = mContext.getPackageManager();
-        mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
-
-        mTestNetworkCallback = new TestNetworkCallback();
-        mConnectivityManager.requestNetwork(TEST_NETWORK_REQUEST, mTestNetworkCallback);
-
-        mRegisteredCallbacks = new ArrayList<>();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mConnectivityManager.unregisterNetworkCallback(mTestNetworkCallback);
-        if (mTestNetwork != null) {
-            runWithShellPermissionIdentity(() -> {
-                final TestNetworkManager tnm = mContext.getSystemService(TestNetworkManager.class);
-                tnm.teardownTestNetwork(mTestNetwork);
-            });
-            mTestNetwork = null;
-        }
-
-        if (mTestNetworkFD != null) {
-            mTestNetworkFD.close();
-            mTestNetworkFD = null;
-        }
-
-        for (TestConnectivityDiagnosticsCallback cb : mRegisteredCallbacks) {
-            mCdm.unregisterConnectivityDiagnosticsCallback(cb);
-        }
-    }
-
-    @Test
-    public void testRegisterConnectivityDiagnosticsCallback() throws Exception {
-        mTestNetworkFD = setUpTestNetwork().getFileDescriptor();
-        mTestNetwork = mTestNetworkCallback.waitForAvailable();
-
-        final TestConnectivityDiagnosticsCallback cb =
-                createAndRegisterConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST);
-
-        final String interfaceName =
-                mConnectivityManager.getLinkProperties(mTestNetwork).getInterfaceName();
-
-        cb.expectOnConnectivityReportAvailable(mTestNetwork, interfaceName);
-        cb.assertNoCallback();
-    }
-
-    @SkipPresubmit(reason = "Flaky: b/159718782; add to presubmit after fixing")
-    @Test
-    public void testRegisterCallbackWithCarrierPrivileges() throws Exception {
-        assumeTrue(mPackageManager.hasSystemFeature(FEATURE_TELEPHONY));
-
-        final int subId = SubscriptionManager.getDefaultSubscriptionId();
-        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            fail("Need an active subscription. Please ensure that the device has working mobile"
-                    + " data.");
-        }
-
-        final CarrierConfigReceiver carrierConfigReceiver = new CarrierConfigReceiver(subId);
-        mContext.registerReceiver(
-                carrierConfigReceiver,
-                new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
-
-        final TestNetworkCallback testNetworkCallback = new TestNetworkCallback();
-
-        try {
-            doBroadcastCarrierConfigsAndVerifyOnConnectivityReportAvailable(
-                    subId, carrierConfigReceiver, testNetworkCallback);
-        } finally {
-            runWithShellPermissionIdentity(
-                    () -> mCarrierConfigManager.overrideConfig(subId, null),
-                    android.Manifest.permission.MODIFY_PHONE_STATE);
-            mConnectivityManager.unregisterNetworkCallback(testNetworkCallback);
-            mContext.unregisterReceiver(carrierConfigReceiver);
-        }
-    }
-
-    private String getCertHashForThisPackage() throws Exception {
-        final PackageInfo pkgInfo =
-                mPackageManager.getPackageInfo(
-                        mContext.getOpPackageName(), PackageManager.GET_SIGNATURES);
-        final MessageDigest md = MessageDigest.getInstance(SHA_256);
-        final byte[] certHash = md.digest(pkgInfo.signatures[0].toByteArray());
-        return IccUtils.bytesToHexString(certHash);
-    }
-
-    private void doBroadcastCarrierConfigsAndVerifyOnConnectivityReportAvailable(
-            int subId,
-            @NonNull CarrierConfigReceiver carrierConfigReceiver,
-            @NonNull TestNetworkCallback testNetworkCallback)
-            throws Exception {
-        final PersistableBundle carrierConfigs = new PersistableBundle();
-        carrierConfigs.putStringArray(
-                CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY,
-                new String[] {getCertHashForThisPackage()});
-
-        runWithShellPermissionIdentity(
-                () -> {
-                    mCarrierConfigManager.overrideConfig(subId, carrierConfigs);
-                    mCarrierConfigManager.notifyConfigChangedForSubId(subId);
-                },
-                android.Manifest.permission.MODIFY_PHONE_STATE);
-
-        // TODO(b/157779832): This should use android.permission.CHANGE_NETWORK_STATE. However, the
-        // shell does not have CHANGE_NETWORK_STATE, so use CONNECTIVITY_INTERNAL until the shell
-        // permissions are updated.
-        runWithShellPermissionIdentity(
-                () -> mConnectivityManager.requestNetwork(
-                        CELLULAR_NETWORK_REQUEST, testNetworkCallback),
-                android.Manifest.permission.CONNECTIVITY_INTERNAL);
-
-        final Network network = testNetworkCallback.waitForAvailable();
-        assertNotNull(network);
-
-        assertTrue("Didn't receive broadcast for ACTION_CARRIER_CONFIG_CHANGED for subId=" + subId,
-                carrierConfigReceiver.waitForCarrierConfigChanged());
-        assertTrue("Don't have Carrier Privileges after adding cert for this package",
-                mTelephonyManager.createForSubscriptionId(subId).hasCarrierPrivileges());
-
-        // Wait for CarrierPrivilegesTracker to receive the ACTION_CARRIER_CONFIG_CHANGED
-        // broadcast. CPT then needs to update the corresponding DataConnection, which then
-        // updates ConnectivityService. Unfortunately, this update to the NetworkCapabilities in
-        // CS does not trigger NetworkCallback#onCapabilitiesChanged as changing the
-        // administratorUids is not a publicly visible change. In lieu of a better signal to
-        // detministically wait for, use Thread#sleep here.
-        // TODO(b/157949581): replace this Thread#sleep with a deterministic signal
-        Thread.sleep(DELAY_FOR_ADMIN_UIDS_MILLIS);
-
-        final TestConnectivityDiagnosticsCallback connDiagsCallback =
-                createAndRegisterConnectivityDiagnosticsCallback(CELLULAR_NETWORK_REQUEST);
-
-        final String interfaceName =
-                mConnectivityManager.getLinkProperties(network).getInterfaceName();
-        connDiagsCallback.expectOnConnectivityReportAvailable(
-                network, interfaceName, TRANSPORT_CELLULAR);
-        connDiagsCallback.assertNoCallback();
-    }
-
-    @Test
-    public void testRegisterDuplicateConnectivityDiagnosticsCallback() {
-        final TestConnectivityDiagnosticsCallback cb =
-                createAndRegisterConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST);
-
-        try {
-            mCdm.registerConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST, INLINE_EXECUTOR, cb);
-            fail("Registering the same callback twice should throw an IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    @Test
-    public void testUnregisterConnectivityDiagnosticsCallback() {
-        final TestConnectivityDiagnosticsCallback cb = new TestConnectivityDiagnosticsCallback();
-        mCdm.registerConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST, INLINE_EXECUTOR, cb);
-        mCdm.unregisterConnectivityDiagnosticsCallback(cb);
-    }
-
-    @Test
-    public void testUnregisterUnknownConnectivityDiagnosticsCallback() {
-        // Expected to silently ignore the unregister() call
-        mCdm.unregisterConnectivityDiagnosticsCallback(new TestConnectivityDiagnosticsCallback());
-    }
-
-    @Test
-    public void testOnConnectivityReportAvailable() throws Exception {
-        final TestConnectivityDiagnosticsCallback cb =
-                createAndRegisterConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST);
-
-        mTestNetworkFD = setUpTestNetwork().getFileDescriptor();
-        mTestNetwork = mTestNetworkCallback.waitForAvailable();
-
-        final String interfaceName =
-                mConnectivityManager.getLinkProperties(mTestNetwork).getInterfaceName();
-
-        cb.expectOnConnectivityReportAvailable(mTestNetwork, interfaceName);
-        cb.assertNoCallback();
-    }
-
-    @Test
-    public void testOnDataStallSuspected_DnsEvents() throws Exception {
-        final PersistableBundle extras = new PersistableBundle();
-        extras.putInt(KEY_DNS_CONSECUTIVE_TIMEOUTS, DNS_CONSECUTIVE_TIMEOUTS);
-
-        verifyOnDataStallSuspected(DETECTION_METHOD_DNS_EVENTS, TIMESTAMP, extras);
-    }
-
-    @Test
-    public void testOnDataStallSuspected_TcpMetrics() throws Exception {
-        final PersistableBundle extras = new PersistableBundle();
-        extras.putInt(KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS, COLLECTION_PERIOD_MILLIS);
-        extras.putInt(KEY_TCP_PACKET_FAIL_RATE, FAIL_RATE_PERCENTAGE);
-
-        verifyOnDataStallSuspected(DETECTION_METHOD_TCP_METRICS, TIMESTAMP, extras);
-    }
-
-    @Test
-    public void testOnDataStallSuspected_UnknownDetectionMethod() throws Exception {
-        verifyOnDataStallSuspected(
-                UNKNOWN_DETECTION_METHOD,
-                FILTERED_UNKNOWN_DETECTION_METHOD,
-                TIMESTAMP,
-                PersistableBundle.EMPTY);
-    }
-
-    private void verifyOnDataStallSuspected(
-            int detectionMethod, long timestampMillis, @NonNull PersistableBundle extras)
-            throws Exception {
-        // Input detection method is expected to match received detection method
-        verifyOnDataStallSuspected(detectionMethod, detectionMethod, timestampMillis, extras);
-    }
-
-    private void verifyOnDataStallSuspected(
-            int inputDetectionMethod,
-            int expectedDetectionMethod,
-            long timestampMillis,
-            @NonNull PersistableBundle extras)
-            throws Exception {
-        mTestNetworkFD = setUpTestNetwork().getFileDescriptor();
-        mTestNetwork = mTestNetworkCallback.waitForAvailable();
-
-        final TestConnectivityDiagnosticsCallback cb =
-                createAndRegisterConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST);
-
-        final String interfaceName =
-                mConnectivityManager.getLinkProperties(mTestNetwork).getInterfaceName();
-
-        cb.expectOnConnectivityReportAvailable(mTestNetwork, interfaceName);
-
-        runWithShellPermissionIdentity(
-                () -> mConnectivityManager.simulateDataStall(
-                        inputDetectionMethod, timestampMillis, mTestNetwork, extras),
-                android.Manifest.permission.MANAGE_TEST_NETWORKS);
-
-        cb.expectOnDataStallSuspected(
-                mTestNetwork, interfaceName, expectedDetectionMethod, timestampMillis, extras);
-        cb.assertNoCallback();
-    }
-
-    @Test
-    public void testOnNetworkConnectivityReportedTrue() throws Exception {
-        verifyOnNetworkConnectivityReported(true /* hasConnectivity */);
-    }
-
-    @Test
-    public void testOnNetworkConnectivityReportedFalse() throws Exception {
-        verifyOnNetworkConnectivityReported(false /* hasConnectivity */);
-    }
-
-    private void verifyOnNetworkConnectivityReported(boolean hasConnectivity) throws Exception {
-        mTestNetworkFD = setUpTestNetwork().getFileDescriptor();
-        mTestNetwork = mTestNetworkCallback.waitForAvailable();
-
-        final TestConnectivityDiagnosticsCallback cb =
-                createAndRegisterConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST);
-
-        // onConnectivityReportAvailable always invoked when the test network is established
-        final String interfaceName =
-                mConnectivityManager.getLinkProperties(mTestNetwork).getInterfaceName();
-        cb.expectOnConnectivityReportAvailable(mTestNetwork, interfaceName);
-        cb.assertNoCallback();
-
-        mConnectivityManager.reportNetworkConnectivity(mTestNetwork, hasConnectivity);
-
-        cb.expectOnNetworkConnectivityReported(mTestNetwork, hasConnectivity);
-
-        // if hasConnectivity does not match the network's known connectivity, it will be
-        // revalidated which will trigger another onConnectivityReportAvailable callback.
-        if (!hasConnectivity) {
-            cb.expectOnConnectivityReportAvailable(mTestNetwork, interfaceName);
-        }
-
-        cb.assertNoCallback();
-    }
-
-    private TestConnectivityDiagnosticsCallback createAndRegisterConnectivityDiagnosticsCallback(
-            NetworkRequest request) {
-        final TestConnectivityDiagnosticsCallback cb = new TestConnectivityDiagnosticsCallback();
-        mCdm.registerConnectivityDiagnosticsCallback(request, INLINE_EXECUTOR, cb);
-        mRegisteredCallbacks.add(cb);
-        return cb;
-    }
-
-    /**
-     * Registers a test NetworkAgent with ConnectivityService with limited capabilities, which leads
-     * to the Network being validated.
-     */
-    @NonNull
-    private TestNetworkInterface setUpTestNetwork() throws Exception {
-        final int[] administratorUids = new int[] {Process.myUid()};
-        return callWithShellPermissionIdentity(
-                () -> {
-                    final TestNetworkManager tnm =
-                            mContext.getSystemService(TestNetworkManager.class);
-                    final TestNetworkInterface tni = tnm.createTunInterface(new LinkAddress[0]);
-                    tnm.setupTestNetwork(tni.getInterfaceName(), administratorUids, BINDER);
-                    return tni;
-                });
-    }
-
-    private static class TestConnectivityDiagnosticsCallback
-            extends ConnectivityDiagnosticsCallback {
-        private final ArrayTrackRecord<Object>.ReadHead mHistory =
-                new ArrayTrackRecord<Object>().newReadHead();
-
-        @Override
-        public void onConnectivityReportAvailable(ConnectivityReport report) {
-            mHistory.add(report);
-        }
-
-        @Override
-        public void onDataStallSuspected(DataStallReport report) {
-            mHistory.add(report);
-        }
-
-        @Override
-        public void onNetworkConnectivityReported(Network network, boolean hasConnectivity) {
-            mHistory.add(new Pair<Network, Boolean>(network, hasConnectivity));
-        }
-
-        public void expectOnConnectivityReportAvailable(
-                @NonNull Network network, @NonNull String interfaceName) {
-            expectOnConnectivityReportAvailable(network, interfaceName, TRANSPORT_TEST);
-        }
-
-        public void expectOnConnectivityReportAvailable(
-                @NonNull Network network, @NonNull String interfaceName, int transportType) {
-            final ConnectivityReport result =
-                    (ConnectivityReport) mHistory.poll(CALLBACK_TIMEOUT_MILLIS, x -> true);
-            assertEquals(network, result.getNetwork());
-
-            final NetworkCapabilities nc = result.getNetworkCapabilities();
-            assertNotNull(nc);
-            assertTrue(nc.hasTransport(transportType));
-            assertNotNull(result.getLinkProperties());
-            assertEquals(interfaceName, result.getLinkProperties().getInterfaceName());
-
-            final PersistableBundle extras = result.getAdditionalInfo();
-            assertTrue(extras.containsKey(KEY_NETWORK_VALIDATION_RESULT));
-            final int validationResult = extras.getInt(KEY_NETWORK_VALIDATION_RESULT);
-            assertEquals("Network validation result is not 'valid'",
-                    NETWORK_VALIDATION_RESULT_VALID, validationResult);
-
-            assertTrue(extras.containsKey(KEY_NETWORK_PROBES_SUCCEEDED_BITMASK));
-            final int probesSucceeded = extras.getInt(KEY_NETWORK_VALIDATION_RESULT);
-            assertTrue("PROBES_SUCCEEDED mask not in expected range", probesSucceeded >= 0);
-
-            assertTrue(extras.containsKey(KEY_NETWORK_PROBES_ATTEMPTED_BITMASK));
-            final int probesAttempted = extras.getInt(KEY_NETWORK_PROBES_ATTEMPTED_BITMASK);
-            assertTrue("PROBES_ATTEMPTED mask not in expected range", probesAttempted >= 0);
-        }
-
-        public void expectOnDataStallSuspected(
-                @NonNull Network network,
-                @NonNull String interfaceName,
-                int detectionMethod,
-                long timestampMillis,
-                @NonNull PersistableBundle extras) {
-            final DataStallReport result =
-                    (DataStallReport) mHistory.poll(CALLBACK_TIMEOUT_MILLIS, x -> true);
-            assertEquals(network, result.getNetwork());
-            assertEquals(detectionMethod, result.getDetectionMethod());
-            assertEquals(timestampMillis, result.getReportTimestamp());
-
-            final NetworkCapabilities nc = result.getNetworkCapabilities();
-            assertNotNull(nc);
-            assertTrue(nc.hasTransport(TRANSPORT_TEST));
-            assertNotNull(result.getLinkProperties());
-            assertEquals(interfaceName, result.getLinkProperties().getInterfaceName());
-
-            assertTrue(persistableBundleEquals(extras, result.getStallDetails()));
-        }
-
-        public void expectOnNetworkConnectivityReported(
-                @NonNull Network network, boolean hasConnectivity) {
-            final Pair<Network, Boolean> result =
-                    (Pair<Network, Boolean>) mHistory.poll(CALLBACK_TIMEOUT_MILLIS, x -> true);
-            assertEquals(network, result.first /* network */);
-            assertEquals(hasConnectivity, result.second /* hasConnectivity */);
-        }
-
-        public void assertNoCallback() {
-            // If no more callbacks exist, there should be nothing left in the ReadHead
-            assertNull("Unexpected event in history",
-                    mHistory.poll(NO_CALLBACK_INVOKED_TIMEOUT, x -> true));
-        }
-    }
-
-    private class CarrierConfigReceiver extends BroadcastReceiver {
-        private final CountDownLatch mLatch = new CountDownLatch(1);
-        private final int mSubId;
-
-        CarrierConfigReceiver(int subId) {
-            mSubId = subId;
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (!CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(intent.getAction())) {
-                return;
-            }
-
-            final int subId =
-                    intent.getIntExtra(
-                            CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX,
-                            SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-            if (mSubId != subId) return;
-
-            final PersistableBundle carrierConfigs = mCarrierConfigManager.getConfigForSubId(subId);
-            if (!CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfigs)) return;
-
-            final String[] certs =
-                    carrierConfigs.getStringArray(
-                            CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY);
-            try {
-                if (ArrayUtils.contains(certs, getCertHashForThisPackage())) {
-                    mLatch.countDown();
-                }
-            } catch (Exception e) {
-            }
-        }
-
-        boolean waitForCarrierConfigChanged() throws Exception {
-            return mLatch.await(CARRIER_CONFIG_CHANGED_BROADCAST_TIMEOUT, TimeUnit.MILLISECONDS);
-        }
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
deleted file mode 100644
index b7cc95d..0000000
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ /dev/null
@@ -1,1384 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
-import static android.content.pm.PackageManager.FEATURE_ETHERNET;
-import static android.content.pm.PackageManager.FEATURE_TELEPHONY;
-import static android.content.pm.PackageManager.FEATURE_USB_HOST;
-import static android.content.pm.PackageManager.FEATURE_WIFI;
-import static android.content.pm.PackageManager.GET_PERMISSIONS;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-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.NET_CAPABILITY_NOT_RESTRICTED;
-import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
-import static android.net.cts.util.CtsNetUtils.ConnectivityActionReceiver;
-import static android.net.cts.util.CtsNetUtils.HTTP_PORT;
-import static android.net.cts.util.CtsNetUtils.NETWORK_CALLBACK_ACTION;
-import static android.net.cts.util.CtsNetUtils.TEST_HOST;
-import static android.net.cts.util.CtsNetUtils.TestNetworkCallback;
-import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
-import static android.provider.Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE;
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.AF_INET6;
-import static android.system.OsConstants.AF_UNSPEC;
-
-import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
-import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
-
-import android.annotation.NonNull;
-import android.app.Instrumentation;
-import android.app.PendingIntent;
-import android.app.UiAutomation;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.net.ConnectivityManager;
-import android.net.ConnectivityManager.NetworkCallback;
-import android.net.IpSecManager;
-import android.net.IpSecManager.UdpEncapsulationSocket;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkConfig;
-import android.net.NetworkInfo;
-import android.net.NetworkInfo.DetailedState;
-import android.net.NetworkInfo.State;
-import android.net.NetworkRequest;
-import android.net.NetworkUtils;
-import android.net.SocketKeepalive;
-import android.net.cts.util.CtsNetUtils;
-import android.net.util.KeepaliveUtils;
-import android.net.wifi.WifiManager;
-import android.os.Binder;
-import android.os.Build;
-import android.os.Looper;
-import android.os.MessageQueue;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.os.VintfRuntimeInfo;
-import android.platform.test.annotations.AppModeFull;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Pair;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.util.ArrayUtils;
-import com.android.testutils.SkipPresubmit;
-
-import libcore.io.Streams;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.net.HttpURLConnection;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.concurrent.CountDownLatch;
-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;
-
-@RunWith(AndroidJUnit4.class)
-public class ConnectivityManagerTest {
-
-    private static final String TAG = ConnectivityManagerTest.class.getSimpleName();
-
-    public static final int TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE;
-    public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI;
-
-    private static final int HOST_ADDRESS = 0x7f000001;// represent ip 127.0.0.1
-    private static final int KEEPALIVE_CALLBACK_TIMEOUT_MS = 2000;
-    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;
-
-    // Changing meteredness on wifi involves reconnecting, which can take several seconds (involves
-    // re-associating, DHCP...)
-    private static final int NETWORK_CHANGE_METEREDNESS_TIMEOUT = 30_000;
-    private static final int NUM_TRIES_MULTIPATH_PREF_CHECK = 20;
-    private static final long INTERVAL_MULTIPATH_PREF_CHECK_MS = 500;
-    // 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;
-    private WifiManager mWifiManager;
-    private PackageManager mPackageManager;
-    private final HashMap<Integer, NetworkConfig> mNetworks =
-            new HashMap<Integer, NetworkConfig>();
-    boolean mWifiWasDisabled;
-    private UiAutomation mUiAutomation;
-    private CtsNetUtils mCtsNetUtils;
-
-    @Before
-    public void setUp() throws Exception {
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
-        mContext = mInstrumentation.getContext();
-        mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
-        mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
-        mPackageManager = mContext.getPackageManager();
-        mCtsNetUtils = new CtsNetUtils(mContext);
-        mWifiWasDisabled = false;
-
-        // Get com.android.internal.R.array.networkAttributes
-        int resId = mContext.getResources().getIdentifier("networkAttributes", "array", "android");
-        String[] naStrings = mContext.getResources().getStringArray(resId);
-        //TODO: What is the "correct" way to determine if this is a wifi only device?
-        boolean wifiOnly = SystemProperties.getBoolean("ro.radio.noril", false);
-        for (String naString : naStrings) {
-            try {
-                NetworkConfig n = new NetworkConfig(naString);
-                if (wifiOnly && ConnectivityManager.isNetworkTypeMobile(n.type)) {
-                    continue;
-                }
-                mNetworks.put(n.type, n);
-            } catch (Exception e) {}
-        }
-        mUiAutomation = mInstrumentation.getUiAutomation();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        // Return WiFi to its original disabled state after tests that explicitly connect.
-        if (mWifiWasDisabled) {
-            mCtsNetUtils.disconnectFromWifi(null);
-        }
-        if (mCtsNetUtils.cellConnectAttempted()) {
-            mCtsNetUtils.disconnectFromCell();
-        }
-
-        // All tests in this class require a working Internet connection as they start. Make
-        // sure there is still one as they end that's ready to use for the next test to use.
-        final TestNetworkCallback callback = new TestNetworkCallback();
-        mCm.registerDefaultNetworkCallback(callback);
-        try {
-            assertNotNull("Couldn't restore Internet connectivity", callback.waitForAvailable());
-        } finally {
-            mCm.unregisterNetworkCallback(callback);
-        }
-    }
-
-    /**
-     * Make sure WiFi is connected to an access point if it is not already. If
-     * WiFi is enabled as a result of this function, it will be disabled
-     * automatically in tearDown().
-     */
-    private Network ensureWifiConnected() {
-        mWifiWasDisabled = !mWifiManager.isWifiEnabled();
-        // Even if wifi is enabled, the network may not be connected or ready yet
-        return mCtsNetUtils.connectToWifi();
-    }
-
-    @Test
-    public void testIsNetworkTypeValid() {
-        assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE));
-        assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_WIFI));
-        assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_MMS));
-        assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_SUPL));
-        assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_DUN));
-        assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_HIPRI));
-        assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_WIMAX));
-        assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_BLUETOOTH));
-        assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_DUMMY));
-        assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_ETHERNET));
-        assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_FOTA));
-        assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_IMS));
-        assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_CBS));
-        assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_WIFI_P2P));
-        assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_IA));
-        assertFalse(mCm.isNetworkTypeValid(-1));
-        assertTrue(mCm.isNetworkTypeValid(0));
-        assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.MAX_NETWORK_TYPE));
-        assertFalse(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.MAX_NETWORK_TYPE+1));
-
-        NetworkInfo[] ni = mCm.getAllNetworkInfo();
-
-        for (NetworkInfo n: ni) {
-            assertTrue(ConnectivityManager.isNetworkTypeValid(n.getType()));
-        }
-
-    }
-
-    @Test
-    public void testSetNetworkPreference() {
-        // getNetworkPreference() and setNetworkPreference() are both deprecated so they do
-        // not preform any action.  Verify they are at least still callable.
-        mCm.setNetworkPreference(mCm.getNetworkPreference());
-    }
-
-    @Test
-    public void testGetActiveNetworkInfo() {
-        NetworkInfo ni = mCm.getActiveNetworkInfo();
-
-        assertNotNull("You must have an active network connection to complete CTS", ni);
-        assertTrue(ConnectivityManager.isNetworkTypeValid(ni.getType()));
-        assertTrue(ni.getState() == State.CONNECTED);
-    }
-
-    @Test
-    public void testGetActiveNetwork() {
-        Network network = mCm.getActiveNetwork();
-        assertNotNull("You must have an active network connection to complete CTS", network);
-
-        NetworkInfo ni = mCm.getNetworkInfo(network);
-        assertNotNull("Network returned from getActiveNetwork was invalid", ni);
-
-        // Similar to testGetActiveNetworkInfo above.
-        assertTrue(ConnectivityManager.isNetworkTypeValid(ni.getType()));
-        assertTrue(ni.getState() == State.CONNECTED);
-    }
-
-    @Test
-    public void testGetNetworkInfo() {
-        for (int type = -1; type <= ConnectivityManager.MAX_NETWORK_TYPE+1; type++) {
-            if (shouldBeSupported(type)) {
-                NetworkInfo ni = mCm.getNetworkInfo(type);
-                assertTrue("Info shouldn't be null for " + type, ni != null);
-                State state = ni.getState();
-                assertTrue("Bad state for " + type, State.UNKNOWN.ordinal() >= state.ordinal()
-                           && state.ordinal() >= State.CONNECTING.ordinal());
-                DetailedState ds = ni.getDetailedState();
-                assertTrue("Bad detailed state for " + type,
-                           DetailedState.FAILED.ordinal() >= ds.ordinal()
-                           && ds.ordinal() >= DetailedState.IDLE.ordinal());
-            } else {
-                assertNull("Info should be null for " + type, mCm.getNetworkInfo(type));
-            }
-        }
-    }
-
-    @Test
-    public void testGetAllNetworkInfo() {
-        NetworkInfo[] ni = mCm.getAllNetworkInfo();
-        assertTrue(ni.length >= MIN_NUM_NETWORK_TYPES);
-        for (int type = 0; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) {
-            int desiredFoundCount = (shouldBeSupported(type) ? 1 : 0);
-            int foundCount = 0;
-            for (NetworkInfo i : ni) {
-                if (i.getType() == type) foundCount++;
-            }
-            if (foundCount != desiredFoundCount) {
-                Log.e(TAG, "failure in testGetAllNetworkInfo.  Dump of returned NetworkInfos:");
-                for (NetworkInfo networkInfo : ni) Log.e(TAG, "  " + networkInfo);
-            }
-            assertTrue("Unexpected foundCount of " + foundCount + " for type " + type,
-                    foundCount == desiredFoundCount);
-        }
-    }
-
-    /**
-     * Tests that connections can be opened on WiFi and cellphone networks,
-     * and that they are made from different IP addresses.
-     */
-    @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
-    @Test
-    @SkipPresubmit(reason = "Virtual devices use a single internet connection for all networks")
-    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 = mCtsNetUtils.connectToWifi();
-        Network cellNetwork = mCtsNetUtils.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));
-    }
-
-    /**
-     * 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);
-            fail("startUsingNetworkFeature is no longer supported in the current API version");
-        } catch (UnsupportedOperationException expected) {}
-    }
-
-    private void assertStopUsingNetworkFeatureUnsupported(int networkType, String feature) {
-        try {
-            mCm.startUsingNetworkFeature(networkType, feature);
-            fail("stopUsingNetworkFeature is no longer supported in the current API version");
-        } catch (UnsupportedOperationException expected) {}
-    }
-
-    private void assertRequestRouteToHostUnsupported(int networkType, int hostAddress) {
-        try {
-            mCm.requestRouteToHost(networkType, hostAddress);
-            fail("requestRouteToHost is no longer supported in the current API version");
-        } catch (UnsupportedOperationException expected) {}
-    }
-
-    @Test
-    public void testStartUsingNetworkFeature() {
-
-        final String invalidateFeature = "invalidateFeature";
-        final String mmsFeature = "enableMMS";
-
-        assertStartUsingNetworkFeatureUnsupported(TYPE_MOBILE, invalidateFeature);
-        assertStopUsingNetworkFeatureUnsupported(TYPE_MOBILE, invalidateFeature);
-        assertStartUsingNetworkFeatureUnsupported(TYPE_WIFI, mmsFeature);
-    }
-
-    private boolean shouldEthernetBeSupported() {
-        // Instant mode apps aren't allowed to query the Ethernet service due to selinux policies.
-        // When in instant mode, don't fail if the Ethernet service is available. Instead, rely on
-        // the fact that Ethernet should be supported if the device has a hardware Ethernet port, or
-        // if the device can be a USB host and thus can use USB Ethernet adapters.
-        //
-        // Note that this test this will still fail in instant mode if a device supports Ethernet
-        // via other hardware means. We are not currently aware of any such device.
-        return (mContext.getSystemService(Context.ETHERNET_SERVICE) != null) ||
-            mPackageManager.hasSystemFeature(FEATURE_ETHERNET) ||
-            mPackageManager.hasSystemFeature(FEATURE_USB_HOST);
-    }
-
-    private boolean shouldBeSupported(int networkType) {
-        return mNetworks.containsKey(networkType) ||
-               (networkType == ConnectivityManager.TYPE_VPN) ||
-               (networkType == ConnectivityManager.TYPE_ETHERNET && shouldEthernetBeSupported());
-    }
-
-    @Test
-    public void testIsNetworkSupported() {
-        for (int type = -1; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) {
-            boolean supported = mCm.isNetworkSupported(type);
-            if (shouldBeSupported(type)) {
-                assertTrue("Network type " + type + " should be supported", supported);
-            } else {
-                assertFalse("Network type " + type + " should not be supported", supported);
-            }
-        }
-    }
-
-    @Test
-    public void testRequestRouteToHost() {
-        for (int type = -1 ; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) {
-            assertRequestRouteToHostUnsupported(type, HOST_ADDRESS);
-        }
-    }
-
-    @Test
-    public void testTest() {
-        mCm.getBackgroundDataSetting();
-    }
-
-    private NetworkRequest makeWifiNetworkRequest() {
-        return new NetworkRequest.Builder()
-                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
-                .build();
-    }
-
-    /**
-     * Exercises both registerNetworkCallback and unregisterNetworkCallback. This checks to
-     * see if we get a callback for the TRANSPORT_WIFI transport type being available.
-     *
-     * <p>In order to test that a NetworkCallback occurs, we need some change in the network
-     * state (either a transport or capability is now available). The most straightforward is
-     * WiFi. We could add a version that uses the telephony data connection but it's not clear
-     * that it would increase test coverage by much (how many devices have 3G radio but not Wifi?).
-     */
-    @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
-    @Test
-    public void testRegisterNetworkCallback() {
-        if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
-            Log.i(TAG, "testRegisterNetworkCallback cannot execute unless device supports WiFi");
-            return;
-        }
-
-        // We will register for a WIFI network being available or lost.
-        final TestNetworkCallback callback = new TestNetworkCallback();
-        mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback);
-
-        final TestNetworkCallback defaultTrackingCallback = new TestNetworkCallback();
-        mCm.registerDefaultNetworkCallback(defaultTrackingCallback);
-
-        Network wifiNetwork = null;
-
-        try {
-            ensureWifiConnected();
-
-            // Now we should expect to get a network callback about availability of the wifi
-            // network even if it was already connected as a state-based action when the callback
-            // is registered.
-            wifiNetwork = callback.waitForAvailable();
-            assertNotNull("Did not receive NetworkCallback.onAvailable for TRANSPORT_WIFI",
-                    wifiNetwork);
-
-            assertNotNull("Did not receive NetworkCallback.onAvailable for any default network",
-                    defaultTrackingCallback.waitForAvailable());
-        } catch (InterruptedException e) {
-            fail("Broadcast receiver or NetworkCallback wait was interrupted.");
-        } finally {
-            mCm.unregisterNetworkCallback(callback);
-            mCm.unregisterNetworkCallback(defaultTrackingCallback);
-        }
-    }
-
-    /**
-     * Tests both registerNetworkCallback and unregisterNetworkCallback similarly to
-     * {@link #testRegisterNetworkCallback} except that a {@code PendingIntent} is used instead
-     * of a {@code NetworkCallback}.
-     */
-    @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
-    @Test
-    public void testRegisterNetworkCallback_withPendingIntent() {
-        if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
-            Log.i(TAG, "testRegisterNetworkCallback cannot execute unless device supports WiFi");
-            return;
-        }
-
-        // Create a ConnectivityActionReceiver that has an IntentFilter for our locally defined
-        // action, NETWORK_CALLBACK_ACTION.
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(NETWORK_CALLBACK_ACTION);
-
-        ConnectivityActionReceiver receiver = new ConnectivityActionReceiver(
-                mCm, ConnectivityManager.TYPE_WIFI, NetworkInfo.State.CONNECTED);
-        mContext.registerReceiver(receiver, filter);
-
-        // Create a broadcast PendingIntent for NETWORK_CALLBACK_ACTION.
-        Intent intent = new Intent(NETWORK_CALLBACK_ACTION);
-        PendingIntent pendingIntent = PendingIntent.getBroadcast(
-                mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
-
-        // We will register for a WIFI network being available or lost.
-        mCm.registerNetworkCallback(makeWifiNetworkRequest(), pendingIntent);
-
-        try {
-            ensureWifiConnected();
-
-            // Now we expect to get the Intent delivered notifying of the availability of the wifi
-            // network even if it was already connected as a state-based action when the callback
-            // is registered.
-            assertTrue("Did not receive expected Intent " + intent + " for TRANSPORT_WIFI",
-                    receiver.waitForState());
-        } catch (InterruptedException e) {
-            fail("Broadcast receiver or NetworkCallback wait was interrupted.");
-        } finally {
-            mCm.unregisterNetworkCallback(pendingIntent);
-            pendingIntent.cancel();
-            mContext.unregisterReceiver(receiver);
-        }
-    }
-
-    /**
-     * Exercises the requestNetwork with NetworkCallback API. This checks to
-     * see if we get a callback for an INTERNET request.
-     */
-    @AppModeFull(reason = "CHANGE_NETWORK_STATE permission can't be granted to instant apps")
-    @Test
-    public void testRequestNetworkCallback() {
-        final TestNetworkCallback callback = new TestNetworkCallback();
-        mCm.requestNetwork(new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build(), callback);
-
-        try {
-            // Wait to get callback for availability of internet
-            Network internetNetwork = callback.waitForAvailable();
-            assertNotNull("Did not receive NetworkCallback#onAvailable for INTERNET",
-                    internetNetwork);
-        } catch (InterruptedException e) {
-            fail("NetworkCallback wait was interrupted.");
-        } finally {
-            mCm.unregisterNetworkCallback(callback);
-        }
-    }
-
-    /**
-     * Exercises the requestNetwork with NetworkCallback API with timeout - expected to
-     * fail. Use WIFI and switch Wi-Fi off.
-     */
-    @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
-    @Test
-    public void testRequestNetworkCallback_onUnavailable() {
-        final boolean previousWifiEnabledState = mWifiManager.isWifiEnabled();
-        if (previousWifiEnabledState) {
-            mCtsNetUtils.ensureWifiDisconnected(null);
-        }
-
-        final TestNetworkCallback callback = new TestNetworkCallback();
-        mCm.requestNetwork(new NetworkRequest.Builder()
-                .addTransportType(TRANSPORT_WIFI)
-                .build(), callback, 100);
-
-        try {
-            // Wait to get callback for unavailability of requested network
-            assertTrue("Did not receive NetworkCallback#onUnavailable",
-                    callback.waitForUnavailable());
-        } catch (InterruptedException e) {
-            fail("NetworkCallback wait was interrupted.");
-        } finally {
-            mCm.unregisterNetworkCallback(callback);
-            if (previousWifiEnabledState) {
-                mCtsNetUtils.connectToWifi();
-            }
-        }
-    }
-
-    private InetAddress getFirstV4Address(Network network) {
-        LinkProperties linkProperties = mCm.getLinkProperties(network);
-        for (InetAddress address : linkProperties.getAddresses()) {
-            if (address instanceof Inet4Address) {
-                return address;
-            }
-        }
-        return null;
-    }
-
-    /** Verify restricted networks cannot be requested. */
-    @AppModeFull(reason = "CHANGE_NETWORK_STATE permission can't be granted to instant apps")
-    @Test
-    public void testRestrictedNetworks() {
-        // Verify we can request unrestricted networks:
-        NetworkRequest request = new NetworkRequest.Builder()
-                .addCapability(NET_CAPABILITY_INTERNET).build();
-        NetworkCallback callback = new NetworkCallback();
-        mCm.requestNetwork(request, callback);
-        mCm.unregisterNetworkCallback(callback);
-        // Verify we cannot request restricted networks:
-        request = new NetworkRequest.Builder().addCapability(NET_CAPABILITY_IMS).build();
-        callback = new NetworkCallback();
-        try {
-            mCm.requestNetwork(request, callback);
-            fail("No exception thrown when restricted network requested.");
-        } catch (SecurityException expected) {}
-    }
-
-    // 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(int targetTransportType, boolean requestedMeteredness)
-            throws Exception {
-        final CountDownLatch latch = new CountDownLatch(1);
-        final NetworkCallback networkCallback = new NetworkCallback() {
-            @Override
-            public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) {
-                if (!nc.hasTransport(targetTransportType)) return;
-
-                final boolean metered = !nc.hasCapability(NET_CAPABILITY_NOT_METERED);
-                if (metered == requestedMeteredness) {
-                    latch.countDown();
-                }
-            }
-        };
-        // 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)
-            ? getIntResourceForName(NETWORK_METERED_MULTIPATH_PREFERENCE_RES_NAME)
-            : 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.
-     */
-    @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
-    @Test
-    public void testGetMultipathPreference() throws Exception {
-        final ContentResolver resolver = mContext.getContentResolver();
-        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(TRANSPORT_WIFI, true);
-            // Wifi meterness changes from unmetered to metered will disconnect and reconnect since
-            // R.
-            final Network network = ensureWifiConnected();
-            assertEquals(ssid, unquoteSSID(mWifiManager.getConnectionInfo().getSSID()));
-            assertEquals(mCm.getNetworkCapabilities(network).hasCapability(
-                    NET_CAPABILITY_NOT_METERED), false);
-            assertMultipathPreferenceIsEventually(network, initialMeteredPreference,
-                    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");
-            // No disconnect from unmetered to metered.
-            waitForActiveNetworkMetered(TRANSPORT_WIFI, 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);
-        }
-    }
-
-    // TODO: move the following socket keep alive test to dedicated test class.
-    /**
-     * Callback used in tcp keepalive offload that allows caller to wait callback fires.
-     */
-    private static class TestSocketKeepaliveCallback extends SocketKeepalive.Callback {
-        public enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR };
-
-        public static class CallbackValue {
-            public final CallbackType callbackType;
-            public final int error;
-
-            private CallbackValue(final CallbackType type, final int error) {
-                this.callbackType = type;
-                this.error = error;
-            }
-
-            public static class OnStartedCallback extends CallbackValue {
-                OnStartedCallback() { super(CallbackType.ON_STARTED, 0); }
-            }
-
-            public static class OnStoppedCallback extends CallbackValue {
-                OnStoppedCallback() { super(CallbackType.ON_STOPPED, 0); }
-            }
-
-            public static class OnErrorCallback extends CallbackValue {
-                OnErrorCallback(final int error) { super(CallbackType.ON_ERROR, error); }
-            }
-
-            @Override
-            public boolean equals(Object o) {
-                return o.getClass() == this.getClass()
-                        && this.callbackType == ((CallbackValue) o).callbackType
-                        && this.error == ((CallbackValue) o).error;
-            }
-
-            @Override
-            public String toString() {
-                return String.format("%s(%s, %d)", getClass().getSimpleName(), callbackType, error);
-            }
-        }
-
-        private final LinkedBlockingQueue<CallbackValue> mCallbacks = new LinkedBlockingQueue<>();
-
-        @Override
-        public void onStarted() {
-            mCallbacks.add(new CallbackValue.OnStartedCallback());
-        }
-
-        @Override
-        public void onStopped() {
-            mCallbacks.add(new CallbackValue.OnStoppedCallback());
-        }
-
-        @Override
-        public void onError(final int error) {
-            mCallbacks.add(new CallbackValue.OnErrorCallback(error));
-        }
-
-        public CallbackValue pollCallback() {
-            try {
-                return mCallbacks.poll(KEEPALIVE_CALLBACK_TIMEOUT_MS,
-                        TimeUnit.MILLISECONDS);
-            } catch (InterruptedException e) {
-                fail("Callback not seen after " + KEEPALIVE_CALLBACK_TIMEOUT_MS + " ms");
-            }
-            return null;
-        }
-        private void expectCallback(CallbackValue expectedCallback) {
-            final CallbackValue actualCallback = pollCallback();
-            assertEquals(expectedCallback, actualCallback);
-        }
-
-        public void expectStarted() {
-            expectCallback(new CallbackValue.OnStartedCallback());
-        }
-
-        public void expectStopped() {
-            expectCallback(new CallbackValue.OnStoppedCallback());
-        }
-
-        public void expectError(int error) {
-            expectCallback(new CallbackValue.OnErrorCallback(error));
-        }
-    }
-
-    private InetAddress getAddrByName(final String hostname, final int family) throws Exception {
-        final InetAddress[] allAddrs = InetAddress.getAllByName(hostname);
-        for (InetAddress addr : allAddrs) {
-            if (family == AF_INET && addr instanceof Inet4Address) return addr;
-
-            if (family == AF_INET6 && addr instanceof Inet6Address) return addr;
-
-            if (family == AF_UNSPEC) return addr;
-        }
-        return null;
-    }
-
-    private Socket getConnectedSocket(final Network network, final String host, final int port,
-            final int family) throws Exception {
-        final Socket s = network.getSocketFactory().createSocket();
-        try {
-            final InetAddress addr = getAddrByName(host, family);
-            if (addr == null) fail("Fail to get destination address for " + family);
-
-            final InetSocketAddress sockAddr = new InetSocketAddress(addr, port);
-            s.connect(sockAddr);
-        } catch (Exception e) {
-            s.close();
-            throw e;
-        }
-        return s;
-    }
-
-    private int getSupportedKeepalivesForNet(@NonNull Network network) throws Exception {
-        final NetworkCapabilities nc = mCm.getNetworkCapabilities(network);
-
-        // Get number of supported concurrent keepalives for testing network.
-        final int[] keepalivesPerTransport = KeepaliveUtils.getSupportedKeepalives(mContext);
-        return KeepaliveUtils.getSupportedKeepalivesForNetworkCapabilities(
-                keepalivesPerTransport, nc);
-    }
-
-    private static boolean isTcpKeepaliveSupportedByKernel() {
-        final String kVersionString = VintfRuntimeInfo.getKernelVersion();
-        return compareMajorMinorVersion(kVersionString, "4.8") >= 0;
-    }
-
-    private static Pair<Integer, Integer> getVersionFromString(String version) {
-        // Only gets major and minor number of the version string.
-        final Pattern versionPattern = Pattern.compile("^(\\d+)(\\.(\\d+))?.*");
-        final Matcher m = versionPattern.matcher(version);
-        if (m.matches()) {
-            final int major = Integer.parseInt(m.group(1));
-            final int minor = TextUtils.isEmpty(m.group(3)) ? 0 : Integer.parseInt(m.group(3));
-            return new Pair<>(major, minor);
-        } else {
-            return new Pair<>(0, 0);
-        }
-    }
-
-    // TODO: Move to util class.
-    private static int compareMajorMinorVersion(final String s1, final String s2) {
-        final Pair<Integer, Integer> v1 = getVersionFromString(s1);
-        final Pair<Integer, Integer> v2 = getVersionFromString(s2);
-
-        if (v1.first == v2.first) {
-            return Integer.compare(v1.second, v2.second);
-        } else {
-            return Integer.compare(v1.first, v2.first);
-        }
-    }
-
-    /**
-     * Verifies that version string compare logic returns expected result for various cases.
-     * Note that only major and minor number are compared.
-     */
-    @Test
-    public void testMajorMinorVersionCompare() {
-        assertEquals(0, compareMajorMinorVersion("4.8.1", "4.8"));
-        assertEquals(1, compareMajorMinorVersion("4.9", "4.8.1"));
-        assertEquals(1, compareMajorMinorVersion("5.0", "4.8"));
-        assertEquals(1, compareMajorMinorVersion("5", "4.8"));
-        assertEquals(0, compareMajorMinorVersion("5", "5.0"));
-        assertEquals(1, compareMajorMinorVersion("5-beta1", "4.8"));
-        assertEquals(0, compareMajorMinorVersion("4.8.0.0", "4.8"));
-        assertEquals(0, compareMajorMinorVersion("4.8-RC1", "4.8"));
-        assertEquals(0, compareMajorMinorVersion("4.8", "4.8"));
-        assertEquals(-1, compareMajorMinorVersion("3.10", "4.8.0"));
-        assertEquals(-1, compareMajorMinorVersion("4.7.10.10", "4.8"));
-    }
-
-    /**
-     * Verifies that the keepalive API cannot create any keepalive when the maximum number of
-     * keepalives is set to 0.
-     */
-    @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
-    @Test
-    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;
-        final InetAddress srcAddr = getFirstV4Address(network);
-        assumeTrue("This test requires native IPv4", srcAddr != null);
-
-        runWithShellPermissionIdentity(() -> {
-            assertEquals(0, createConcurrentSocketKeepalives(network, srcAddr, 1, 0));
-            assertEquals(0, createConcurrentSocketKeepalives(network, srcAddr, 0, 1));
-        });
-    }
-
-    @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
-    @Test
-    @SkipPresubmit(reason = "Keepalive is not supported on virtual hardware")
-    public void testCreateTcpKeepalive() throws Exception {
-        if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
-            Log.i(TAG, "testCreateTcpKeepalive cannot execute unless device supports WiFi");
-            return;
-        }
-
-        final Network network = ensureWifiConnected();
-        if (getSupportedKeepalivesForNet(network) == 0) return;
-        final InetAddress srcAddr = getFirstV4Address(network);
-        assumeTrue("This test requires native IPv4", srcAddr != null);
-
-        // 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.
-            runWithShellPermissionIdentity(() -> {
-                assertEquals(0, createConcurrentSocketKeepalives(network, srcAddr, 0, 1));
-            });
-            Log.i(TAG, "testCreateTcpKeepalive is skipped for kernel "
-                    + VintfRuntimeInfo.getKernelVersion());
-            return;
-        }
-
-        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.
-        try (Socket s = getConnectedSocket(network, TEST_HOST, HTTP_PORT, AF_INET)) {
-
-            // Should able to start keep alive offload when socket is idle.
-            final Executor executor = mContext.getMainExecutor();
-            final TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback();
-
-            mUiAutomation.adoptShellPermissionIdentity();
-            try (SocketKeepalive sk = mCm.createSocketKeepalive(network, s, executor, callback)) {
-                sk.start(MIN_KEEPALIVE_INTERVAL);
-                callback.expectStarted();
-
-                // App should not able to write during keepalive offload.
-                final OutputStream out = s.getOutputStream();
-                try {
-                    out.write(requestBytes);
-                    fail("Should not able to write");
-                } catch (IOException e) { }
-                // App should not able to read during keepalive offload.
-                final InputStream in = s.getInputStream();
-                byte[] responseBytes = new byte[4096];
-                try {
-                    in.read(responseBytes);
-                    fail("Should not able to read");
-                } catch (IOException e) { }
-
-                // Stop.
-                sk.stop();
-                callback.expectStopped();
-            } finally {
-                mUiAutomation.dropShellPermissionIdentity();
-            }
-
-            // Ensure socket is still connected.
-            assertTrue(s.isConnected());
-            assertFalse(s.isClosed());
-
-            // Let socket be not idle.
-            try {
-                final OutputStream out = s.getOutputStream();
-                out.write(requestBytes);
-            } catch (IOException e) {
-                fail("Failed to write data " + e);
-            }
-            // Make sure response data arrives.
-            final MessageQueue fdHandlerQueue = Looper.getMainLooper().getQueue();
-            final FileDescriptor fd = s.getFileDescriptor$();
-            final CountDownLatch mOnReceiveLatch = new CountDownLatch(1);
-            fdHandlerQueue.addOnFileDescriptorEventListener(fd, EVENT_INPUT, (readyFd, events) -> {
-                mOnReceiveLatch.countDown();
-                return 0; // Unregister listener.
-            });
-            if (!mOnReceiveLatch.await(2, TimeUnit.SECONDS)) {
-                fdHandlerQueue.removeOnFileDescriptorEventListener(fd);
-                fail("Timeout: no response data");
-            }
-
-            // Should get ERROR_SOCKET_NOT_IDLE because there is still data in the receive queue
-            // that has not been read.
-            mUiAutomation.adoptShellPermissionIdentity();
-            try (SocketKeepalive sk = mCm.createSocketKeepalive(network, s, executor, callback)) {
-                sk.start(MIN_KEEPALIVE_INTERVAL);
-                callback.expectError(SocketKeepalive.ERROR_SOCKET_NOT_IDLE);
-            } finally {
-                mUiAutomation.dropShellPermissionIdentity();
-            }
-        }
-    }
-
-    private ArrayList<SocketKeepalive> createConcurrentKeepalivesOfType(
-            int requestCount, @NonNull TestSocketKeepaliveCallback callback,
-            Supplier<SocketKeepalive> kaFactory) {
-        final ArrayList<SocketKeepalive> kalist = new ArrayList<>();
-
-        int remainingRetries = MAX_KEEPALIVE_RETRY_COUNT;
-
-        // 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 (kalist.size() == 0 && cv.error == SocketKeepalive.ERROR_UNSUPPORTED) {
-                    // Unsupported.
-                    break;
-                } 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 " + (kalist.size() + 1) + " "
-                        + ka.getClass().getSimpleName() + ": " + cv);
-            }
-        }
-
-        return kalist;
-    }
-
-    private @NonNull ArrayList<SocketKeepalive> createConcurrentNattSocketKeepalives(
-            @NonNull Network network, @NonNull InetAddress srcAddr, 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 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,
-                    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, @NonNull InetAddress srcAddr, int nattCount, int tcpCount)
-            throws Exception {
-        final ArrayList<SocketKeepalive> kalist = new ArrayList<>();
-        final TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback();
-
-        kalist.addAll(createConcurrentNattSocketKeepalives(network, srcAddr, nattCount, callback));
-        kalist.addAll(createConcurrentTcpSocketKeepalives(network, tcpCount, callback));
-
-        final int ret = kalist.size();
-
-        // Clean up.
-        for (final SocketKeepalive ka : kalist) {
-            ka.stop();
-            callback.expectStopped();
-        }
-        kalist.clear();
-
-        return ret;
-    }
-
-    /**
-     * Verifies that the concurrent keepalive slots meet the minimum requirement, and don't
-     * get leaked after iterations.
-     */
-    @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
-    @Test
-    @SkipPresubmit(reason = "Keepalive is not supported on virtual hardware")
-    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;
-        }
-        final InetAddress srcAddr = getFirstV4Address(network);
-        assumeTrue("This test requires native IPv4", srcAddr != null);
-
-        runWithShellPermissionIdentity(() -> {
-            // Verifies that the supported keepalive slots meet MIN_SUPPORTED_KEEPALIVE_COUNT.
-            assertGreaterOrEqual(supported, MIN_SUPPORTED_WIFI_KEEPALIVE_COUNT);
-
-            // Verifies that Nat-T keepalives can be established.
-            assertEquals(supported, createConcurrentSocketKeepalives(network, srcAddr,
-                    supported + 1, 0));
-            // Verifies that keepalives don't get leaked in second round.
-            assertEquals(supported, createConcurrentSocketKeepalives(network, srcAddr, 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()) return;
-
-        runWithShellPermissionIdentity(() -> {
-            assertEquals(supported, createConcurrentSocketKeepalives(network, srcAddr, 0,
-                    supported + 1));
-
-            // Verifies that different types can be established at the same time.
-            assertEquals(supported, createConcurrentSocketKeepalives(network, srcAddr,
-                    supported / 2, supported - supported / 2));
-
-            // Verifies that keepalives don't get leaked in second round.
-            assertEquals(supported, createConcurrentSocketKeepalives(network, srcAddr, 0,
-                    supported));
-            assertEquals(supported, createConcurrentSocketKeepalives(network, srcAddr,
-                    supported / 2, supported - supported / 2));
-        });
-    }
-
-    /**
-     * 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")
-    @Test
-    @SkipPresubmit(reason = "Keepalive is not supported on virtual hardware")
-    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);
-        final InetAddress srcAddr = getFirstV4Address(network);
-        assumeTrue("This test requires native IPv4", srcAddr != null);
-
-        runWithShellPermissionIdentity(() -> {
-            // 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, srcAddr,
-                    supported + 1, 0));
-            // Verifies that keepalives don't get leaked in second round.
-            assertEquals(supported, createConcurrentSocketKeepalives(network, srcAddr, supported,
-                    0));
-        });
-    }
-
-    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")
-    @Test
-    @SkipPresubmit(reason = "Keepalive is not supported on virtual hardware")
-    public void testSocketKeepaliveUnprivileged() throws Exception {
-        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 InetAddress srcAddr = getFirstV4Address(network);
-        assumeTrue("This test requires native IPv4", srcAddr != null);
-
-        // 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.
-        assertGreaterOrEqual(supported, reservedPrivilegedSlots);
-        assertGreaterOrEqual(supported, allowedUnprivilegedPerUid);
-        final int expectedUnprivileged =
-                Math.min(allowedUnprivilegedPerUid, supported - reservedPrivilegedSlots);
-        assertEquals(expectedUnprivileged,
-                createConcurrentSocketKeepalives(network, srcAddr, supported + 1, 0));
-    }
-
-    private static void assertGreaterOrEqual(long greater, long lesser) {
-        assertTrue("" + greater + " expected to be greater than or equal to " + lesser,
-                greater >= lesser);
-    }
-
-    /**
-     * Verifies that apps are not allowed to access restricted networks even if they declare the
-     * CONNECTIVITY_USE_RESTRICTED_NETWORKS permission in their manifests.
-     * See. b/144679405.
-     */
-    @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
-    @Test
-    public void testRestrictedNetworkPermission() throws Exception {
-        // Ensure that CONNECTIVITY_USE_RESTRICTED_NETWORKS isn't granted to this package.
-        final PackageInfo app = mPackageManager.getPackageInfo(mContext.getPackageName(),
-                GET_PERMISSIONS);
-        final int index = ArrayUtils.indexOf(
-                app.requestedPermissions, CONNECTIVITY_USE_RESTRICTED_NETWORKS);
-        assertTrue(index >= 0);
-        assertTrue(app.requestedPermissionsFlags[index] != PERMISSION_GRANTED);
-
-        // Ensure that NetworkUtils.queryUserAccess always returns false since this package should
-        // not have netd system permission to call this function.
-        final Network wifiNetwork = ensureWifiConnected();
-        assertFalse(NetworkUtils.queryUserAccess(Binder.getCallingUid(), wifiNetwork.netId));
-
-        // Ensure that this package cannot bind to any restricted network that's currently
-        // connected.
-        Network[] networks = mCm.getAllNetworks();
-        for (Network network : networks) {
-            NetworkCapabilities nc = mCm.getNetworkCapabilities(network);
-            if (nc != null && !nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
-                try {
-                    network.bindSocket(new Socket());
-                    fail("Bind to restricted network " + network + " unexpectedly succeeded");
-                } catch (IOException expected) {}
-            }
-        }
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/CredentialsTest.java b/tests/cts/net/src/android/net/cts/CredentialsTest.java
deleted file mode 100644
index 91c3621..0000000
--- a/tests/cts/net/src/android/net/cts/CredentialsTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-import android.net.Credentials;
-import android.test.AndroidTestCase;
-
-public class CredentialsTest extends AndroidTestCase {
-
-    public void testCredentials() {
-        // new the Credentials instance
-        // Test with zero inputs
-        Credentials cred = new Credentials(0, 0, 0);
-        assertEquals(0, cred.getGid());
-        assertEquals(0, cred.getPid());
-        assertEquals(0, cred.getUid());
-
-        // Test with big integer
-        cred = new Credentials(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
-        assertEquals(Integer.MAX_VALUE, cred.getGid());
-        assertEquals(Integer.MAX_VALUE, cred.getPid());
-        assertEquals(Integer.MAX_VALUE, cred.getUid());
-
-        // Test with big negative integer
-        cred = new Credentials(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE);
-        assertEquals(Integer.MIN_VALUE, cred.getGid());
-        assertEquals(Integer.MIN_VALUE, cred.getPid());
-        assertEquals(Integer.MIN_VALUE, cred.getUid());
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/DnsResolverTest.java b/tests/cts/net/src/android/net/cts/DnsResolverTest.java
deleted file mode 100644
index 4d95fbe..0000000
--- a/tests/cts/net/src/android/net/cts/DnsResolverTest.java
+++ /dev/null
@@ -1,763 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-import static android.net.DnsResolver.CLASS_IN;
-import static android.net.DnsResolver.FLAG_EMPTY;
-import static android.net.DnsResolver.FLAG_NO_CACHE_LOOKUP;
-import static android.net.DnsResolver.TYPE_A;
-import static android.net.DnsResolver.TYPE_AAAA;
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.system.OsConstants.ETIMEDOUT;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.content.ContentResolver;
-import android.content.pm.PackageManager;
-import android.net.ConnectivityManager;
-import android.net.ConnectivityManager.NetworkCallback;
-import android.net.DnsResolver;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.net.ParseException;
-import android.net.cts.util.CtsNetUtils;
-import android.os.CancellationSignal;
-import android.os.Handler;
-import android.os.Looper;
-import android.platform.test.annotations.AppModeFull;
-import android.provider.Settings;
-import android.system.ErrnoException;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import com.android.net.module.util.DnsPacket;
-import com.android.testutils.SkipPresubmit;
-
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-
-@AppModeFull(reason = "WRITE_SECURE_SETTINGS permission can't be granted to instant apps")
-public class DnsResolverTest extends AndroidTestCase {
-    private static final String TAG = "DnsResolverTest";
-    private static final char[] HEX_CHARS = {
-            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
-    };
-
-    static final String TEST_DOMAIN = "www.google.com";
-    static final String TEST_NX_DOMAIN = "test1-nx.metric.gstatic.com";
-    static final String INVALID_PRIVATE_DNS_SERVER = "invalid.google";
-    static final String GOOGLE_PRIVATE_DNS_SERVER = "dns.google";
-    static final byte[] TEST_BLOB = new byte[]{
-            /* Header */
-            0x55, 0x66, /* Transaction ID */
-            0x01, 0x00, /* Flags */
-            0x00, 0x01, /* Questions */
-            0x00, 0x00, /* Answer RRs */
-            0x00, 0x00, /* Authority RRs */
-            0x00, 0x00, /* Additional RRs */
-            /* Queries */
-            0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65,
-            0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */
-            0x00, 0x01, /* Type */
-            0x00, 0x01  /* Class */
-    };
-    static final int TIMEOUT_MS = 12_000;
-    static final int CANCEL_TIMEOUT_MS = 3_000;
-    static final int CANCEL_RETRY_TIMES = 5;
-    static final int QUERY_TIMES = 10;
-    static final int NXDOMAIN = 3;
-
-    private ContentResolver mCR;
-    private ConnectivityManager mCM;
-    private PackageManager mPackageManager;
-    private CtsNetUtils mCtsNetUtils;
-    private Executor mExecutor;
-    private Executor mExecutorInline;
-    private DnsResolver mDns;
-
-    private String mOldMode;
-    private String mOldDnsSpecifier;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
-        mDns = DnsResolver.getInstance();
-        mExecutor = new Handler(Looper.getMainLooper())::post;
-        mExecutorInline = (Runnable r) -> r.run();
-        mCR = getContext().getContentResolver();
-        mCtsNetUtils = new CtsNetUtils(getContext());
-        mCtsNetUtils.storePrivateDnsSetting();
-        mPackageManager = mContext.getPackageManager();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mCtsNetUtils.restorePrivateDnsSetting();
-        super.tearDown();
-    }
-
-    private static String byteArrayToHexString(byte[] bytes) {
-        char[] hexChars = new char[bytes.length * 2];
-        for (int i = 0; i < bytes.length; ++i) {
-            int b = bytes[i] & 0xFF;
-            hexChars[i * 2] = HEX_CHARS[b >>> 4];
-            hexChars[i * 2 + 1] = HEX_CHARS[b & 0x0F];
-        }
-        return new String(hexChars);
-    }
-
-    private Network[] getTestableNetworks() {
-        if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
-            mCtsNetUtils.ensureWifiConnected();
-        }
-        final ArrayList<Network> testableNetworks = new ArrayList<Network>();
-        for (Network network : mCM.getAllNetworks()) {
-            final NetworkCapabilities nc = mCM.getNetworkCapabilities(network);
-            if (nc != null
-                    && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
-                    && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
-                testableNetworks.add(network);
-            }
-        }
-
-        assertTrue(
-                "This test requires that at least one network be connected. " +
-                        "Please ensure that the device is connected to a network.",
-                testableNetworks.size() >= 1);
-        // In order to test query with null network, add null as an element.
-        // Test cases which query with null network will go on default network.
-        testableNetworks.add(null);
-        return testableNetworks.toArray(new Network[0]);
-    }
-
-    static private void assertGreaterThan(String msg, int first, int second) {
-        assertTrue(msg + " Excepted " + first + " to be greater than " + second, first > second);
-    }
-
-    private static class DnsParseException extends Exception {
-        public DnsParseException(String msg) {
-            super(msg);
-        }
-    }
-
-    private static class DnsAnswer extends DnsPacket {
-        DnsAnswer(@NonNull byte[] data) throws DnsParseException {
-            super(data);
-
-            // Check QR field.(query (0), or a response (1)).
-            if ((mHeader.flags & (1 << 15)) == 0) {
-                throw new DnsParseException("Not an answer packet");
-            }
-        }
-
-        int getRcode() {
-            return mHeader.rcode;
-        }
-
-        int getANCount() {
-            return mHeader.getRecordCount(ANSECTION);
-        }
-
-        int getQDCount() {
-            return mHeader.getRecordCount(QDSECTION);
-        }
-    }
-
-    /**
-     * A query callback that ensures that the query is cancelled and that onAnswer is never
-     * called. If the query succeeds before it is cancelled, needRetry will return true so the
-     * test can retry.
-     */
-    class VerifyCancelCallback implements DnsResolver.Callback<byte[]> {
-        private final CountDownLatch mLatch = new CountDownLatch(1);
-        private final String mMsg;
-        private final CancellationSignal mCancelSignal;
-        private int mRcode;
-        private DnsAnswer mDnsAnswer;
-        private String mErrorMsg = null;
-
-        VerifyCancelCallback(@NonNull String msg, @Nullable CancellationSignal cancel) {
-            mMsg = msg;
-            mCancelSignal = cancel;
-        }
-
-        VerifyCancelCallback(@NonNull String msg) {
-            this(msg, null);
-        }
-
-        public boolean waitForAnswer(int timeout) throws InterruptedException {
-            return mLatch.await(timeout, TimeUnit.MILLISECONDS);
-        }
-
-        public boolean waitForAnswer() throws InterruptedException {
-            return waitForAnswer(TIMEOUT_MS);
-        }
-
-        public boolean needRetry() throws InterruptedException {
-            return mLatch.await(CANCEL_TIMEOUT_MS, TimeUnit.MILLISECONDS);
-        }
-
-        @Override
-        public void onAnswer(@NonNull byte[] answer, int rcode) {
-            if (mCancelSignal != null && mCancelSignal.isCanceled()) {
-                mErrorMsg = mMsg + " should not have returned any answers";
-                mLatch.countDown();
-                return;
-            }
-
-            mRcode = rcode;
-            try {
-                mDnsAnswer = new DnsAnswer(answer);
-            } catch (ParseException | DnsParseException e) {
-                mErrorMsg = mMsg + e.getMessage();
-                mLatch.countDown();
-                return;
-            }
-            Log.d(TAG, "Reported blob: " + byteArrayToHexString(answer));
-            mLatch.countDown();
-        }
-
-        @Override
-        public void onError(@NonNull DnsResolver.DnsException error) {
-            mErrorMsg = mMsg + error.getMessage();
-            mLatch.countDown();
-        }
-
-        private void assertValidAnswer() {
-            assertNull(mErrorMsg);
-            assertNotNull(mMsg + " No valid answer", mDnsAnswer);
-            assertEquals(mMsg + " Unexpected error: reported rcode" + mRcode +
-                    " blob's rcode " + mDnsAnswer.getRcode(), mRcode, mDnsAnswer.getRcode());
-        }
-
-        public void assertHasAnswer() {
-            assertValidAnswer();
-            // Check rcode field.(0, No error condition).
-            assertEquals(mMsg + " Response error, rcode: " + mRcode, mRcode, 0);
-            // Check answer counts.
-            assertGreaterThan(mMsg + " No answer found", mDnsAnswer.getANCount(), 0);
-            // Check question counts.
-            assertGreaterThan(mMsg + " No question found", mDnsAnswer.getQDCount(), 0);
-        }
-
-        public void assertNXDomain() {
-            assertValidAnswer();
-            // Check rcode field.(3, NXDomain).
-            assertEquals(mMsg + " Unexpected rcode: " + mRcode, mRcode, NXDOMAIN);
-            // Check answer counts. Expect 0 answer.
-            assertEquals(mMsg + " Not an empty answer", mDnsAnswer.getANCount(), 0);
-            // Check question counts.
-            assertGreaterThan(mMsg + " No question found", mDnsAnswer.getQDCount(), 0);
-        }
-
-        public void assertEmptyAnswer() {
-            assertValidAnswer();
-            // Check rcode field.(0, No error condition).
-            assertEquals(mMsg + " Response error, rcode: " + mRcode, mRcode, 0);
-            // Check answer counts. Expect 0 answer.
-            assertEquals(mMsg + " Not an empty answer", mDnsAnswer.getANCount(), 0);
-            // Check question counts.
-            assertGreaterThan(mMsg + " No question found", mDnsAnswer.getQDCount(), 0);
-        }
-    }
-
-    public void testRawQuery() throws Exception {
-        doTestRawQuery(mExecutor);
-    }
-
-    public void testRawQueryInline() throws Exception {
-        doTestRawQuery(mExecutorInline);
-    }
-
-    public void testRawQueryBlob() throws Exception {
-        doTestRawQueryBlob(mExecutor);
-    }
-
-    public void testRawQueryBlobInline() throws Exception {
-        doTestRawQueryBlob(mExecutorInline);
-    }
-
-    public void testRawQueryRoot() throws Exception {
-        doTestRawQueryRoot(mExecutor);
-    }
-
-    public void testRawQueryRootInline() throws Exception {
-        doTestRawQueryRoot(mExecutorInline);
-    }
-
-    public void testRawQueryNXDomain() throws Exception {
-        doTestRawQueryNXDomain(mExecutor);
-    }
-
-    public void testRawQueryNXDomainInline() throws Exception {
-        doTestRawQueryNXDomain(mExecutorInline);
-    }
-
-    public void testRawQueryNXDomainWithPrivateDns() throws Exception {
-        doTestRawQueryNXDomainWithPrivateDns(mExecutor);
-    }
-
-    public void testRawQueryNXDomainInlineWithPrivateDns() throws Exception {
-        doTestRawQueryNXDomainWithPrivateDns(mExecutorInline);
-    }
-
-    public void doTestRawQuery(Executor executor) throws InterruptedException {
-        final String msg = "RawQuery " + TEST_DOMAIN;
-        for (Network network : getTestableNetworks()) {
-            final VerifyCancelCallback callback = new VerifyCancelCallback(msg);
-            mDns.rawQuery(network, TEST_DOMAIN, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP,
-                    executor, null, callback);
-
-            assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
-                    callback.waitForAnswer());
-            callback.assertHasAnswer();
-        }
-    }
-
-    public void doTestRawQueryBlob(Executor executor) throws InterruptedException {
-        final byte[] blob = new byte[]{
-                /* Header */
-                0x55, 0x66, /* Transaction ID */
-                0x01, 0x00, /* Flags */
-                0x00, 0x01, /* Questions */
-                0x00, 0x00, /* Answer RRs */
-                0x00, 0x00, /* Authority RRs */
-                0x00, 0x00, /* Additional RRs */
-                /* Queries */
-                0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65,
-                0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */
-                0x00, 0x01, /* Type */
-                0x00, 0x01  /* Class */
-        };
-        final String msg = "RawQuery blob " + byteArrayToHexString(blob);
-        for (Network network : getTestableNetworks()) {
-            final VerifyCancelCallback callback = new VerifyCancelCallback(msg);
-            mDns.rawQuery(network, blob, FLAG_NO_CACHE_LOOKUP, executor, null, callback);
-
-            assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
-                    callback.waitForAnswer());
-            callback.assertHasAnswer();
-        }
-    }
-
-    public void doTestRawQueryRoot(Executor executor) throws InterruptedException {
-        final String dname = "";
-        final String msg = "RawQuery empty dname(ROOT) ";
-        for (Network network : getTestableNetworks()) {
-            final VerifyCancelCallback callback = new VerifyCancelCallback(msg);
-            mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP,
-                    executor, null, callback);
-
-            assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
-                    callback.waitForAnswer());
-            // Except no answer record because the root does not have AAAA records.
-            callback.assertEmptyAnswer();
-        }
-    }
-
-    public void doTestRawQueryNXDomain(Executor executor) throws InterruptedException {
-        final String msg = "RawQuery " + TEST_NX_DOMAIN;
-
-        for (Network network : getTestableNetworks()) {
-            final NetworkCapabilities nc = (network != null)
-                    ? mCM.getNetworkCapabilities(network)
-                    : mCM.getNetworkCapabilities(mCM.getActiveNetwork());
-            assertNotNull("Couldn't determine NetworkCapabilities for " + network, nc);
-            // Some cellular networks configure their DNS servers never to return NXDOMAIN, so don't
-            // test NXDOMAIN on these DNS servers.
-            // b/144521720
-            if (nc.hasTransport(TRANSPORT_CELLULAR)) continue;
-            final VerifyCancelCallback callback = new VerifyCancelCallback(msg);
-            mDns.rawQuery(network, TEST_NX_DOMAIN, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP,
-                    executor, null, callback);
-
-            assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
-                    callback.waitForAnswer());
-            callback.assertNXDomain();
-        }
-    }
-
-    public void doTestRawQueryNXDomainWithPrivateDns(Executor executor)
-            throws InterruptedException {
-        final String msg = "RawQuery " + TEST_NX_DOMAIN + " with private DNS";
-        // Enable private DNS strict mode and set server to dns.google before doing NxDomain test.
-        // b/144521720
-        mCtsNetUtils.setPrivateDnsStrictMode(GOOGLE_PRIVATE_DNS_SERVER);
-        for (Network network :  getTestableNetworks()) {
-            final Network networkForPrivateDns =
-                    (network != null) ? network : mCM.getActiveNetwork();
-            assertNotNull("Can't find network to await private DNS on", networkForPrivateDns);
-            mCtsNetUtils.awaitPrivateDnsSetting(msg + " wait private DNS setting timeout",
-                    networkForPrivateDns, GOOGLE_PRIVATE_DNS_SERVER, true);
-            final VerifyCancelCallback callback = new VerifyCancelCallback(msg);
-            mDns.rawQuery(network, TEST_NX_DOMAIN, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP,
-                    executor, null, callback);
-
-            assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
-                    callback.waitForAnswer());
-            callback.assertNXDomain();
-        }
-    }
-
-    public void testRawQueryCancel() throws InterruptedException {
-        final String msg = "Test cancel RawQuery " + TEST_DOMAIN;
-        // Start a DNS query and the cancel it immediately. Use VerifyCancelCallback to expect
-        // that the query is cancelled before it succeeds. If it is not cancelled before it
-        // succeeds, retry the test until it is.
-        for (Network network : getTestableNetworks()) {
-            boolean retry = false;
-            int round = 0;
-            do {
-                if (++round > CANCEL_RETRY_TIMES) {
-                    fail(msg + " cancel failed " + CANCEL_RETRY_TIMES + " times");
-                }
-                final CountDownLatch latch = new CountDownLatch(1);
-                final CancellationSignal cancelSignal = new CancellationSignal();
-                final VerifyCancelCallback callback = new VerifyCancelCallback(msg, cancelSignal);
-                mDns.rawQuery(network, TEST_DOMAIN, CLASS_IN, TYPE_AAAA, FLAG_EMPTY,
-                        mExecutor, cancelSignal, callback);
-                mExecutor.execute(() -> {
-                    cancelSignal.cancel();
-                    latch.countDown();
-                });
-
-                retry = callback.needRetry();
-                assertTrue(msg + " query was not cancelled",
-                        latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-            } while (retry);
-        }
-    }
-
-    public void testRawQueryBlobCancel() throws InterruptedException {
-        final String msg = "Test cancel RawQuery blob " + byteArrayToHexString(TEST_BLOB);
-        // Start a DNS query and the cancel it immediately. Use VerifyCancelCallback to expect
-        // that the query is cancelled before it succeeds. If it is not cancelled before it
-        // succeeds, retry the test until it is.
-        for (Network network : getTestableNetworks()) {
-            boolean retry = false;
-            int round = 0;
-            do {
-                if (++round > CANCEL_RETRY_TIMES) {
-                    fail(msg + " cancel failed " + CANCEL_RETRY_TIMES + " times");
-                }
-                final CountDownLatch latch = new CountDownLatch(1);
-                final CancellationSignal cancelSignal = new CancellationSignal();
-                final VerifyCancelCallback callback = new VerifyCancelCallback(msg, cancelSignal);
-                mDns.rawQuery(network, TEST_BLOB, FLAG_EMPTY, mExecutor, cancelSignal, callback);
-                mExecutor.execute(() -> {
-                    cancelSignal.cancel();
-                    latch.countDown();
-                });
-
-                retry = callback.needRetry();
-                assertTrue(msg + " cancel is not done",
-                        latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-            } while (retry);
-        }
-    }
-
-    public void testCancelBeforeQuery() throws InterruptedException {
-        final String msg = "Test cancelled RawQuery " + TEST_DOMAIN;
-        for (Network network : getTestableNetworks()) {
-            final VerifyCancelCallback callback = new VerifyCancelCallback(msg);
-            final CancellationSignal cancelSignal = new CancellationSignal();
-            cancelSignal.cancel();
-            mDns.rawQuery(network, TEST_DOMAIN, CLASS_IN, TYPE_AAAA, FLAG_EMPTY,
-                    mExecutor, cancelSignal, callback);
-
-            assertTrue(msg + " should not return any answers",
-                    !callback.waitForAnswer(CANCEL_TIMEOUT_MS));
-        }
-    }
-
-    /**
-     * A query callback for InetAddress that ensures that the query is
-     * cancelled and that onAnswer is never called. If the query succeeds
-     * before it is cancelled, needRetry will return true so the
-     * test can retry.
-     */
-    class VerifyCancelInetAddressCallback implements DnsResolver.Callback<List<InetAddress>> {
-        private final CountDownLatch mLatch = new CountDownLatch(1);
-        private final String mMsg;
-        private final List<InetAddress> mAnswers;
-        private final CancellationSignal mCancelSignal;
-        private String mErrorMsg = null;
-
-        VerifyCancelInetAddressCallback(@NonNull String msg, @Nullable CancellationSignal cancel) {
-            this.mMsg = msg;
-            this.mCancelSignal = cancel;
-            mAnswers = new ArrayList<>();
-        }
-
-        public boolean waitForAnswer() throws InterruptedException {
-            return mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
-        }
-
-        public boolean needRetry() throws InterruptedException {
-            return mLatch.await(CANCEL_TIMEOUT_MS, TimeUnit.MILLISECONDS);
-        }
-
-        public boolean isAnswerEmpty() {
-            return mAnswers.isEmpty();
-        }
-
-        public boolean hasIpv6Answer() {
-            for (InetAddress answer : mAnswers) {
-                if (answer instanceof Inet6Address) return true;
-            }
-            return false;
-        }
-
-        public boolean hasIpv4Answer() {
-            for (InetAddress answer : mAnswers) {
-                if (answer instanceof Inet4Address) return true;
-            }
-            return false;
-        }
-
-        public void assertNoError() {
-            assertNull(mErrorMsg);
-        }
-
-        @Override
-        public void onAnswer(@NonNull List<InetAddress> answerList, int rcode) {
-            if (mCancelSignal != null && mCancelSignal.isCanceled()) {
-                mErrorMsg = mMsg + " should not have returned any answers";
-                mLatch.countDown();
-                return;
-            }
-            for (InetAddress addr : answerList) {
-                Log.d(TAG, "Reported addr: " + addr.toString());
-            }
-            mAnswers.clear();
-            mAnswers.addAll(answerList);
-            mLatch.countDown();
-        }
-
-        @Override
-        public void onError(@NonNull DnsResolver.DnsException error) {
-            mErrorMsg = mMsg + error.getMessage();
-            mLatch.countDown();
-        }
-    }
-
-    public void testQueryForInetAddress() throws Exception {
-        doTestQueryForInetAddress(mExecutor);
-    }
-
-    public void testQueryForInetAddressInline() throws Exception {
-        doTestQueryForInetAddress(mExecutorInline);
-    }
-
-    public void testQueryForInetAddressIpv4() throws Exception {
-        doTestQueryForInetAddressIpv4(mExecutor);
-    }
-
-    public void testQueryForInetAddressIpv4Inline() throws Exception {
-        doTestQueryForInetAddressIpv4(mExecutorInline);
-    }
-
-    public void testQueryForInetAddressIpv6() throws Exception {
-        doTestQueryForInetAddressIpv6(mExecutor);
-    }
-
-    public void testQueryForInetAddressIpv6Inline() throws Exception {
-        doTestQueryForInetAddressIpv6(mExecutorInline);
-    }
-
-    public void testContinuousQueries() throws Exception {
-        doTestContinuousQueries(mExecutor);
-    }
-
-    @SkipPresubmit(reason = "Flaky: b/159762682; add to presubmit after fixing")
-    public void testContinuousQueriesInline() throws Exception {
-        doTestContinuousQueries(mExecutorInline);
-    }
-
-    public void doTestQueryForInetAddress(Executor executor) throws InterruptedException {
-        final String msg = "Test query for InetAddress " + TEST_DOMAIN;
-        for (Network network : getTestableNetworks()) {
-            final VerifyCancelInetAddressCallback callback =
-                    new VerifyCancelInetAddressCallback(msg, null);
-            mDns.query(network, TEST_DOMAIN, FLAG_NO_CACHE_LOOKUP, executor, null, callback);
-
-            assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
-                    callback.waitForAnswer());
-            callback.assertNoError();
-            assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty());
-        }
-    }
-
-    public void testQueryCancelForInetAddress() throws InterruptedException {
-        final String msg = "Test cancel query for InetAddress " + TEST_DOMAIN;
-        // Start a DNS query and the cancel it immediately. Use VerifyCancelInetAddressCallback to
-        // expect that the query is cancelled before it succeeds. If it is not cancelled before it
-        // succeeds, retry the test until it is.
-        for (Network network : getTestableNetworks()) {
-            boolean retry = false;
-            int round = 0;
-            do {
-                if (++round > CANCEL_RETRY_TIMES) {
-                    fail(msg + " cancel failed " + CANCEL_RETRY_TIMES + " times");
-                }
-                final CountDownLatch latch = new CountDownLatch(1);
-                final CancellationSignal cancelSignal = new CancellationSignal();
-                final VerifyCancelInetAddressCallback callback =
-                        new VerifyCancelInetAddressCallback(msg, cancelSignal);
-                mDns.query(network, TEST_DOMAIN, FLAG_EMPTY, mExecutor, cancelSignal, callback);
-                mExecutor.execute(() -> {
-                    cancelSignal.cancel();
-                    latch.countDown();
-                });
-
-                retry = callback.needRetry();
-                assertTrue(msg + " query was not cancelled",
-                        latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-            } while (retry);
-        }
-    }
-
-    public void doTestQueryForInetAddressIpv4(Executor executor) throws InterruptedException {
-        final String msg = "Test query for IPv4 InetAddress " + TEST_DOMAIN;
-        for (Network network : getTestableNetworks()) {
-            final VerifyCancelInetAddressCallback callback =
-                    new VerifyCancelInetAddressCallback(msg, null);
-            mDns.query(network, TEST_DOMAIN, TYPE_A, FLAG_NO_CACHE_LOOKUP,
-                    executor, null, callback);
-
-            assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
-                    callback.waitForAnswer());
-            callback.assertNoError();
-            assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty());
-            assertTrue(msg + " returned Ipv6 results", !callback.hasIpv6Answer());
-        }
-    }
-
-    public void doTestQueryForInetAddressIpv6(Executor executor) throws InterruptedException {
-        final String msg = "Test query for IPv6 InetAddress " + TEST_DOMAIN;
-        for (Network network : getTestableNetworks()) {
-            final VerifyCancelInetAddressCallback callback =
-                    new VerifyCancelInetAddressCallback(msg, null);
-            mDns.query(network, TEST_DOMAIN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP,
-                    executor, null, callback);
-
-            assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
-                    callback.waitForAnswer());
-            callback.assertNoError();
-            assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty());
-            assertTrue(msg + " returned Ipv4 results", !callback.hasIpv4Answer());
-        }
-    }
-
-    public void testPrivateDnsBypass() throws InterruptedException {
-        final Network[] testNetworks = getTestableNetworks();
-
-        // Set an invalid private DNS server
-        mCtsNetUtils.setPrivateDnsStrictMode(INVALID_PRIVATE_DNS_SERVER);
-        final String msg = "Test PrivateDnsBypass " + TEST_DOMAIN;
-        for (Network network : testNetworks) {
-            // This test cannot be ran with null network because we need to explicitly pass a
-            // private DNS bypassable network or bind one.
-            if (network == null) continue;
-
-            // wait for private DNS setting propagating
-            mCtsNetUtils.awaitPrivateDnsSetting(msg + " wait private DNS setting timeout",
-                    network, INVALID_PRIVATE_DNS_SERVER, false);
-
-            final CountDownLatch latch = new CountDownLatch(1);
-            final DnsResolver.Callback<List<InetAddress>> errorCallback =
-                    new DnsResolver.Callback<List<InetAddress>>() {
-                        @Override
-                        public void onAnswer(@NonNull List<InetAddress> answerList, int rcode) {
-                            fail(msg + " should not get valid answer");
-                        }
-
-                        @Override
-                        public void onError(@NonNull DnsResolver.DnsException error) {
-                            assertEquals(DnsResolver.ERROR_SYSTEM, error.code);
-                            assertEquals(ETIMEDOUT, ((ErrnoException) error.getCause()).errno);
-                            latch.countDown();
-                        }
-                    };
-            // Private DNS strict mode with invalid DNS server is set
-            // Expect no valid answer returned but ErrnoException with ETIMEDOUT
-            mDns.query(network, TEST_DOMAIN, FLAG_NO_CACHE_LOOKUP, mExecutor, null, errorCallback);
-
-            assertTrue(msg + " invalid server round. No response after " + TIMEOUT_MS + "ms.",
-                    latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
-            final VerifyCancelInetAddressCallback callback =
-                    new VerifyCancelInetAddressCallback(msg, null);
-            // Bypass privateDns, expect query works fine
-            mDns.query(network.getPrivateDnsBypassingCopy(),
-                    TEST_DOMAIN, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback);
-
-            assertTrue(msg + " bypass private DNS round. No answer after " + TIMEOUT_MS + "ms.",
-                    callback.waitForAnswer());
-            callback.assertNoError();
-            assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty());
-
-            // To ensure private DNS bypass still work even if passing null network.
-            // Bind process network with a private DNS bypassable network.
-            mCM.bindProcessToNetwork(network.getPrivateDnsBypassingCopy());
-            final VerifyCancelInetAddressCallback callbackWithNullNetwork =
-                    new VerifyCancelInetAddressCallback(msg + " with null network ", null);
-            mDns.query(null,
-                    TEST_DOMAIN, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callbackWithNullNetwork);
-
-            assertTrue(msg + " with null network bypass private DNS round. No answer after " +
-                    TIMEOUT_MS + "ms.", callbackWithNullNetwork.waitForAnswer());
-            callbackWithNullNetwork.assertNoError();
-            assertTrue(msg + " with null network returned 0 results",
-                    !callbackWithNullNetwork.isAnswerEmpty());
-
-            // Reset process network to default.
-            mCM.bindProcessToNetwork(null);
-        }
-    }
-
-    public void doTestContinuousQueries(Executor executor) throws InterruptedException {
-        final String msg = "Test continuous " + QUERY_TIMES + " queries " + TEST_DOMAIN;
-        for (Network network : getTestableNetworks()) {
-            for (int i = 0; i < QUERY_TIMES ; ++i) {
-                final VerifyCancelInetAddressCallback callback =
-                        new VerifyCancelInetAddressCallback(msg, null);
-                // query v6/v4 in turn
-                boolean queryV6 = (i % 2 == 0);
-                mDns.query(network, TEST_DOMAIN, queryV6 ? TYPE_AAAA : TYPE_A,
-                        FLAG_NO_CACHE_LOOKUP, executor, null, callback);
-
-                assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
-                        callback.waitForAnswer());
-                callback.assertNoError();
-                assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty());
-                assertTrue(msg + " returned " + (queryV6 ? "Ipv4" : "Ipv6") + " results",
-                        queryV6 ? !callback.hasIpv4Answer() : !callback.hasIpv6Answer());
-            }
-        }
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/DnsTest.java b/tests/cts/net/src/android/net/cts/DnsTest.java
deleted file mode 100644
index fde27e9..0000000
--- a/tests/cts/net/src/android/net/cts/DnsTest.java
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Copyright (C) 2013 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.content.Context;
-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.NetworkInfo;
-import android.os.SystemClock;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import com.android.testutils.SkipPresubmit;
-
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-public class DnsTest extends AndroidTestCase {
-
-    static {
-        System.loadLibrary("nativedns_jni");
-    }
-
-    private static final boolean DBG = false;
-    private static final String TAG = "DnsTest";
-    private static final String PROXY_NETWORK_TYPE = "PROXY";
-
-    private ConnectivityManager mCm;
-
-    public void setUp() {
-        mCm = getContext().getSystemService(ConnectivityManager.class);
-    }
-
-    /**
-     * @return true on success
-     */
-    private static native boolean testNativeDns();
-
-    /**
-     * Verify:
-     * DNS works - forwards and backwards, giving ipv4 and ipv6
-     * Test that DNS work on v4 and v6 networks
-     * Test Native dns calls (4)
-     * Todo:
-     * Cache is flushed when we change networks
-     * have per-network caches
-     * No cache when there's no network
-     * Perf - measure size of first and second tier caches and their effect
-     * Assert requires network permission
-     */
-    @SkipPresubmit(reason = "IPv6 support may be missing on presubmit virtual hardware")
-    public void testDnsWorks() throws Exception {
-        ensureIpv6Connectivity();
-
-        InetAddress addrs[] = {};
-        try {
-            addrs = InetAddress.getAllByName("www.google.com");
-        } catch (UnknownHostException e) {}
-        assertTrue("[RERUN] DNS could not resolve www.google.com. Check internet connection",
-                addrs.length != 0);
-        boolean foundV4 = false, foundV6 = false;
-        for (InetAddress addr : addrs) {
-            if (addr instanceof Inet4Address) foundV4 = true;
-            else if (addr instanceof Inet6Address) foundV6 = true;
-            if (DBG) Log.e(TAG, "www.google.com gave " + addr.toString());
-        }
-
-        // We should have at least one of the addresses to connect!
-        assertTrue("www.google.com must have IPv4 and/or IPv6 address", foundV4 || foundV6);
-
-        // Skip the rest of the test if the active network for watch is PROXY.
-        // TODO: Check NetworkInfo type in addition to type name once ag/601257 is merged.
-        if (getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)
-                && activeNetworkInfoIsProxy()) {
-            Log.i(TAG, "Skipping test because the active network type name is PROXY.");
-            return;
-        }
-
-        // Clear test state so we don't get confused with the previous results.
-        addrs = new InetAddress[0];
-        foundV4 = foundV6 = false;
-        try {
-            addrs = InetAddress.getAllByName("ipv6.google.com");
-        } catch (UnknownHostException e) {}
-        String msg =
-            "[RERUN] DNS could not resolve ipv6.google.com, check the network supports IPv6. lp=" +
-            mCm.getActiveLinkProperties();
-        assertTrue(msg, addrs.length != 0);
-        for (InetAddress addr : addrs) {
-            msg = "[RERUN] ipv6.google.com returned IPv4 address: " + addr.getHostAddress() +
-                    ", check your network's DNS server. lp=" + mCm.getActiveLinkProperties();
-            assertFalse (msg, addr instanceof Inet4Address);
-            foundV6 |= (addr instanceof Inet6Address);
-            if (DBG) Log.e(TAG, "ipv6.google.com gave " + addr.toString());
-        }
-
-        assertTrue(foundV6);
-
-        assertTrue(testNativeDns());
-    }
-
-    private static final String[] URLS = { "www.google.com", "ipv6.google.com", "www.yahoo.com",
-            "facebook.com", "youtube.com", "blogspot.com", "baidu.com", "wikipedia.org",
-// live.com fails rev lookup.
-            "twitter.com", "qq.com", "msn.com", "yahoo.co.jp", "linkedin.com",
-            "taobao.com", "google.co.in", "sina.com.cn", "amazon.com", "wordpress.com",
-            "google.co.uk", "ebay.com", "yandex.ru", "163.com", "google.co.jp", "google.fr",
-            "microsoft.com", "paypal.com", "google.com.br", "flickr.com",
-            "mail.ru", "craigslist.org", "fc2.com", "google.it",
-// "apple.com", fails rev lookup
-            "google.es",
-            "imdb.com", "google.ru", "soho.com", "bbc.co.uk", "vkontakte.ru", "ask.com",
-            "tumblr.com", "weibo.com", "go.com", "xvideos.com", "livejasmin.com", "cnn.com",
-            "youku.com", "blogspot.com", "soso.com", "google.ca", "aol.com", "tudou.com",
-            "xhamster.com", "megaupload.com", "ifeng.com", "zedo.com", "mediafire.com", "ameblo.jp",
-            "pornhub.com", "google.co.id", "godaddy.com", "adobe.com", "rakuten.co.jp", "about.com",
-            "espn.go.com", "4shared.com", "alibaba.com","ebay.de", "yieldmanager.com",
-            "wordpress.org", "livejournal.com", "google.com.tr", "google.com.mx", "renren.com",
-           "livedoor.com", "google.com.au", "youporn.com", "uol.com.br", "cnet.com", "conduit.com",
-            "google.pl", "myspace.com", "nytimes.com", "ebay.co.uk", "chinaz.com", "hao123.com",
-            "thepiratebay.org", "doubleclick.com", "alipay.com", "netflix.com", "cnzz.com",
-            "huffingtonpost.com", "twitpic.com", "weather.com", "babylon.com", "amazon.de",
-            "dailymotion.com", "orkut.com", "orkut.com.br", "google.com.sa", "odnoklassniki.ru",
-            "amazon.co.jp", "google.nl", "goo.ne.jp", "stumbleupon.com", "tube8.com", "tmall.com",
-            "imgur.com", "globo.com", "secureserver.net", "fileserve.com", "tianya.cn", "badoo.com",
-            "ehow.com", "photobucket.com", "imageshack.us", "xnxx.com", "deviantart.com",
-            "filestube.com", "addthis.com", "douban.com", "vimeo.com", "sogou.com",
-            "stackoverflow.com", "reddit.com", "dailymail.co.uk", "redtube.com", "megavideo.com",
-            "taringa.net", "pengyou.com", "amazon.co.uk", "fbcdn.net", "aweber.com", "spiegel.de",
-            "rapidshare.com", "mixi.jp", "360buy.com", "google.cn", "digg.com", "answers.com",
-            "bit.ly", "indiatimes.com", "skype.com", "yfrog.com", "optmd.com", "google.com.eg",
-            "google.com.pk", "58.com", "hotfile.com", "google.co.th",
-            "bankofamerica.com", "sourceforge.net", "maktoob.com", "warriorforum.com", "rediff.com",
-            "google.co.za", "56.com", "torrentz.eu", "clicksor.com", "avg.com",
-            "download.com", "ku6.com", "statcounter.com", "foxnews.com", "google.com.ar",
-            "nicovideo.jp", "reference.com", "liveinternet.ru", "ucoz.ru", "xinhuanet.com",
-            "xtendmedia.com", "naver.com", "youjizz.com", "domaintools.com", "sparkstudios.com",
-            "rambler.ru", "scribd.com", "kaixin001.com", "mashable.com", "adultfirendfinder.com",
-            "files.wordpress.com", "guardian.co.uk", "bild.de", "yelp.com", "wikimedia.org",
-            "chase.com", "onet.pl", "ameba.jp", "pconline.com.cn", "free.fr", "etsy.com",
-            "typepad.com", "youdao.com", "megaclick.com", "digitalpoint.com", "blogfa.com",
-            "salesforce.com", "adf.ly", "ganji.com", "wikia.com", "archive.org", "terra.com.br",
-            "w3schools.com", "ezinearticles.com", "wjs.com", "google.com.my", "clickbank.com",
-            "squidoo.com", "hulu.com", "repubblica.it", "google.be", "allegro.pl", "comcast.net",
-            "narod.ru", "zol.com.cn", "orange.fr", "soufun.com", "hatena.ne.jp", "google.gr",
-            "in.com", "techcrunch.com", "orkut.co.in", "xunlei.com",
-            "reuters.com", "google.com.vn", "hostgator.com", "kaskus.us", "espncricinfo.com",
-            "hootsuite.com", "qiyi.com", "gmx.net", "xing.com", "php.net", "soku.com", "web.de",
-            "libero.it", "groupon.com", "51.la", "slideshare.net", "booking.com", "seesaa.net",
-            "126.com", "telegraph.co.uk", "wretch.cc", "twimg.com", "rutracker.org", "angege.com",
-            "nba.com", "dell.com", "leboncoin.fr", "people.com", "google.com.tw", "walmart.com",
-            "daum.net", "2ch.net", "constantcontact.com", "nifty.com", "mywebsearch.com",
-            "tripadvisor.com", "google.se", "paipai.com", "google.com.ua", "ning.com", "hp.com",
-            "google.at", "joomla.org", "icio.us", "hudong.com", "csdn.net", "getfirebug.com",
-            "ups.com", "cj.com", "google.ch", "camzap.com", "wordreference.com", "tagged.com",
-            "wp.pl", "mozilla.com", "google.ru", "usps.com", "china.com", "themeforest.net",
-            "search-results.com", "tribalfusion.com", "thefreedictionary.com", "isohunt.com",
-            "linkwithin.com", "cam4.com", "plentyoffish.com", "wellsfargo.com", "metacafe.com",
-            "depositfiles.com", "freelancer.com", "opendns.com", "homeway.com", "engadget.com",
-            "10086.cn", "360.cn", "marca.com", "dropbox.com", "ign.com", "match.com", "google.pt",
-            "facemoods.com", "hardsextube.com", "google.com.ph", "lockerz.com", "istockphoto.com",
-            "partypoker.com", "netlog.com", "outbrain.com", "elpais.com", "fiverr.com",
-            "biglobe.ne.jp", "corriere.it", "love21cn.com", "yesky.com", "spankwire.com",
-            "ig.com.br", "imagevenue.com", "hubpages.com", "google.co.ve"};
-
-// TODO - this works, but is slow and cts doesn't do anything with the result.
-// Maybe require a min performance, a min cache size (detectable) and/or move
-// to perf testing
-    private static final int LOOKUP_COUNT_GOAL = URLS.length;
-    public void skiptestDnsPerf() {
-        ArrayList<String> results = new ArrayList<String>();
-        int failures = 0;
-        try {
-            for (int numberOfUrls = URLS.length; numberOfUrls > 0; numberOfUrls--) {
-                failures = 0;
-                int iterationLimit = LOOKUP_COUNT_GOAL / numberOfUrls;
-                long startTime = SystemClock.elapsedRealtimeNanos();
-                for (int iteration = 0; iteration < iterationLimit; iteration++) {
-                    for (int urlIndex = 0; urlIndex < numberOfUrls; urlIndex++) {
-                        try {
-                            InetAddress addr = InetAddress.getByName(URLS[urlIndex]);
-                        } catch (UnknownHostException e) {
-                            Log.e(TAG, "failed first lookup of " + URLS[urlIndex]);
-                            failures++;
-                            try {
-                                InetAddress addr = InetAddress.getByName(URLS[urlIndex]);
-                            } catch (UnknownHostException ee) {
-                                failures++;
-                                Log.e(TAG, "failed SECOND lookup of " + URLS[urlIndex]);
-                            }
-                        }
-                    }
-                }
-                long endTime = SystemClock.elapsedRealtimeNanos();
-                float nsPer = ((float)(endTime-startTime) / iterationLimit) / numberOfUrls/ 1000;
-                String thisResult = new String("getByName for " + numberOfUrls + " took " +
-                        (endTime - startTime)/1000 + "(" + nsPer + ") with " +
-                        failures + " failures\n");
-                Log.d(TAG, thisResult);
-                results.add(thisResult);
-            }
-            // build up a list of addresses
-            ArrayList<byte[]> addressList = new ArrayList<byte[]>();
-            for (String url : URLS) {
-                try {
-                    InetAddress addr = InetAddress.getByName(url);
-                    addressList.add(addr.getAddress());
-                } catch (UnknownHostException e) {
-                    Log.e(TAG, "Exception making reverseDNS list: " + e.toString());
-                }
-            }
-            for (int numberOfAddrs = addressList.size(); numberOfAddrs > 0; numberOfAddrs--) {
-                int iterationLimit = LOOKUP_COUNT_GOAL / numberOfAddrs;
-                failures = 0;
-                long startTime = SystemClock.elapsedRealtimeNanos();
-                for (int iteration = 0; iteration < iterationLimit; iteration++) {
-                    for (int addrIndex = 0; addrIndex < numberOfAddrs; addrIndex++) {
-                        try {
-                            InetAddress addr = InetAddress.getByAddress(addressList.get(addrIndex));
-                            String hostname = addr.getHostName();
-                        } catch (UnknownHostException e) {
-                            failures++;
-                            Log.e(TAG, "Failure doing reverse DNS lookup: " + e.toString());
-                            try {
-                                InetAddress addr =
-                                        InetAddress.getByAddress(addressList.get(addrIndex));
-                                String hostname = addr.getHostName();
-
-                            } catch (UnknownHostException ee) {
-                                failures++;
-                                Log.e(TAG, "Failure doing SECOND reverse DNS lookup: " +
-                                        ee.toString());
-                            }
-                        }
-                    }
-                }
-                long endTime = SystemClock.elapsedRealtimeNanos();
-                float nsPer = ((endTime-startTime) / iterationLimit) / numberOfAddrs / 1000;
-                String thisResult = new String("getHostName for " + numberOfAddrs + " took " +
-                        (endTime - startTime)/1000 + "(" + nsPer + ") with " +
-                        failures + " failures\n");
-                Log.d(TAG, thisResult);
-                results.add(thisResult);
-            }
-            for (String result : results) Log.d(TAG, result);
-
-            InetAddress exit = InetAddress.getByName("exitrightnow.com");
-            Log.e(TAG, " exit address= "+exit.toString());
-
-        } catch (Exception e) {
-            Log.e(TAG, "bad URL in testDnsPerf: " + e.toString());
-        }
-    }
-
-    private boolean activeNetworkInfoIsProxy() {
-        NetworkInfo info = mCm.getActiveNetworkInfo();
-        if (PROXY_NETWORK_TYPE.equals(info.getTypeName())) {
-            return true;
-        }
-
-        return false;
-    }
-
-    private void ensureIpv6Connectivity() throws InterruptedException {
-        CountDownLatch latch = new CountDownLatch(1);
-        final int TIMEOUT_MS = 5_000;
-
-        final NetworkCallback callback = new NetworkCallback() {
-            @Override
-            public void onLinkPropertiesChanged(Network network, LinkProperties lp) {
-                if (lp.hasGlobalIpv6Address()) {
-                    latch.countDown();
-                }
-            }
-        };
-        mCm.registerDefaultNetworkCallback(callback);
-
-        String msg = "Default network did not provide IPv6 connectivity after " + TIMEOUT_MS
-                + "ms. Please connect to an IPv6-capable network. lp="
-                + mCm.getActiveLinkProperties();
-        try {
-            assertTrue(msg, latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        } finally {
-            mCm.unregisterNetworkCallback(callback);
-        }
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/IkeTunUtils.java b/tests/cts/net/src/android/net/cts/IkeTunUtils.java
deleted file mode 100644
index fc25292..0000000
--- a/tests/cts/net/src/android/net/cts/IkeTunUtils.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net.cts;
-
-import static android.net.cts.PacketUtils.BytePayload;
-import static android.net.cts.PacketUtils.IP4_HDRLEN;
-import static android.net.cts.PacketUtils.IP6_HDRLEN;
-import static android.net.cts.PacketUtils.IpHeader;
-import static android.net.cts.PacketUtils.UDP_HDRLEN;
-import static android.net.cts.PacketUtils.UdpHeader;
-import static android.net.cts.PacketUtils.getIpHeader;
-import static android.system.OsConstants.IPPROTO_UDP;
-
-import android.os.ParcelFileDescriptor;
-
-import java.net.InetAddress;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-// TODO: Merge this with the version in the IPsec module (IKEv2 library) CTS tests.
-/** An extension of the TunUtils class with IKE-specific packet handling. */
-public class IkeTunUtils extends TunUtils {
-    private static final int PORT_LEN = 2;
-
-    private static final byte[] NON_ESP_MARKER = new byte[] {0, 0, 0, 0};
-
-    private static final int IKE_HEADER_LEN = 28;
-    private static final int IKE_SPI_LEN = 8;
-    private static final int IKE_IS_RESP_BYTE_OFFSET = 19;
-    private static final int IKE_MSG_ID_OFFSET = 20;
-    private static final int IKE_MSG_ID_LEN = 4;
-
-    public IkeTunUtils(ParcelFileDescriptor tunFd) {
-        super(tunFd);
-    }
-
-    /**
-     * Await an expected IKE request and inject an IKE response.
-     *
-     * @param respIkePkt IKE response packet without IP/UDP headers or NON ESP MARKER.
-     */
-    public byte[] awaitReqAndInjectResp(long expectedInitIkeSpi, int expectedMsgId,
-            boolean encapExpected, byte[] respIkePkt) throws Exception {
-        final byte[] request = awaitIkePacket(expectedInitIkeSpi, expectedMsgId, encapExpected);
-
-        // Build response header by flipping address and port
-        final InetAddress srcAddr = getDstAddress(request);
-        final InetAddress dstAddr = getSrcAddress(request);
-        final int srcPort = getDstPort(request);
-        final int dstPort = getSrcPort(request);
-
-        final byte[] response =
-                buildIkePacket(srcAddr, dstAddr, srcPort, dstPort, encapExpected, respIkePkt);
-        injectPacket(response);
-        return request;
-    }
-
-    private byte[] awaitIkePacket(long expectedInitIkeSpi, int expectedMsgId, boolean expectEncap)
-            throws Exception {
-        return super.awaitPacket(pkt -> isIke(pkt, expectedInitIkeSpi, expectedMsgId, expectEncap));
-    }
-
-    private static boolean isIke(
-            byte[] pkt, long expectedInitIkeSpi, int expectedMsgId, boolean encapExpected) {
-        final int ipProtocolOffset;
-        final int ikeOffset;
-
-        if (isIpv6(pkt)) {
-            ipProtocolOffset = IP6_PROTO_OFFSET;
-            ikeOffset = IP6_HDRLEN + UDP_HDRLEN;
-        } else {
-            if (encapExpected && !hasNonEspMarkerv4(pkt)) {
-                return false;
-            }
-
-            // Use default IPv4 header length (assuming no options)
-            final int encapMarkerLen = encapExpected ? NON_ESP_MARKER.length : 0;
-            ipProtocolOffset = IP4_PROTO_OFFSET;
-            ikeOffset = IP4_HDRLEN + UDP_HDRLEN + encapMarkerLen;
-        }
-
-        return pkt[ipProtocolOffset] == IPPROTO_UDP
-                && areSpiAndMsgIdEqual(pkt, ikeOffset, expectedInitIkeSpi, expectedMsgId);
-    }
-
-    /** Checks if the provided IPv4 packet has a UDP-encapsulation NON-ESP marker */
-    private static boolean hasNonEspMarkerv4(byte[] ipv4Pkt) {
-        final int nonEspMarkerOffset = IP4_HDRLEN + UDP_HDRLEN;
-        if (ipv4Pkt.length < nonEspMarkerOffset + NON_ESP_MARKER.length) {
-            return false;
-        }
-
-        final byte[] nonEspMarker = Arrays.copyOfRange(
-                ipv4Pkt, nonEspMarkerOffset, nonEspMarkerOffset + NON_ESP_MARKER.length);
-        return Arrays.equals(NON_ESP_MARKER, nonEspMarker);
-    }
-
-    private static boolean areSpiAndMsgIdEqual(
-            byte[] pkt, int ikeOffset, long expectedIkeInitSpi, int expectedMsgId) {
-        if (pkt.length <= ikeOffset + IKE_HEADER_LEN) {
-            return false;
-        }
-
-        final ByteBuffer buffer = ByteBuffer.wrap(pkt);
-        final long spi = buffer.getLong(ikeOffset);
-        final int msgId = buffer.getInt(ikeOffset + IKE_MSG_ID_OFFSET);
-
-        return expectedIkeInitSpi == spi && expectedMsgId == msgId;
-    }
-
-    private static InetAddress getSrcAddress(byte[] pkt) throws Exception {
-        return getAddress(pkt, true);
-    }
-
-    private static InetAddress getDstAddress(byte[] pkt) throws Exception {
-        return getAddress(pkt, false);
-    }
-
-    private static InetAddress getAddress(byte[] pkt, boolean getSrcAddr) throws Exception {
-        final int ipLen = isIpv6(pkt) ? IP6_ADDR_LEN : IP4_ADDR_LEN;
-        final int srcIpOffset = isIpv6(pkt) ? IP6_ADDR_OFFSET : IP4_ADDR_OFFSET;
-        final int ipOffset = getSrcAddr ? srcIpOffset : srcIpOffset + ipLen;
-
-        if (pkt.length < ipOffset + ipLen) {
-            // Should be impossible; getAddress() is only called with a full IKE request including
-            // the IP and UDP headers.
-            throw new IllegalArgumentException("Packet was too short to contain IP address");
-        }
-
-        return InetAddress.getByAddress(Arrays.copyOfRange(pkt, ipOffset, ipOffset + ipLen));
-    }
-
-    private static int getSrcPort(byte[] pkt) throws Exception {
-        return getPort(pkt, true);
-    }
-
-    private static int getDstPort(byte[] pkt) throws Exception {
-        return getPort(pkt, false);
-    }
-
-    private static int getPort(byte[] pkt, boolean getSrcPort) {
-        final int srcPortOffset = isIpv6(pkt) ? IP6_HDRLEN : IP4_HDRLEN;
-        final int portOffset = getSrcPort ? srcPortOffset : srcPortOffset + PORT_LEN;
-
-        if (pkt.length < portOffset + PORT_LEN) {
-            // Should be impossible; getPort() is only called with a full IKE request including the
-            // IP and UDP headers.
-            throw new IllegalArgumentException("Packet was too short to contain port");
-        }
-
-        final ByteBuffer buffer = ByteBuffer.wrap(pkt);
-        return Short.toUnsignedInt(buffer.getShort(portOffset));
-    }
-
-    private static byte[] buildIkePacket(
-            InetAddress srcAddr,
-            InetAddress dstAddr,
-            int srcPort,
-            int dstPort,
-            boolean useEncap,
-            byte[] payload)
-            throws Exception {
-        // Append non-ESP marker if encap is enabled
-        if (useEncap) {
-            final ByteBuffer buffer = ByteBuffer.allocate(NON_ESP_MARKER.length + payload.length);
-            buffer.put(NON_ESP_MARKER);
-            buffer.put(payload);
-            payload = buffer.array();
-        }
-
-        final UdpHeader udpPkt = new UdpHeader(srcPort, dstPort, new BytePayload(payload));
-        final IpHeader ipPkt = getIpHeader(udpPkt.getProtocolId(), srcAddr, dstAddr, udpPkt);
-        return ipPkt.getPacketBytes();
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/Ikev2VpnTest.java b/tests/cts/net/src/android/net/cts/Ikev2VpnTest.java
deleted file mode 100644
index 9eab024..0000000
--- a/tests/cts/net/src/android/net/cts/Ikev2VpnTest.java
+++ /dev/null
@@ -1,535 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
-import static android.net.NetworkCapabilities.TRANSPORT_VPN;
-import static android.net.cts.util.CtsNetUtils.TestNetworkCallback;
-
-import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.app.AppOpsManager;
-import android.content.Context;
-import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.net.Ikev2VpnProfile;
-import android.net.IpSecAlgorithm;
-import android.net.LinkAddress;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.net.ProxyInfo;
-import android.net.TestNetworkInterface;
-import android.net.TestNetworkManager;
-import android.net.VpnManager;
-import android.net.cts.util.CtsNetUtils;
-import android.os.Build;
-import android.os.Process;
-import android.platform.test.annotations.AppModeFull;
-
-import androidx.test.InstrumentationRegistry;
-
-import com.android.internal.util.HexDump;
-import com.android.org.bouncycastle.x509.X509V1CertificateGenerator;
-import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
-import com.android.testutils.DevSdkIgnoreRunner;
-
-import org.junit.After;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.math.BigInteger;
-import java.net.InetAddress;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import javax.security.auth.x500.X500Principal;
-
-@RunWith(DevSdkIgnoreRunner.class)
-@IgnoreUpTo(Build.VERSION_CODES.Q)
-@AppModeFull(reason = "Appops state changes disallowed for instant apps (OP_ACTIVATE_PLATFORM_VPN)")
-public class Ikev2VpnTest {
-    private static final String TAG = Ikev2VpnTest.class.getSimpleName();
-
-    // Test vectors for IKE negotiation in test mode.
-    private static final String SUCCESSFUL_IKE_INIT_RESP_V4 =
-            "46b8eca1e0d72a18b2b5d9006d47a0022120222000000000000002d0220000300000002c01010004030000"
-                    + "0c0100000c800e0100030000080300000c030000080200000400000008040000102800020800"
-                    + "100000b8070f159fe5141d8754ca86f72ecc28d66f514927e96cbe9eec0adb42bf2c276a0ab7"
-                    + "a97fa93555f4be9218c14e7f286bb28c6b4fb13825a420f2ffc165854f200bab37d69c8963d4"
-                    + "0acb831d983163aa50622fd35c182efe882cf54d6106222abcfaa597255d302f1b95ab71c142"
-                    + "c279ea5839a180070bff73f9d03fab815f0d5ee2adec7e409d1e35979f8bd92ffd8aab13d1a0"
-                    + "0657d816643ae767e9ae84d2ccfa2bcce1a50572be8d3748ae4863c41ae90da16271e014270f"
-                    + "77edd5cd2e3299f3ab27d7203f93d770bacf816041cdcecd0f9af249033979da4369cb242dd9"
-                    + "6d172e60513ff3db02de63e50eb7d7f596ada55d7946cad0af0669d1f3e2804846ab3f2a930d"
-                    + "df56f7f025f25c25ada694e6231abbb87ee8cfd072c8481dc0b0f6b083fdc3bd89b080e49feb"
-                    + "0288eef6fdf8a26ee2fc564a11e7385215cf2deaf2a9965638fc279c908ccdf04094988d91a2"
-                    + "464b4a8c0326533aff5119ed79ecbd9d99a218b44f506a5eb09351e67da86698b4c58718db25"
-                    + "d55f426fb4c76471b27a41fbce00777bc233c7f6e842e39146f466826de94f564cad8b92bfbe"
-                    + "87c99c4c7973ec5f1eea8795e7da82819753aa7c4fcfdab77066c56b939330c4b0d354c23f83"
-                    + "ea82fa7a64c4b108f1188379ea0eb4918ee009d804100e6bf118771b9058d42141c847d5ec37"
-                    + "6e5ec591c71fc9dac01063c2bd31f9c783b28bf1182900002430f3d5de3449462b31dd28bc27"
-                    + "297b6ad169bccce4f66c5399c6e0be9120166f2900001c0000400428b8df2e66f69c8584a186"
-                    + "c5eac66783551d49b72900001c000040054e7a622e802d5cbfb96d5f30a6e433994370173529"
-                    + "0000080000402e290000100000402f00020003000400050000000800004014";
-    private static final String SUCCESSFUL_IKE_INIT_RESP_V6 =
-            "46b8eca1e0d72a1800d9ea1babce26bf2120222000000000000002d0220000300000002c01010004030000"
-                    + "0c0100000c800e0100030000080300000c030000080200000400000008040000102800020800"
-                    + "100000ea0e6dd9ca5930a9a45c323a41f64bfd8cdef7730f5fbff37d7c377da427f489a42aa8"
-                    + "c89233380e6e925990d49de35c2cdcf63a61302c731a4b3569df1ee1bf2457e55a6751838ede"
-                    + "abb75cc63ba5c9e4355e8e784f383a5efe8a44727dc14aeaf8dacc2620fb1c8875416dc07739"
-                    + "7fe4decc1bd514a9c7d270cf21fd734c63a25c34b30b68686e54e8a198f37f27cb491fe27235"
-                    + "fab5476b036d875ccab9a68d65fbf3006197f9bebbf94de0d3802b4fafe1d48d931ce3a1a346"
-                    + "2d65bd639e9bd7fa46299650a9dbaf9b324e40b466942d91a59f41ef8042f8474c4850ed0f63"
-                    + "e9238949d41cd8bbaea9aefdb65443a6405792839563aa5dc5c36b5ce8326ccf8a94d9622b85"
-                    + "038d390d5fc0299e14e1f022966d4ac66515f6108ca04faec44821fe5bbf2ed4f84ff5671219"
-                    + "608cb4c36b44a31ba010c9088f8d5ff943bb9ff857f74be1755f57a5783874adc57f42bb174e"
-                    + "4ad3215de628707014dbcb1707bd214658118fdd7a42b3e1638b991ce5b812a667f1145be811"
-                    + "685e3cd3baf9b18d062657b64c206a4d19a531c252a6a51a04aeaf42c618620cdbab65baca23"
-                    + "82c57ed888422aeaacf7f1bc3fe2247ff7e7eaca218b74d7b31d02f2b0afa123f802529e7e6c"
-                    + "3259d418290740ddbf55686e26998d7edcbbf895664972fed666f2f20af40503aa2af436ec6d"
-                    + "4ec981ab19b9088755d94ae7a7c2066ea331d4e56e290000243fefe5555fce552d57a84e682c"
-                    + "d4a6dfb3f2f94a94464d5bec3d88b88e9559642900001c00004004eb4afff764e7b79bca78b1"
-                    + "3a89100d36d678ae982900001c00004005d177216a3c26f782076e12570d40bfaaa148822929"
-                    + "0000080000402e290000100000402f00020003000400050000000800004014";
-    private static final String SUCCESSFUL_IKE_AUTH_RESP_V4 =
-            "46b8eca1e0d72a18b2b5d9006d47a0022e20232000000001000000e0240000c420a2500a3da4c66fa6929e"
-                    + "600f36349ba0e38de14f78a3ad0416cba8c058735712a3d3f9a0a6ed36de09b5e9e02697e7c4"
-                    + "2d210ac86cfbd709503cfa51e2eab8cfdc6427d136313c072968f6506a546eb5927164200592"
-                    + "6e36a16ee994e63f029432a67bc7d37ca619e1bd6e1678df14853067ecf816b48b81e8746069"
-                    + "406363e5aa55f13cb2afda9dbebee94256c29d630b17dd7f1ee52351f92b6e1c3d8551c513f1"
-                    + "d74ac52a80b2041397e109fe0aeb3c105b0d4be0ae343a943398764281";
-    private static final String SUCCESSFUL_IKE_AUTH_RESP_V6 =
-            "46b8eca1e0d72a1800d9ea1babce26bf2e20232000000001000000f0240000d4aaf6eaa6c06b50447e6f54"
-                    + "827fd8a9d9d6ac8015c1ebb3e8cb03fc6e54b49a107441f50004027cc5021600828026367f03"
-                    + "bc425821cd7772ee98637361300c9b76056e874fea2bd4a17212370b291894264d8c023a01d1"
-                    + "c3b691fd4b7c0b534e8c95af4c4638e2d125cb21c6267e2507cd745d72e8da109c47b9259c6c"
-                    + "57a26f6bc5b337b9b9496d54bdde0333d7a32e6e1335c9ee730c3ecd607a8689aa7b0577b74f"
-                    + "3bf437696a9fd5fc0aee3ed346cd9e15d1dda293df89eb388a8719388a60ca7625754de12cdb"
-                    + "efe4c886c5c401";
-    private static final long IKE_INITIATOR_SPI = Long.parseLong("46B8ECA1E0D72A18", 16);
-
-    private static final InetAddress LOCAL_OUTER_4 = InetAddress.parseNumericAddress("192.0.2.1");
-    private static final InetAddress LOCAL_OUTER_6 =
-            InetAddress.parseNumericAddress("2001:db8::1");
-
-    private static final int IP4_PREFIX_LEN = 32;
-    private static final int IP6_PREFIX_LEN = 128;
-
-    // TODO: Use IPv6 address when we can generate test vectors (GCE does not allow IPv6 yet).
-    private static final String TEST_SERVER_ADDR_V4 = "192.0.2.2";
-    private static final String TEST_SERVER_ADDR_V6 = "2001:db8::2";
-    private static final String TEST_IDENTITY = "client.cts.android.com";
-    private static final List<String> TEST_ALLOWED_ALGORITHMS =
-            Arrays.asList(IpSecAlgorithm.AUTH_CRYPT_AES_GCM);
-
-    private static final ProxyInfo TEST_PROXY_INFO =
-            ProxyInfo.buildDirectProxy("proxy.cts.android.com", 1234);
-    private static final int TEST_MTU = 1300;
-
-    private static final byte[] TEST_PSK = "ikeAndroidPsk".getBytes();
-    private static final String TEST_USER = "username";
-    private static final String TEST_PASSWORD = "pa55w0rd";
-
-    // Static state to reduce setup/teardown
-    private static final Context sContext = InstrumentationRegistry.getContext();
-    private static final ConnectivityManager sCM =
-            (ConnectivityManager) sContext.getSystemService(Context.CONNECTIVITY_SERVICE);
-    private static final VpnManager sVpnMgr =
-            (VpnManager) sContext.getSystemService(Context.VPN_MANAGEMENT_SERVICE);
-    private static final CtsNetUtils mCtsNetUtils = new CtsNetUtils(sContext);
-
-    private final X509Certificate mServerRootCa;
-    private final CertificateAndKey mUserCertKey;
-
-    public Ikev2VpnTest() throws Exception {
-        // Build certificates
-        mServerRootCa = generateRandomCertAndKeyPair().cert;
-        mUserCertKey = generateRandomCertAndKeyPair();
-    }
-
-    @After
-    public void tearDown() {
-        setAppop(AppOpsManager.OP_ACTIVATE_VPN, false);
-        setAppop(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN, false);
-    }
-
-    /**
-     * Sets the given appop using shell commands
-     *
-     * <p>This method must NEVER be called from within a shell permission, as it will attempt to
-     * acquire, and then drop the shell permission identity. This results in the caller losing the
-     * shell permission identity due to these calls not being reference counted.
-     */
-    public void setAppop(int appop, boolean allow) {
-        // Requires shell permission to update appops.
-        runWithShellPermissionIdentity(() -> {
-            mCtsNetUtils.setAppopPrivileged(appop, allow);
-        }, Manifest.permission.MANAGE_TEST_NETWORKS);
-    }
-
-    private Ikev2VpnProfile buildIkev2VpnProfileCommon(
-            Ikev2VpnProfile.Builder builder, boolean isRestrictedToTestNetworks) throws Exception {
-        if (isRestrictedToTestNetworks) {
-            builder.restrictToTestNetworks();
-        }
-
-        return builder.setBypassable(true)
-                .setAllowedAlgorithms(TEST_ALLOWED_ALGORITHMS)
-                .setProxy(TEST_PROXY_INFO)
-                .setMaxMtu(TEST_MTU)
-                .setMetered(false)
-                .build();
-    }
-
-    private Ikev2VpnProfile buildIkev2VpnProfilePsk(boolean isRestrictedToTestNetworks)
-            throws Exception {
-        return buildIkev2VpnProfilePsk(TEST_SERVER_ADDR_V6, isRestrictedToTestNetworks);
-    }
-
-    private Ikev2VpnProfile buildIkev2VpnProfilePsk(
-            String remote, boolean isRestrictedToTestNetworks) throws Exception {
-        final Ikev2VpnProfile.Builder builder =
-                new Ikev2VpnProfile.Builder(remote, TEST_IDENTITY).setAuthPsk(TEST_PSK);
-
-        return buildIkev2VpnProfileCommon(builder, isRestrictedToTestNetworks);
-    }
-
-    private Ikev2VpnProfile buildIkev2VpnProfileUsernamePassword(boolean isRestrictedToTestNetworks)
-            throws Exception {
-        final Ikev2VpnProfile.Builder builder =
-                new Ikev2VpnProfile.Builder(TEST_SERVER_ADDR_V6, TEST_IDENTITY)
-                        .setAuthUsernamePassword(TEST_USER, TEST_PASSWORD, mServerRootCa);
-
-        return buildIkev2VpnProfileCommon(builder, isRestrictedToTestNetworks);
-    }
-
-    private Ikev2VpnProfile buildIkev2VpnProfileDigitalSignature(boolean isRestrictedToTestNetworks)
-            throws Exception {
-        final Ikev2VpnProfile.Builder builder =
-                new Ikev2VpnProfile.Builder(TEST_SERVER_ADDR_V6, TEST_IDENTITY)
-                        .setAuthDigitalSignature(
-                                mUserCertKey.cert, mUserCertKey.key, mServerRootCa);
-
-        return buildIkev2VpnProfileCommon(builder, isRestrictedToTestNetworks);
-    }
-
-    private void checkBasicIkev2VpnProfile(@NonNull Ikev2VpnProfile profile) throws Exception {
-        assertEquals(TEST_SERVER_ADDR_V6, profile.getServerAddr());
-        assertEquals(TEST_IDENTITY, profile.getUserIdentity());
-        assertEquals(TEST_PROXY_INFO, profile.getProxyInfo());
-        assertEquals(TEST_ALLOWED_ALGORITHMS, profile.getAllowedAlgorithms());
-        assertTrue(profile.isBypassable());
-        assertFalse(profile.isMetered());
-        assertEquals(TEST_MTU, profile.getMaxMtu());
-        assertFalse(profile.isRestrictedToTestNetworks());
-    }
-
-    @Test
-    public void testBuildIkev2VpnProfilePsk() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-
-        final Ikev2VpnProfile profile =
-                buildIkev2VpnProfilePsk(false /* isRestrictedToTestNetworks */);
-
-        checkBasicIkev2VpnProfile(profile);
-        assertArrayEquals(TEST_PSK, profile.getPresharedKey());
-
-        // Verify nothing else is set.
-        assertNull(profile.getUsername());
-        assertNull(profile.getPassword());
-        assertNull(profile.getServerRootCaCert());
-        assertNull(profile.getRsaPrivateKey());
-        assertNull(profile.getUserCert());
-    }
-
-    @Test
-    public void testBuildIkev2VpnProfileUsernamePassword() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-
-        final Ikev2VpnProfile profile =
-                buildIkev2VpnProfileUsernamePassword(false /* isRestrictedToTestNetworks */);
-
-        checkBasicIkev2VpnProfile(profile);
-        assertEquals(TEST_USER, profile.getUsername());
-        assertEquals(TEST_PASSWORD, profile.getPassword());
-        assertEquals(mServerRootCa, profile.getServerRootCaCert());
-
-        // Verify nothing else is set.
-        assertNull(profile.getPresharedKey());
-        assertNull(profile.getRsaPrivateKey());
-        assertNull(profile.getUserCert());
-    }
-
-    @Test
-    public void testBuildIkev2VpnProfileDigitalSignature() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-
-        final Ikev2VpnProfile profile =
-                buildIkev2VpnProfileDigitalSignature(false /* isRestrictedToTestNetworks */);
-
-        checkBasicIkev2VpnProfile(profile);
-        assertEquals(mUserCertKey.cert, profile.getUserCert());
-        assertEquals(mUserCertKey.key, profile.getRsaPrivateKey());
-        assertEquals(mServerRootCa, profile.getServerRootCaCert());
-
-        // Verify nothing else is set.
-        assertNull(profile.getUsername());
-        assertNull(profile.getPassword());
-        assertNull(profile.getPresharedKey());
-    }
-
-    private void verifyProvisionVpnProfile(
-            boolean hasActivateVpn, boolean hasActivatePlatformVpn, boolean expectIntent)
-            throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-
-        setAppop(AppOpsManager.OP_ACTIVATE_VPN, hasActivateVpn);
-        setAppop(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN, hasActivatePlatformVpn);
-
-        final Ikev2VpnProfile profile =
-                buildIkev2VpnProfilePsk(false /* isRestrictedToTestNetworks */);
-        final Intent intent = sVpnMgr.provisionVpnProfile(profile);
-        assertEquals(expectIntent, intent != null);
-    }
-
-    @Test
-    public void testProvisionVpnProfileNoPreviousConsent() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-
-        verifyProvisionVpnProfile(false /* hasActivateVpn */,
-                false /* hasActivatePlatformVpn */, true /* expectIntent */);
-    }
-
-    @Test
-    public void testProvisionVpnProfilePlatformVpnConsented() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-
-        verifyProvisionVpnProfile(false /* hasActivateVpn */,
-                true /* hasActivatePlatformVpn */, false /* expectIntent */);
-    }
-
-    @Test
-    public void testProvisionVpnProfileVpnServiceConsented() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-
-        verifyProvisionVpnProfile(true /* hasActivateVpn */,
-                false /* hasActivatePlatformVpn */, false /* expectIntent */);
-    }
-
-    @Test
-    public void testProvisionVpnProfileAllPreConsented() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-
-        verifyProvisionVpnProfile(true /* hasActivateVpn */,
-                true /* hasActivatePlatformVpn */, false /* expectIntent */);
-    }
-
-    @Test
-    public void testDeleteVpnProfile() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-
-        setAppop(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN, true);
-
-        final Ikev2VpnProfile profile =
-                buildIkev2VpnProfilePsk(false /* isRestrictedToTestNetworks */);
-        assertNull(sVpnMgr.provisionVpnProfile(profile));
-
-        // Verify that deleting the profile works (even without the appop)
-        setAppop(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN, false);
-        sVpnMgr.deleteProvisionedVpnProfile();
-
-        // Test that the profile was deleted - starting it should throw an IAE.
-        try {
-            setAppop(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN, true);
-            sVpnMgr.startProvisionedVpnProfile();
-            fail("Expected IllegalArgumentException due to missing profile");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    @Test
-    public void testStartVpnProfileNoPreviousConsent() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-
-        setAppop(AppOpsManager.OP_ACTIVATE_VPN, false);
-        setAppop(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN, false);
-
-        // Make sure the VpnProfile is not provisioned already.
-        sVpnMgr.stopProvisionedVpnProfile();
-
-        try {
-            sVpnMgr.startProvisionedVpnProfile();
-            fail("Expected SecurityException for missing consent");
-        } catch (SecurityException expected) {
-        }
-    }
-
-    private void checkStartStopVpnProfileBuildsNetworks(IkeTunUtils tunUtils, boolean testIpv6)
-            throws Exception {
-        String serverAddr = testIpv6 ? TEST_SERVER_ADDR_V6 : TEST_SERVER_ADDR_V4;
-        String initResp = testIpv6 ? SUCCESSFUL_IKE_INIT_RESP_V6 : SUCCESSFUL_IKE_INIT_RESP_V4;
-        String authResp = testIpv6 ? SUCCESSFUL_IKE_AUTH_RESP_V6 : SUCCESSFUL_IKE_AUTH_RESP_V4;
-        boolean hasNat = !testIpv6;
-
-        // Requires MANAGE_TEST_NETWORKS to provision a test-mode profile.
-        mCtsNetUtils.setAppopPrivileged(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN, true);
-
-        final Ikev2VpnProfile profile =
-                buildIkev2VpnProfilePsk(serverAddr, true /* isRestrictedToTestNetworks */);
-        assertNull(sVpnMgr.provisionVpnProfile(profile));
-
-        sVpnMgr.startProvisionedVpnProfile();
-
-        // Inject IKE negotiation
-        int expectedMsgId = 0;
-        tunUtils.awaitReqAndInjectResp(IKE_INITIATOR_SPI, expectedMsgId++, false /* isEncap */,
-                HexDump.hexStringToByteArray(initResp));
-        tunUtils.awaitReqAndInjectResp(IKE_INITIATOR_SPI, expectedMsgId++, hasNat /* isEncap */,
-                HexDump.hexStringToByteArray(authResp));
-
-        // Verify the VPN network came up
-        final NetworkRequest nr = new NetworkRequest.Builder()
-                .clearCapabilities().addTransportType(TRANSPORT_VPN).build();
-
-        final TestNetworkCallback cb = new TestNetworkCallback();
-        sCM.requestNetwork(nr, cb);
-        cb.waitForAvailable();
-        final Network vpnNetwork = cb.currentNetwork;
-        assertNotNull(vpnNetwork);
-
-        final NetworkCapabilities caps = sCM.getNetworkCapabilities(vpnNetwork);
-        assertTrue(caps.hasTransport(TRANSPORT_VPN));
-        assertTrue(caps.hasCapability(NET_CAPABILITY_INTERNET));
-        assertEquals(Process.myUid(), caps.getOwnerUid());
-
-        sVpnMgr.stopProvisionedVpnProfile();
-        cb.waitForLost();
-        assertEquals(vpnNetwork, cb.lastLostNetwork);
-    }
-
-    private void doTestStartStopVpnProfile(boolean testIpv6) throws Exception {
-        // Non-final; these variables ensure we clean up properly after our test if we have
-        // allocated test network resources
-        final TestNetworkManager tnm = sContext.getSystemService(TestNetworkManager.class);
-        TestNetworkInterface testIface = null;
-        TestNetworkCallback tunNetworkCallback = null;
-
-        try {
-            // Build underlying test network
-            testIface = tnm.createTunInterface(
-                    new LinkAddress[] {
-                            new LinkAddress(LOCAL_OUTER_4, IP4_PREFIX_LEN),
-                            new LinkAddress(LOCAL_OUTER_6, IP6_PREFIX_LEN)});
-
-            // Hold on to this callback to ensure network does not get reaped.
-            tunNetworkCallback = mCtsNetUtils.setupAndGetTestNetwork(
-                    testIface.getInterfaceName());
-            final IkeTunUtils tunUtils = new IkeTunUtils(testIface.getFileDescriptor());
-
-            checkStartStopVpnProfileBuildsNetworks(tunUtils, testIpv6);
-        } finally {
-            // Make sure to stop the VPN profile. This is safe to call multiple times.
-            sVpnMgr.stopProvisionedVpnProfile();
-
-            if (testIface != null) {
-                testIface.getFileDescriptor().close();
-            }
-
-            if (tunNetworkCallback != null) {
-                sCM.unregisterNetworkCallback(tunNetworkCallback);
-            }
-
-            final Network testNetwork = tunNetworkCallback.currentNetwork;
-            if (testNetwork != null) {
-                tnm.teardownTestNetwork(testNetwork);
-            }
-        }
-    }
-
-    @Test
-    public void testStartStopVpnProfileV4() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-
-        // Requires shell permission to update appops.
-        runWithShellPermissionIdentity(() -> {
-            doTestStartStopVpnProfile(false);
-        });
-    }
-
-    @Test
-    public void testStartStopVpnProfileV6() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-
-        // Requires shell permission to update appops.
-        runWithShellPermissionIdentity(() -> {
-            doTestStartStopVpnProfile(true);
-        });
-    }
-
-    private static class CertificateAndKey {
-        public final X509Certificate cert;
-        public final PrivateKey key;
-
-        CertificateAndKey(X509Certificate cert, PrivateKey key) {
-            this.cert = cert;
-            this.key = key;
-        }
-    }
-
-    private static CertificateAndKey generateRandomCertAndKeyPair() throws Exception {
-        final Date validityBeginDate =
-                new Date(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1L));
-        final Date validityEndDate =
-                new Date(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1L));
-
-        // Generate a keypair
-        final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
-        keyPairGenerator.initialize(512);
-        final KeyPair keyPair = keyPairGenerator.generateKeyPair();
-
-        final X500Principal dnName = new X500Principal("CN=test.android.com");
-        final X509V1CertificateGenerator certGen = new X509V1CertificateGenerator();
-        certGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
-        certGen.setSubjectDN(dnName);
-        certGen.setIssuerDN(dnName);
-        certGen.setNotBefore(validityBeginDate);
-        certGen.setNotAfter(validityEndDate);
-        certGen.setPublicKey(keyPair.getPublic());
-        certGen.setSignatureAlgorithm("SHA256WithRSAEncryption");
-
-        final X509Certificate cert = certGen.generate(keyPair.getPrivate(), "AndroidOpenSSL");
-        return new CertificateAndKey(cert, keyPair.getPrivate());
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/InetAddressesTest.java b/tests/cts/net/src/android/net/cts/InetAddressesTest.java
deleted file mode 100644
index 7837ce9..0000000
--- a/tests/cts/net/src/android/net/cts/InetAddressesTest.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * 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.net.InetAddresses;
-import java.net.InetAddress;
-import junitparams.JUnitParamsRunner;
-import junitparams.Parameters;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-@RunWith(JUnitParamsRunner.class)
-public class InetAddressesTest {
-
-    public static String[][] validNumericAddressesAndStringRepresentation() {
-        return new String[][] {
-            // Regular IPv4.
-            { "1.2.3.4", "1.2.3.4" },
-
-            // Regular IPv6.
-            { "2001:4860:800d::68", "2001:4860:800d::68" },
-            { "1234:5678::9ABC:DEF0", "1234:5678::9abc:def0" },
-            { "2001:cdba:9abc:5678::", "2001:cdba:9abc:5678::" },
-            { "::2001:cdba:9abc:5678", "::2001:cdba:9abc:5678" },
-            { "64:ff9b::1.2.3.4", "64:ff9b::102:304" },
-
-            { "::9abc:5678", "::154.188.86.120" },
-
-            // Mapped IPv4
-            { "::ffff:127.0.0.1", "127.0.0.1" },
-
-            // Android does not recognize Octal (leading 0) cases: they are treated as decimal.
-            { "0177.00.00.01", "177.0.0.1" },
-
-            // Verify that examples from JavaDoc work correctly.
-            { "192.0.2.1", "192.0.2.1" },
-            { "2001:db8::1:2", "2001:db8::1:2" },
-        };
-    }
-
-    public static String[] invalidNumericAddresses() {
-        return new String[] {
-            "",
-            " ",
-            "\t",
-            "\n",
-            "1.2.3.4.",
-            "1.2.3",
-            "1.2",
-            "1",
-            "1234",
-            "0",
-            "0x1.0x2.0x3.0x4",
-            "0x7f.0x00.0x00.0x01",
-            "0256.00.00.01",
-            "fred",
-            "www.google.com",
-            // IPv6 encoded for use in URL as defined in RFC 2732
-            "[fe80::6:2222]",
-        };
-    }
-
-    @Parameters(method = "validNumericAddressesAndStringRepresentation")
-    @Test
-    public void parseNumericAddress(String address, String expectedString) {
-        InetAddress inetAddress = InetAddresses.parseNumericAddress(address);
-        assertEquals(expectedString, inetAddress.getHostAddress());
-    }
-
-    @Parameters(method = "invalidNumericAddresses")
-    @Test
-    public void test_parseNonNumericAddress(String address) {
-        try {
-            InetAddress inetAddress = InetAddresses.parseNumericAddress(address);
-            fail(String.format(
-                "Address %s is not numeric but was parsed as %s", address, inetAddress));
-        } catch (IllegalArgumentException e) {
-            assertThat(e.getMessage()).contains(address);
-        }
-    }
-
-    @Test
-    public void test_parseNumericAddress_null() {
-        try {
-            InetAddress inetAddress = InetAddresses.parseNumericAddress(null);
-            fail(String.format("null is not numeric but was parsed as %s", inetAddress));
-        } catch (NullPointerException e) {
-            // expected
-        }
-    }
-
-    @Parameters(method = "validNumericAddressesAndStringRepresentation")
-    @Test
-    public void test_isNumericAddress(String address, String unused) {
-        assertTrue("expected '" + address + "' to be treated as numeric",
-            InetAddresses.isNumericAddress(address));
-    }
-
-    @Parameters(method = "invalidNumericAddresses")
-    @Test
-    public void test_isNotNumericAddress(String address) {
-        assertFalse("expected '" + address + "' to be treated as non-numeric",
-            InetAddresses.isNumericAddress(address));
-    }
-
-    @Test
-    public void test_isNumericAddress_null() {
-        try {
-            InetAddresses.isNumericAddress(null);
-            fail("expected null to throw a NullPointerException");
-        } catch (NullPointerException e) {
-            // expected
-        }
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/IpConfigurationTest.java b/tests/cts/net/src/android/net/cts/IpConfigurationTest.java
deleted file mode 100644
index 56ab2a7..0000000
--- a/tests/cts/net/src/android/net/cts/IpConfigurationTest.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-import static com.android.testutils.ParcelUtils.assertParcelSane;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
-import android.net.IpConfiguration;
-import android.net.LinkAddress;
-import android.net.ProxyInfo;
-import android.net.StaticIpConfiguration;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import libcore.net.InetAddressUtils;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.net.InetAddress;
-import java.util.ArrayList;
-
-@RunWith(AndroidJUnit4.class)
-public final class IpConfigurationTest {
-    private static final LinkAddress LINKADDR = new LinkAddress("192.0.2.2/25");
-    private static final InetAddress GATEWAY = InetAddressUtils.parseNumericAddress("192.0.2.1");
-    private static final InetAddress DNS1 = InetAddressUtils.parseNumericAddress("8.8.8.8");
-    private static final InetAddress DNS2 = InetAddressUtils.parseNumericAddress("8.8.4.4");
-    private static final String DOMAINS = "example.com";
-
-    private static final ArrayList<InetAddress> dnsServers = new ArrayList<>();
-
-    private StaticIpConfiguration mStaticIpConfig;
-    private ProxyInfo mProxy;
-
-    @Before
-    public void setUp() {
-        dnsServers.add(DNS1);
-        dnsServers.add(DNS2);
-        mStaticIpConfig = new StaticIpConfiguration.Builder()
-                .setIpAddress(LINKADDR)
-                .setGateway(GATEWAY)
-                .setDnsServers(dnsServers)
-                .setDomains(DOMAINS)
-                .build();
-
-        mProxy = ProxyInfo.buildDirectProxy("test", 8888);
-    }
-
-    @Test
-    public void testConstructor() {
-        IpConfiguration ipConfig = new IpConfiguration();
-        checkEmpty(ipConfig);
-        assertIpConfigurationEqual(ipConfig, new IpConfiguration());
-        assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig));
-
-        ipConfig.setStaticIpConfiguration(mStaticIpConfig);
-        ipConfig.setHttpProxy(mProxy);
-
-        ipConfig.setIpAssignment(IpConfiguration.IpAssignment.STATIC);
-        ipConfig.setProxySettings(IpConfiguration.ProxySettings.PAC);
-        assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig));
-
-        ipConfig.setIpAssignment(IpConfiguration.IpAssignment.STATIC);
-        ipConfig.setProxySettings(IpConfiguration.ProxySettings.STATIC);
-        assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig));
-
-        ipConfig.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
-        ipConfig.setProxySettings(IpConfiguration.ProxySettings.PAC);
-        assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig));
-
-        ipConfig.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
-        ipConfig.setProxySettings(IpConfiguration.ProxySettings.PAC);
-        assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig));
-
-        ipConfig.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
-        ipConfig.setProxySettings(IpConfiguration.ProxySettings.STATIC);
-        assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig));
-
-        ipConfig.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
-        ipConfig.setProxySettings(IpConfiguration.ProxySettings.NONE);
-        assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig));
-    }
-
-    private void checkEmpty(IpConfiguration config) {
-        assertEquals(IpConfiguration.IpAssignment.UNASSIGNED,
-                config.getIpAssignment().UNASSIGNED);
-        assertEquals(IpConfiguration.ProxySettings.UNASSIGNED,
-                config.getProxySettings().UNASSIGNED);
-        assertNull(config.getStaticIpConfiguration());
-        assertNull(config.getHttpProxy());
-    }
-
-    private void assertIpConfigurationEqual(IpConfiguration source, IpConfiguration target) {
-        assertEquals(source.getIpAssignment(), target.getIpAssignment());
-        assertEquals(source.getProxySettings(), target.getProxySettings());
-        assertEquals(source.getHttpProxy(), target.getHttpProxy());
-        assertEquals(source.getStaticIpConfiguration(), target.getStaticIpConfiguration());
-    }
-
-    @Test
-    public void testParcel() {
-        final IpConfiguration config = new IpConfiguration();
-        assertParcelSane(config, 4);
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java
deleted file mode 100644
index 10e43e7..0000000
--- a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
- * 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.ConnectivityManager;
-import android.net.IpSecAlgorithm;
-import android.net.IpSecManager;
-import android.net.IpSecTransform;
-import android.platform.test.annotations.AppModeFull;
-import android.system.Os;
-import android.system.OsConstants;
-import android.util.Log;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-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.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketException;
-import java.util.Arrays;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class IpSecBaseTest {
-
-    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 ConnectivityManager mCM;
-    protected IpSecManager mISM;
-
-    @Before
-    public void setUp() throws Exception {
-        mISM =
-                (IpSecManager)
-                        InstrumentationRegistry.getContext()
-                                .getSystemService(Context.IPSEC_SERVICE);
-        mCM =
-                (ConnectivityManager)
-                        InstrumentationRegistry.getContext()
-                                .getSystemService(Context.CONNECTIVITY_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, int port) {
-            try {
-                mSocket = new DatagramSocket(port, 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);
-            }
-        }
-
-        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 context,
-            IpSecManager.SecurityParameterIndex spi,
-            IpSecManager.UdpEncapsulationSocket encapSocket,
-            InetAddress remoteAddr)
-            throws Exception {
-        IpSecTransform.Builder builder =
-                new IpSecTransform.Builder(context)
-                        .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(remoteAddr, spi);
-    }
-
-    private IpSecTransform buildDefaultTransform(InetAddress localAddr) throws Exception {
-        try (IpSecManager.SecurityParameterIndex spi =
-                mISM.allocateSecurityParameterIndex(localAddr)) {
-            return buildIpSecTransform(InstrumentationRegistry.getContext(), spi, null, localAddr);
-        }
-    }
-
-    @Test
-    @AppModeFull(reason = "Socket cannot bind in instant app mode")
-    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);
-            }
-        }
-    }
-
-    @Test
-    @AppModeFull(reason = "Socket cannot bind in instant app mode")
-    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);
-            }
-        }
-    }
-
-    @Test
-    @AppModeFull(reason = "Socket cannot bind in instant app mode")
-    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);
-            }
-        }
-    }
-
-    @Test
-    @AppModeFull(reason = "Socket cannot bind in instant app mode")
-    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);
-            }
-        }
-    }
-
-    @Test
-    @AppModeFull(reason = "Socket cannot bind in instant app mode")
-    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);
-            }
-        }
-    }
-
-    @Test
-    @AppModeFull(reason = "Socket cannot bind in instant app mode")
-    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
deleted file mode 100644
index 355b496..0000000
--- a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java
+++ /dev/null
@@ -1,1189 +0,0 @@
-/*
- * 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.net.cts.PacketUtils.AES_CBC_BLK_SIZE;
-import static android.net.cts.PacketUtils.AES_CBC_IV_LEN;
-import static android.net.cts.PacketUtils.AES_GCM_BLK_SIZE;
-import static android.net.cts.PacketUtils.AES_GCM_IV_LEN;
-import static android.net.cts.PacketUtils.IP4_HDRLEN;
-import static android.net.cts.PacketUtils.IP6_HDRLEN;
-import static android.net.cts.PacketUtils.TCP_HDRLEN_WITH_TIMESTAMP_OPT;
-import static android.net.cts.PacketUtils.UDP_HDRLEN;
-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.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.net.IpSecAlgorithm;
-import android.net.IpSecManager;
-import android.net.IpSecTransform;
-import android.net.TrafficStats;
-import android.platform.test.annotations.AppModeFull;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.OsConstants;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-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.util.Arrays;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@AppModeFull(reason = "Socket cannot bind in instant app mode")
-public class IpSecManagerTest extends IpSecBaseTest {
-
-    private static final String TAG = IpSecManagerTest.class.getSimpleName();
-
-    private static final InetAddress GOOGLE_DNS_4 = InetAddress.parseNumericAddress("8.8.8.8");
-    private static final InetAddress GOOGLE_DNS_6 =
-            InetAddress.parseNumericAddress("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);
-
-    /*
-     * 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
-     */
-    @Test
-    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)
-     */
-    @Test
-    public void testCreateTransform() throws Exception {
-        InetAddress localAddr = InetAddress.getByName(IPV4_LOOPBACK);
-        IpSecManager.SecurityParameterIndex spi =
-                mISM.allocateSecurityParameterIndex(localAddr);
-
-        IpSecTransform transform =
-                new IpSecTransform.Builder(InstrumentationRegistry.getContext())
-                        .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 minRxByteDelta,
-                int maxRxByteDelta,
-                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);
-            assertTrue(
-                    newUidRxBytes - uidRxBytes >= minRxByteDelta
-                            && newUidRxBytes - uidRxBytes <= maxRxByteDelta);
-            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());
-        }
-    }
-
-    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(InstrumentationRegistry.getContext());
-            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_TIMESTAMP_OPT;
-                    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 =
-                PacketUtils.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 =
-                    PacketUtils.calculateEspPacketSize(
-                            TCP_HDRLEN_WITH_TIMESTAMP_OPT, ivLen, blkSize, truncLenBits);
-
-            // Add data packet ACKs
-            expectedOuterBytes += (encryptedTcpPktSize + udpEncapLen + ipHdrLen) * (sendCount);
-            expectedInnerBytes += (TCP_HDRLEN_WITH_TIMESTAMP_OPT + ipHdrLen) * (sendCount);
-            expectedPackets += sendCount;
-        }
-
-        StatsChecker.waitForNumPackets(expectedPackets);
-
-        // eBPF only counts inner packets, whereas xt_qtaguid counts outer packets. Allow both
-        StatsChecker.assertUidStatsDelta(
-                expectedOuterBytes,
-                expectedPackets,
-                expectedInnerBytes,
-                expectedOuterBytes,
-                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,
-                    expectedPacketSize,
-                    expectedNumPkts);
-            StatsChecker.assertIfaceStatsDelta(
-                    expectedPacketSize, expectedNumPkts, expectedPacketSize, expectedNumPkts);
-        }
-    }
-
-    @Test
-    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(InstrumentationRegistry.getContext())
-                                    .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);
-    // }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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);
-    }
-
-    @Test
-    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/IpSecManagerTunnelTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java
deleted file mode 100644
index ae38faa..0000000
--- a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java
+++ /dev/null
@@ -1,899 +0,0 @@
-/*
- * 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.app.AppOpsManager.OP_MANAGE_IPSEC_TUNNELS;
-import static android.net.IpSecManager.UdpEncapsulationSocket;
-import static android.net.cts.PacketUtils.AES_CBC_BLK_SIZE;
-import static android.net.cts.PacketUtils.AES_CBC_IV_LEN;
-import static android.net.cts.PacketUtils.BytePayload;
-import static android.net.cts.PacketUtils.EspHeader;
-import static android.net.cts.PacketUtils.IP4_HDRLEN;
-import static android.net.cts.PacketUtils.IP6_HDRLEN;
-import static android.net.cts.PacketUtils.IpHeader;
-import static android.net.cts.PacketUtils.UDP_HDRLEN;
-import static android.net.cts.PacketUtils.UdpHeader;
-import static android.net.cts.PacketUtils.getIpHeader;
-import static android.net.cts.util.CtsNetUtils.TestNetworkCallback;
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.AF_INET6;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
-
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.IpSecAlgorithm;
-import android.net.IpSecManager;
-import android.net.IpSecTransform;
-import android.net.LinkAddress;
-import android.net.Network;
-import android.net.TestNetworkInterface;
-import android.net.TestNetworkManager;
-import android.net.cts.PacketUtils.Payload;
-import android.net.cts.util.CtsNetUtils;
-import android.os.ParcelFileDescriptor;
-import android.platform.test.annotations.AppModeFull;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@AppModeFull(reason = "MANAGE_TEST_NETWORKS permission can't be granted to instant apps")
-public class IpSecManagerTunnelTest extends IpSecBaseTest {
-    private static final String TAG = IpSecManagerTunnelTest.class.getSimpleName();
-
-    private static final InetAddress LOCAL_OUTER_4 = InetAddress.parseNumericAddress("192.0.2.1");
-    private static final InetAddress REMOTE_OUTER_4 = InetAddress.parseNumericAddress("192.0.2.2");
-    private static final InetAddress LOCAL_OUTER_6 =
-            InetAddress.parseNumericAddress("2001:db8:1::1");
-    private static final InetAddress REMOTE_OUTER_6 =
-            InetAddress.parseNumericAddress("2001:db8:1::2");
-
-    private static final InetAddress LOCAL_INNER_4 =
-            InetAddress.parseNumericAddress("198.51.100.1");
-    private static final InetAddress REMOTE_INNER_4 =
-            InetAddress.parseNumericAddress("198.51.100.2");
-    private static final InetAddress LOCAL_INNER_6 =
-            InetAddress.parseNumericAddress("2001:db8:2::1");
-    private static final InetAddress REMOTE_INNER_6 =
-            InetAddress.parseNumericAddress("2001:db8:2::2");
-
-    private static final int IP4_PREFIX_LEN = 32;
-    private static final int IP6_PREFIX_LEN = 128;
-
-    private static final int TIMEOUT_MS = 500;
-
-    // Static state to reduce setup/teardown
-    private static ConnectivityManager sCM;
-    private static TestNetworkManager sTNM;
-    private static ParcelFileDescriptor sTunFd;
-    private static TestNetworkCallback sTunNetworkCallback;
-    private static Network sTunNetwork;
-    private static TunUtils sTunUtils;
-
-    private static Context sContext = InstrumentationRegistry.getContext();
-    private static final CtsNetUtils mCtsNetUtils = new CtsNetUtils(sContext);
-
-    @BeforeClass
-    public static void setUpBeforeClass() throws Exception {
-        InstrumentationRegistry.getInstrumentation()
-                .getUiAutomation()
-                .adoptShellPermissionIdentity();
-        sCM = (ConnectivityManager) sContext.getSystemService(Context.CONNECTIVITY_SERVICE);
-        sTNM = (TestNetworkManager) sContext.getSystemService(Context.TEST_NETWORK_SERVICE);
-
-        // Under normal circumstances, the MANAGE_IPSEC_TUNNELS appop would be auto-granted, and
-        // a standard permission is insufficient. So we shell out the appop, to give us the
-        // right appop permissions.
-        mCtsNetUtils.setAppopPrivileged(OP_MANAGE_IPSEC_TUNNELS, true);
-
-        TestNetworkInterface testIface =
-                sTNM.createTunInterface(
-                        new LinkAddress[] {
-                            new LinkAddress(LOCAL_OUTER_4, IP4_PREFIX_LEN),
-                            new LinkAddress(LOCAL_OUTER_6, IP6_PREFIX_LEN)
-                        });
-
-        sTunFd = testIface.getFileDescriptor();
-        sTunNetworkCallback = mCtsNetUtils.setupAndGetTestNetwork(testIface.getInterfaceName());
-        sTunNetworkCallback.waitForAvailable();
-        sTunNetwork = sTunNetworkCallback.currentNetwork;
-
-        sTunUtils = new TunUtils(sTunFd);
-    }
-
-    @Before
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-
-        // Set to true before every run; some tests flip this.
-        mCtsNetUtils.setAppopPrivileged(OP_MANAGE_IPSEC_TUNNELS, true);
-
-        // Clear sTunUtils state
-        sTunUtils.reset();
-    }
-
-    @AfterClass
-    public static void tearDownAfterClass() throws Exception {
-        mCtsNetUtils.setAppopPrivileged(OP_MANAGE_IPSEC_TUNNELS, false);
-
-        sCM.unregisterNetworkCallback(sTunNetworkCallback);
-
-        sTNM.teardownTestNetwork(sTunNetwork);
-        sTunFd.close();
-
-        InstrumentationRegistry.getInstrumentation()
-                .getUiAutomation()
-                .dropShellPermissionIdentity();
-    }
-
-    @Test
-    public void testSecurityExceptionCreateTunnelInterfaceWithoutAppop() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-
-        // Ensure we don't have the appop. Permission is not requested in the Manifest
-        mCtsNetUtils.setAppopPrivileged(OP_MANAGE_IPSEC_TUNNELS, false);
-
-        // Security exceptions are thrown regardless of IPv4/IPv6. Just test one
-        try {
-            mISM.createIpSecTunnelInterface(LOCAL_INNER_6, REMOTE_INNER_6, sTunNetwork);
-            fail("Did not throw SecurityException for Tunnel creation without appop");
-        } catch (SecurityException expected) {
-        }
-    }
-
-    @Test
-    public void testSecurityExceptionBuildTunnelTransformWithoutAppop() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-
-        // Ensure we don't have the appop. Permission is not requested in the Manifest
-        mCtsNetUtils.setAppopPrivileged(OP_MANAGE_IPSEC_TUNNELS, false);
-
-        // Security exceptions are thrown regardless of IPv4/IPv6. Just test one
-        try (IpSecManager.SecurityParameterIndex spi =
-                        mISM.allocateSecurityParameterIndex(LOCAL_INNER_4);
-                IpSecTransform transform =
-                        new IpSecTransform.Builder(sContext)
-                                .buildTunnelModeTransform(REMOTE_INNER_4, spi)) {
-            fail("Did not throw SecurityException for Transform creation without appop");
-        } catch (SecurityException expected) {
-        }
-    }
-
-    /* Test runnables for callbacks after IPsec tunnels are set up. */
-    private abstract class IpSecTunnelTestRunnable {
-        /**
-         * Runs the test code, and returns the inner socket port, if any.
-         *
-         * @param ipsecNetwork The IPsec Interface based Network for binding sockets on
-         * @return the integer port of the inner socket if outbound, or 0 if inbound
-         *     IpSecTunnelTestRunnable
-         * @throws Exception if any part of the test failed.
-         */
-        public abstract int run(Network ipsecNetwork) throws Exception;
-    }
-
-    private int getPacketSize(
-            int innerFamily, int outerFamily, boolean useEncap, boolean transportInTunnelMode) {
-        int expectedPacketSize = TEST_DATA.length + UDP_HDRLEN;
-
-        // Inner Transport mode packet size
-        if (transportInTunnelMode) {
-            expectedPacketSize =
-                    PacketUtils.calculateEspPacketSize(
-                            expectedPacketSize,
-                            AES_CBC_IV_LEN,
-                            AES_CBC_BLK_SIZE,
-                            AUTH_KEY.length * 4);
-        }
-
-        // Inner IP Header
-        expectedPacketSize += innerFamily == AF_INET ? IP4_HDRLEN : IP6_HDRLEN;
-
-        // Tunnel mode transform size
-        expectedPacketSize =
-                PacketUtils.calculateEspPacketSize(
-                        expectedPacketSize, AES_CBC_IV_LEN, AES_CBC_BLK_SIZE, AUTH_KEY.length * 4);
-
-        // UDP encap size
-        expectedPacketSize += useEncap ? UDP_HDRLEN : 0;
-
-        // Outer IP Header
-        expectedPacketSize += outerFamily == AF_INET ? IP4_HDRLEN : IP6_HDRLEN;
-
-        return expectedPacketSize;
-    }
-
-    private interface IpSecTunnelTestRunnableFactory {
-        IpSecTunnelTestRunnable getIpSecTunnelTestRunnable(
-                boolean transportInTunnelMode,
-                int spi,
-                InetAddress localInner,
-                InetAddress remoteInner,
-                InetAddress localOuter,
-                InetAddress remoteOuter,
-                IpSecTransform inTransportTransform,
-                IpSecTransform outTransportTransform,
-                int encapPort,
-                int innerSocketPort,
-                int expectedPacketSize)
-                throws Exception;
-    }
-
-    private class OutputIpSecTunnelTestRunnableFactory implements IpSecTunnelTestRunnableFactory {
-        public IpSecTunnelTestRunnable getIpSecTunnelTestRunnable(
-                boolean transportInTunnelMode,
-                int spi,
-                InetAddress localInner,
-                InetAddress remoteInner,
-                InetAddress localOuter,
-                InetAddress remoteOuter,
-                IpSecTransform inTransportTransform,
-                IpSecTransform outTransportTransform,
-                int encapPort,
-                int unusedInnerSocketPort,
-                int expectedPacketSize) {
-            return new IpSecTunnelTestRunnable() {
-                @Override
-                public int run(Network ipsecNetwork) throws Exception {
-                    // Build a socket and send traffic
-                    JavaUdpSocket socket = new JavaUdpSocket(localInner);
-                    ipsecNetwork.bindSocket(socket.mSocket);
-                    int innerSocketPort = socket.getPort();
-
-                    // For Transport-In-Tunnel mode, apply transform to socket
-                    if (transportInTunnelMode) {
-                        mISM.applyTransportModeTransform(
-                                socket.mSocket, IpSecManager.DIRECTION_IN, inTransportTransform);
-                        mISM.applyTransportModeTransform(
-                                socket.mSocket, IpSecManager.DIRECTION_OUT, outTransportTransform);
-                    }
-
-                    socket.sendTo(TEST_DATA, remoteInner, socket.getPort());
-
-                    // Verify that an encrypted packet is sent. As of right now, checking encrypted
-                    // body is not possible, due to the test not knowing some of the fields of the
-                    // inner IP header (flow label, flags, etc)
-                    sTunUtils.awaitEspPacketNoPlaintext(
-                            spi, TEST_DATA, encapPort != 0, expectedPacketSize);
-
-                    socket.close();
-
-                    return innerSocketPort;
-                }
-            };
-        }
-    }
-
-    private class InputReflectedIpSecTunnelTestRunnableFactory
-            implements IpSecTunnelTestRunnableFactory {
-        public IpSecTunnelTestRunnable getIpSecTunnelTestRunnable(
-                boolean transportInTunnelMode,
-                int spi,
-                InetAddress localInner,
-                InetAddress remoteInner,
-                InetAddress localOuter,
-                InetAddress remoteOuter,
-                IpSecTransform inTransportTransform,
-                IpSecTransform outTransportTransform,
-                int encapPort,
-                int innerSocketPort,
-                int expectedPacketSize)
-                throws Exception {
-            return new IpSecTunnelTestRunnable() {
-                @Override
-                public int run(Network ipsecNetwork) throws Exception {
-                    // Build a socket and receive traffic
-                    JavaUdpSocket socket = new JavaUdpSocket(localInner, innerSocketPort);
-                    ipsecNetwork.bindSocket(socket.mSocket);
-
-                    // For Transport-In-Tunnel mode, apply transform to socket
-                    if (transportInTunnelMode) {
-                        mISM.applyTransportModeTransform(
-                                socket.mSocket, IpSecManager.DIRECTION_IN, outTransportTransform);
-                        mISM.applyTransportModeTransform(
-                                socket.mSocket, IpSecManager.DIRECTION_OUT, inTransportTransform);
-                    }
-
-                    sTunUtils.reflectPackets();
-
-                    // Receive packet from socket, and validate that the payload is correct
-                    receiveAndValidatePacket(socket);
-
-                    socket.close();
-
-                    return 0;
-                }
-            };
-        }
-    }
-
-    private class InputPacketGeneratorIpSecTunnelTestRunnableFactory
-            implements IpSecTunnelTestRunnableFactory {
-        public IpSecTunnelTestRunnable getIpSecTunnelTestRunnable(
-                boolean transportInTunnelMode,
-                int spi,
-                InetAddress localInner,
-                InetAddress remoteInner,
-                InetAddress localOuter,
-                InetAddress remoteOuter,
-                IpSecTransform inTransportTransform,
-                IpSecTransform outTransportTransform,
-                int encapPort,
-                int innerSocketPort,
-                int expectedPacketSize)
-                throws Exception {
-            return new IpSecTunnelTestRunnable() {
-                @Override
-                public int run(Network ipsecNetwork) throws Exception {
-                    // Build a socket and receive traffic
-                    JavaUdpSocket socket = new JavaUdpSocket(localInner);
-                    ipsecNetwork.bindSocket(socket.mSocket);
-
-                    // For Transport-In-Tunnel mode, apply transform to socket
-                    if (transportInTunnelMode) {
-                        mISM.applyTransportModeTransform(
-                                socket.mSocket, IpSecManager.DIRECTION_IN, outTransportTransform);
-                        mISM.applyTransportModeTransform(
-                                socket.mSocket, IpSecManager.DIRECTION_OUT, inTransportTransform);
-                    }
-
-                    byte[] pkt;
-                    if (transportInTunnelMode) {
-                        pkt =
-                                getTransportInTunnelModePacket(
-                                        spi,
-                                        spi,
-                                        remoteInner,
-                                        localInner,
-                                        remoteOuter,
-                                        localOuter,
-                                        socket.getPort(),
-                                        encapPort);
-                    } else {
-                        pkt =
-                                getTunnelModePacket(
-                                        spi,
-                                        remoteInner,
-                                        localInner,
-                                        remoteOuter,
-                                        localOuter,
-                                        socket.getPort(),
-                                        encapPort);
-                    }
-                    sTunUtils.injectPacket(pkt);
-
-                    // Receive packet from socket, and validate
-                    receiveAndValidatePacket(socket);
-
-                    socket.close();
-
-                    return 0;
-                }
-            };
-        }
-    }
-
-    private void checkTunnelOutput(
-            int innerFamily, int outerFamily, boolean useEncap, boolean transportInTunnelMode)
-            throws Exception {
-        checkTunnel(
-                innerFamily,
-                outerFamily,
-                useEncap,
-                transportInTunnelMode,
-                new OutputIpSecTunnelTestRunnableFactory());
-    }
-
-    private void checkTunnelInput(
-            int innerFamily, int outerFamily, boolean useEncap, boolean transportInTunnelMode)
-            throws Exception {
-        checkTunnel(
-                innerFamily,
-                outerFamily,
-                useEncap,
-                transportInTunnelMode,
-                new InputPacketGeneratorIpSecTunnelTestRunnableFactory());
-    }
-
-    /**
-     * Validates that the kernel can talk to itself.
-     *
-     * <p>This test takes an outbound IPsec packet, reflects it (by flipping IP src/dst), and
-     * injects it back into the TUN. This test then verifies that a packet with the correct payload
-     * is found on the specified socket/port.
-     */
-    public void checkTunnelReflected(
-            int innerFamily, int outerFamily, boolean useEncap, boolean transportInTunnelMode)
-            throws Exception {
-        InetAddress localInner = innerFamily == AF_INET ? LOCAL_INNER_4 : LOCAL_INNER_6;
-        InetAddress remoteInner = innerFamily == AF_INET ? REMOTE_INNER_4 : REMOTE_INNER_6;
-
-        InetAddress localOuter = outerFamily == AF_INET ? LOCAL_OUTER_4 : LOCAL_OUTER_6;
-        InetAddress remoteOuter = outerFamily == AF_INET ? REMOTE_OUTER_4 : REMOTE_OUTER_6;
-
-        // Preselect both SPI and encap port, to be used for both inbound and outbound tunnels.
-        int spi = getRandomSpi(localOuter, remoteOuter);
-        int expectedPacketSize =
-                getPacketSize(innerFamily, outerFamily, useEncap, transportInTunnelMode);
-
-        try (IpSecManager.SecurityParameterIndex inTransportSpi =
-                        mISM.allocateSecurityParameterIndex(localInner, spi);
-                IpSecManager.SecurityParameterIndex outTransportSpi =
-                        mISM.allocateSecurityParameterIndex(remoteInner, spi);
-                IpSecTransform inTransportTransform =
-                        buildIpSecTransform(sContext, inTransportSpi, null, remoteInner);
-                IpSecTransform outTransportTransform =
-                        buildIpSecTransform(sContext, outTransportSpi, null, localInner);
-                UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) {
-
-            // Run output direction tests
-            IpSecTunnelTestRunnable outputIpSecTunnelTestRunnable =
-                    new OutputIpSecTunnelTestRunnableFactory()
-                            .getIpSecTunnelTestRunnable(
-                                    transportInTunnelMode,
-                                    spi,
-                                    localInner,
-                                    remoteInner,
-                                    localOuter,
-                                    remoteOuter,
-                                    inTransportTransform,
-                                    outTransportTransform,
-                                    useEncap ? encapSocket.getPort() : 0,
-                                    0,
-                                    expectedPacketSize);
-            int innerSocketPort =
-                    buildTunnelNetworkAndRunTests(
-                    localInner,
-                    remoteInner,
-                    localOuter,
-                    remoteOuter,
-                    spi,
-                    useEncap ? encapSocket : null,
-                    outputIpSecTunnelTestRunnable);
-
-            // Input direction tests, with matching inner socket ports.
-            IpSecTunnelTestRunnable inputIpSecTunnelTestRunnable =
-                    new InputReflectedIpSecTunnelTestRunnableFactory()
-                            .getIpSecTunnelTestRunnable(
-                                    transportInTunnelMode,
-                                    spi,
-                                    remoteInner,
-                                    localInner,
-                                    localOuter,
-                                    remoteOuter,
-                                    inTransportTransform,
-                                    outTransportTransform,
-                                    useEncap ? encapSocket.getPort() : 0,
-                                    innerSocketPort,
-                                    expectedPacketSize);
-            buildTunnelNetworkAndRunTests(
-                    remoteInner,
-                    localInner,
-                    localOuter,
-                    remoteOuter,
-                    spi,
-                    useEncap ? encapSocket : null,
-                    inputIpSecTunnelTestRunnable);
-        }
-    }
-
-    public void checkTunnel(
-            int innerFamily,
-            int outerFamily,
-            boolean useEncap,
-            boolean transportInTunnelMode,
-            IpSecTunnelTestRunnableFactory factory)
-            throws Exception {
-
-        InetAddress localInner = innerFamily == AF_INET ? LOCAL_INNER_4 : LOCAL_INNER_6;
-        InetAddress remoteInner = innerFamily == AF_INET ? REMOTE_INNER_4 : REMOTE_INNER_6;
-
-        InetAddress localOuter = outerFamily == AF_INET ? LOCAL_OUTER_4 : LOCAL_OUTER_6;
-        InetAddress remoteOuter = outerFamily == AF_INET ? REMOTE_OUTER_4 : REMOTE_OUTER_6;
-
-        // Preselect both SPI and encap port, to be used for both inbound and outbound tunnels.
-        // Re-uses the same SPI to ensure that even in cases of symmetric SPIs shared across tunnel
-        // and transport mode, packets are encrypted/decrypted properly based on the src/dst.
-        int spi = getRandomSpi(localOuter, remoteOuter);
-        int expectedPacketSize =
-                getPacketSize(innerFamily, outerFamily, useEncap, transportInTunnelMode);
-
-        try (IpSecManager.SecurityParameterIndex inTransportSpi =
-                        mISM.allocateSecurityParameterIndex(localInner, spi);
-                IpSecManager.SecurityParameterIndex outTransportSpi =
-                        mISM.allocateSecurityParameterIndex(remoteInner, spi);
-                IpSecTransform inTransportTransform =
-                        buildIpSecTransform(sContext, inTransportSpi, null, remoteInner);
-                IpSecTransform outTransportTransform =
-                        buildIpSecTransform(sContext, outTransportSpi, null, localInner);
-                UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) {
-
-            buildTunnelNetworkAndRunTests(
-                    localInner,
-                    remoteInner,
-                    localOuter,
-                    remoteOuter,
-                    spi,
-                    useEncap ? encapSocket : null,
-                    factory.getIpSecTunnelTestRunnable(
-                            transportInTunnelMode,
-                            spi,
-                            localInner,
-                            remoteInner,
-                            localOuter,
-                            remoteOuter,
-                            inTransportTransform,
-                            outTransportTransform,
-                            useEncap ? encapSocket.getPort() : 0,
-                            0,
-                            expectedPacketSize));
-        }
-    }
-
-    private int buildTunnelNetworkAndRunTests(
-            InetAddress localInner,
-            InetAddress remoteInner,
-            InetAddress localOuter,
-            InetAddress remoteOuter,
-            int spi,
-            UdpEncapsulationSocket encapSocket,
-            IpSecTunnelTestRunnable test)
-            throws Exception {
-        int innerPrefixLen = localInner instanceof Inet6Address ? IP6_PREFIX_LEN : IP4_PREFIX_LEN;
-        TestNetworkCallback testNetworkCb = null;
-        int innerSocketPort;
-
-        try (IpSecManager.SecurityParameterIndex inSpi =
-                        mISM.allocateSecurityParameterIndex(localOuter, spi);
-                IpSecManager.SecurityParameterIndex outSpi =
-                        mISM.allocateSecurityParameterIndex(remoteOuter, spi);
-                IpSecManager.IpSecTunnelInterface tunnelIface =
-                        mISM.createIpSecTunnelInterface(localOuter, remoteOuter, sTunNetwork)) {
-            // Build the test network
-            tunnelIface.addAddress(localInner, innerPrefixLen);
-            testNetworkCb = mCtsNetUtils.setupAndGetTestNetwork(tunnelIface.getInterfaceName());
-            testNetworkCb.waitForAvailable();
-            Network testNetwork = testNetworkCb.currentNetwork;
-
-            // Check interface was created
-            assertNotNull(NetworkInterface.getByName(tunnelIface.getInterfaceName()));
-
-            // Verify address was added
-            final NetworkInterface netIface = NetworkInterface.getByInetAddress(localInner);
-            assertNotNull(netIface);
-            assertEquals(tunnelIface.getInterfaceName(), netIface.getDisplayName());
-
-            // Configure Transform parameters
-            IpSecTransform.Builder transformBuilder = new IpSecTransform.Builder(sContext);
-            transformBuilder.setEncryption(
-                    new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY));
-            transformBuilder.setAuthentication(
-                    new IpSecAlgorithm(
-                            IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4));
-
-            if (encapSocket != null) {
-                transformBuilder.setIpv4Encapsulation(encapSocket, encapSocket.getPort());
-            }
-
-            // Apply transform and check that traffic is properly encrypted
-            try (IpSecTransform inTransform =
-                            transformBuilder.buildTunnelModeTransform(remoteOuter, inSpi);
-                    IpSecTransform outTransform =
-                            transformBuilder.buildTunnelModeTransform(localOuter, outSpi)) {
-                mISM.applyTunnelModeTransform(tunnelIface, IpSecManager.DIRECTION_IN, inTransform);
-                mISM.applyTunnelModeTransform(
-                        tunnelIface, IpSecManager.DIRECTION_OUT, outTransform);
-
-                innerSocketPort = test.run(testNetwork);
-            }
-
-            // Teardown the test network
-            sTNM.teardownTestNetwork(testNetwork);
-
-            // Remove addresses and check that interface is still present, but fails lookup-by-addr
-            tunnelIface.removeAddress(localInner, innerPrefixLen);
-            assertNotNull(NetworkInterface.getByName(tunnelIface.getInterfaceName()));
-            assertNull(NetworkInterface.getByInetAddress(localInner));
-
-            // Check interface was cleaned up
-            tunnelIface.close();
-            assertNull(NetworkInterface.getByName(tunnelIface.getInterfaceName()));
-        } finally {
-            if (testNetworkCb != null) {
-                sCM.unregisterNetworkCallback(testNetworkCb);
-            }
-        }
-
-        return innerSocketPort;
-    }
-
-    private static void receiveAndValidatePacket(JavaUdpSocket socket) throws Exception {
-        byte[] socketResponseBytes = socket.receive();
-        assertArrayEquals(TEST_DATA, socketResponseBytes);
-    }
-
-    private int getRandomSpi(InetAddress localOuter, InetAddress remoteOuter) throws Exception {
-        // Try to allocate both in and out SPIs using the same requested SPI value.
-        try (IpSecManager.SecurityParameterIndex inSpi =
-                        mISM.allocateSecurityParameterIndex(localOuter);
-                IpSecManager.SecurityParameterIndex outSpi =
-                        mISM.allocateSecurityParameterIndex(remoteOuter, inSpi.getSpi()); ) {
-            return inSpi.getSpi();
-        }
-    }
-
-    private EspHeader buildTransportModeEspPacket(
-            int spi, InetAddress src, InetAddress dst, int port, Payload payload) throws Exception {
-        IpHeader preEspIpHeader = getIpHeader(payload.getProtocolId(), src, dst, payload);
-
-        return new EspHeader(
-                payload.getProtocolId(),
-                spi,
-                1, // sequence number
-                CRYPT_KEY, // Same key for auth and crypt
-                payload.getPacketBytes(preEspIpHeader));
-    }
-
-    private EspHeader buildTunnelModeEspPacket(
-            int spi,
-            InetAddress srcInner,
-            InetAddress dstInner,
-            InetAddress srcOuter,
-            InetAddress dstOuter,
-            int port,
-            int encapPort,
-            Payload payload)
-            throws Exception {
-        IpHeader innerIp = getIpHeader(payload.getProtocolId(), srcInner, dstInner, payload);
-        return new EspHeader(
-                innerIp.getProtocolId(),
-                spi,
-                1, // sequence number
-                CRYPT_KEY, // Same key for auth and crypt
-                innerIp.getPacketBytes());
-    }
-
-    private IpHeader maybeEncapPacket(
-            InetAddress src, InetAddress dst, int encapPort, EspHeader espPayload)
-            throws Exception {
-
-        Payload payload = espPayload;
-        if (encapPort != 0) {
-            payload = new UdpHeader(encapPort, encapPort, espPayload);
-        }
-
-        return getIpHeader(payload.getProtocolId(), src, dst, payload);
-    }
-
-    private byte[] getTunnelModePacket(
-            int spi,
-            InetAddress srcInner,
-            InetAddress dstInner,
-            InetAddress srcOuter,
-            InetAddress dstOuter,
-            int port,
-            int encapPort)
-            throws Exception {
-        UdpHeader udp = new UdpHeader(port, port, new BytePayload(TEST_DATA));
-
-        EspHeader espPayload =
-                buildTunnelModeEspPacket(
-                        spi, srcInner, dstInner, srcOuter, dstOuter, port, encapPort, udp);
-        return maybeEncapPacket(srcOuter, dstOuter, encapPort, espPayload).getPacketBytes();
-    }
-
-    private byte[] getTransportInTunnelModePacket(
-            int spiInner,
-            int spiOuter,
-            InetAddress srcInner,
-            InetAddress dstInner,
-            InetAddress srcOuter,
-            InetAddress dstOuter,
-            int port,
-            int encapPort)
-            throws Exception {
-        UdpHeader udp = new UdpHeader(port, port, new BytePayload(TEST_DATA));
-
-        EspHeader espPayload = buildTransportModeEspPacket(spiInner, srcInner, dstInner, port, udp);
-        espPayload =
-                buildTunnelModeEspPacket(
-                        spiOuter,
-                        srcInner,
-                        dstInner,
-                        srcOuter,
-                        dstOuter,
-                        port,
-                        encapPort,
-                        espPayload);
-        return maybeEncapPacket(srcOuter, dstOuter, encapPort, espPayload).getPacketBytes();
-    }
-
-    // Transport-in-Tunnel mode tests
-    @Test
-    public void testTransportInTunnelModeV4InV4() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelOutput(AF_INET, AF_INET, false, true);
-        checkTunnelInput(AF_INET, AF_INET, false, true);
-    }
-
-    @Test
-    public void testTransportInTunnelModeV4InV4Reflected() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelReflected(AF_INET, AF_INET, false, true);
-    }
-
-    @Test
-    public void testTransportInTunnelModeV4InV4UdpEncap() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelOutput(AF_INET, AF_INET, true, true);
-        checkTunnelInput(AF_INET, AF_INET, true, true);
-    }
-
-    @Test
-    public void testTransportInTunnelModeV4InV4UdpEncapReflected() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelReflected(AF_INET, AF_INET, false, true);
-    }
-
-    @Test
-    public void testTransportInTunnelModeV4InV6() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelOutput(AF_INET, AF_INET6, false, true);
-        checkTunnelInput(AF_INET, AF_INET6, false, true);
-    }
-
-    @Test
-    public void testTransportInTunnelModeV4InV6Reflected() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelReflected(AF_INET, AF_INET, false, true);
-    }
-
-    @Test
-    public void testTransportInTunnelModeV6InV4() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelOutput(AF_INET6, AF_INET, false, true);
-        checkTunnelInput(AF_INET6, AF_INET, false, true);
-    }
-
-    @Test
-    public void testTransportInTunnelModeV6InV4Reflected() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelReflected(AF_INET, AF_INET, false, true);
-    }
-
-    @Test
-    public void testTransportInTunnelModeV6InV4UdpEncap() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelOutput(AF_INET6, AF_INET, true, true);
-        checkTunnelInput(AF_INET6, AF_INET, true, true);
-    }
-
-    @Test
-    public void testTransportInTunnelModeV6InV4UdpEncapReflected() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelReflected(AF_INET, AF_INET, false, true);
-    }
-
-    @Test
-    public void testTransportInTunnelModeV6InV6() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelOutput(AF_INET, AF_INET6, false, true);
-        checkTunnelInput(AF_INET, AF_INET6, false, true);
-    }
-
-    @Test
-    public void testTransportInTunnelModeV6InV6Reflected() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelReflected(AF_INET, AF_INET, false, true);
-    }
-
-    // Tunnel mode tests
-    @Test
-    public void testTunnelV4InV4() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelOutput(AF_INET, AF_INET, false, false);
-        checkTunnelInput(AF_INET, AF_INET, false, false);
-    }
-
-    @Test
-    public void testTunnelV4InV4Reflected() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelReflected(AF_INET, AF_INET, false, false);
-    }
-
-    @Test
-    public void testTunnelV4InV4UdpEncap() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelOutput(AF_INET, AF_INET, true, false);
-        checkTunnelInput(AF_INET, AF_INET, true, false);
-    }
-
-    @Test
-    public void testTunnelV4InV4UdpEncapReflected() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelReflected(AF_INET, AF_INET, true, false);
-    }
-
-    @Test
-    public void testTunnelV4InV6() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelOutput(AF_INET, AF_INET6, false, false);
-        checkTunnelInput(AF_INET, AF_INET6, false, false);
-    }
-
-    @Test
-    public void testTunnelV4InV6Reflected() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelReflected(AF_INET, AF_INET6, false, false);
-    }
-
-    @Test
-    public void testTunnelV6InV4() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelOutput(AF_INET6, AF_INET, false, false);
-        checkTunnelInput(AF_INET6, AF_INET, false, false);
-    }
-
-    @Test
-    public void testTunnelV6InV4Reflected() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelReflected(AF_INET6, AF_INET, false, false);
-    }
-
-    @Test
-    public void testTunnelV6InV4UdpEncap() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelOutput(AF_INET6, AF_INET, true, false);
-        checkTunnelInput(AF_INET6, AF_INET, true, false);
-    }
-
-    @Test
-    public void testTunnelV6InV4UdpEncapReflected() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelReflected(AF_INET6, AF_INET, true, false);
-    }
-
-    @Test
-    public void testTunnelV6InV6() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelOutput(AF_INET6, AF_INET6, false, false);
-        checkTunnelInput(AF_INET6, AF_INET6, false, false);
-    }
-
-    @Test
-    public void testTunnelV6InV6Reflected() throws Exception {
-        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
-        checkTunnelReflected(AF_INET6, AF_INET6, false, false);
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java
deleted file mode 100644
index 7c5a1b3..0000000
--- a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net.cts;
-
-import junit.framework.TestCase;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import android.net.LocalServerSocket;
-import android.net.LocalSocket;
-import android.net.LocalSocketAddress;
-
-public class LocalServerSocketTest extends TestCase {
-
-    public void testLocalServerSocket() throws IOException {
-        String address = "com.android.net.LocalServerSocketTest_testLocalServerSocket";
-        LocalServerSocket localServerSocket = new LocalServerSocket(address);
-        assertNotNull(localServerSocket.getLocalSocketAddress());
-
-        // create client socket
-        LocalSocket clientSocket = new LocalSocket();
-
-        // establish connection between client and server
-        clientSocket.connect(new LocalSocketAddress(address));
-        LocalSocket serverSocket = localServerSocket.accept();
-
-        assertTrue(serverSocket.isConnected());
-        assertTrue(serverSocket.isBound());
-
-        // send data from client to server
-        OutputStream clientOutStream = clientSocket.getOutputStream();
-        clientOutStream.write(12);
-        InputStream serverInStream = serverSocket.getInputStream();
-        assertEquals(12, serverInStream.read());
-
-        // send data from server to client
-        OutputStream serverOutStream = serverSocket.getOutputStream();
-        serverOutStream.write(3);
-        InputStream clientInStream = clientSocket.getInputStream();
-        assertEquals(3, clientInStream.read());
-
-        // close server socket
-        assertNotNull(localServerSocket.getFileDescriptor());
-        localServerSocket.close();
-        assertNull(localServerSocket.getFileDescriptor());
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java b/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java
deleted file mode 100644
index 6ef003b..0000000
--- a/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-import android.net.LocalSocketAddress;
-import android.net.LocalSocketAddress.Namespace;
-import android.test.AndroidTestCase;
-
-public class LocalSocketAddressTest extends AndroidTestCase {
-
-    public void testNewLocalSocketAddressWithDefaultNamespace() {
-        // default namespace
-        LocalSocketAddress localSocketAddress = new LocalSocketAddress("name");
-        assertEquals("name", localSocketAddress.getName());
-        assertEquals(Namespace.ABSTRACT, localSocketAddress.getNamespace());
-
-        // specify the namespace
-        LocalSocketAddress localSocketAddress2 =
-                new LocalSocketAddress("name2", Namespace.ABSTRACT);
-        assertEquals("name2", localSocketAddress2.getName());
-        assertEquals(Namespace.ABSTRACT, localSocketAddress2.getNamespace());
-
-        LocalSocketAddress localSocketAddress3 =
-                new LocalSocketAddress("name3", Namespace.FILESYSTEM);
-        assertEquals("name3", localSocketAddress3.getName());
-        assertEquals(Namespace.FILESYSTEM, localSocketAddress3.getNamespace());
-
-        LocalSocketAddress localSocketAddress4 =
-                new LocalSocketAddress("name4", Namespace.RESERVED);
-        assertEquals("name4", localSocketAddress4.getName());
-        assertEquals(Namespace.RESERVED, localSocketAddress4.getNamespace());
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java b/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java
deleted file mode 100644
index 97dfa43..0000000
--- a/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-import android.net.LocalSocketAddress.Namespace;
-import android.test.AndroidTestCase;
-
-public class LocalSocketAddress_NamespaceTest extends AndroidTestCase {
-
-    public void testValueOf() {
-        assertEquals(Namespace.ABSTRACT, Namespace.valueOf("ABSTRACT"));
-        assertEquals(Namespace.RESERVED, Namespace.valueOf("RESERVED"));
-        assertEquals(Namespace.FILESYSTEM, Namespace.valueOf("FILESYSTEM"));
-    }
-
-    public void testValues() {
-        Namespace[] expected = Namespace.values();
-        assertEquals(Namespace.ABSTRACT, expected[0]);
-        assertEquals(Namespace.RESERVED, expected[1]);
-        assertEquals(Namespace.FILESYSTEM, expected[2]);
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java
deleted file mode 100644
index 6e61705..0000000
--- a/tests/cts/net/src/android/net/cts/LocalSocketTest.java
+++ /dev/null
@@ -1,470 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-import junit.framework.TestCase;
-
-import android.net.Credentials;
-import android.net.LocalServerSocket;
-import android.net.LocalSocket;
-import android.net.LocalSocketAddress;
-import android.system.Os;
-import android.system.OsConstants;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
-public class LocalSocketTest extends TestCase {
-    private final static String ADDRESS_PREFIX = "com.android.net.LocalSocketTest";
-
-    public void testLocalConnections() throws IOException {
-        String address = ADDRESS_PREFIX + "_testLocalConnections";
-        // create client and server socket
-        LocalServerSocket localServerSocket = new LocalServerSocket(address);
-        LocalSocket clientSocket = new LocalSocket();
-
-        // establish connection between client and server
-        LocalSocketAddress locSockAddr = new LocalSocketAddress(address);
-        assertFalse(clientSocket.isConnected());
-        clientSocket.connect(locSockAddr);
-        assertTrue(clientSocket.isConnected());
-
-        LocalSocket serverSocket = localServerSocket.accept();
-        assertTrue(serverSocket.isConnected());
-        assertTrue(serverSocket.isBound());
-        try {
-            serverSocket.bind(localServerSocket.getLocalSocketAddress());
-            fail("Cannot bind a LocalSocket from accept()");
-        } catch (IOException expected) {
-        }
-        try {
-            serverSocket.connect(locSockAddr);
-            fail("Cannot connect a LocalSocket from accept()");
-        } catch (IOException expected) {
-        }
-
-        Credentials credent = clientSocket.getPeerCredentials();
-        assertTrue(0 != credent.getPid());
-
-        // send data from client to server
-        OutputStream clientOutStream = clientSocket.getOutputStream();
-        clientOutStream.write(12);
-        InputStream serverInStream = serverSocket.getInputStream();
-        assertEquals(12, serverInStream.read());
-
-        //send data from server to client
-        OutputStream serverOutStream = serverSocket.getOutputStream();
-        serverOutStream.write(3);
-        InputStream clientInStream = clientSocket.getInputStream();
-        assertEquals(3, clientInStream.read());
-
-        // Test sending and receiving file descriptors
-        clientSocket.setFileDescriptorsForSend(new FileDescriptor[]{FileDescriptor.in});
-        clientOutStream.write(32);
-        assertEquals(32, serverInStream.read());
-
-        FileDescriptor[] out = serverSocket.getAncillaryFileDescriptors();
-        assertEquals(1, out.length);
-        FileDescriptor fd = clientSocket.getFileDescriptor();
-        assertTrue(fd.valid());
-
-        //shutdown input stream of client
-        clientSocket.shutdownInput();
-        assertEquals(-1, clientInStream.read());
-
-        //shutdown output stream of client
-        clientSocket.shutdownOutput();
-        try {
-            clientOutStream.write(10);
-            fail("testLocalSocket shouldn't come to here");
-        } catch (IOException e) {
-            // expected
-        }
-
-        //shutdown input stream of server
-        serverSocket.shutdownInput();
-        assertEquals(-1, serverInStream.read());
-
-        //shutdown output stream of server
-        serverSocket.shutdownOutput();
-        try {
-            serverOutStream.write(10);
-            fail("testLocalSocket shouldn't come to here");
-        } catch (IOException e) {
-            // expected
-        }
-
-        //close client socket
-        clientSocket.close();
-        try {
-            clientInStream.read();
-            fail("testLocalSocket shouldn't come to here");
-        } catch (IOException e) {
-            // expected
-        }
-
-        //close server socket
-        serverSocket.close();
-        try {
-            serverInStream.read();
-            fail("testLocalSocket shouldn't come to here");
-        } catch (IOException e) {
-            // expected
-        }
-    }
-
-    public void testAccessors() throws IOException {
-        String address = ADDRESS_PREFIX + "_testAccessors";
-        LocalSocket socket = new LocalSocket();
-        LocalSocketAddress addr = new LocalSocketAddress(address);
-
-        assertFalse(socket.isBound());
-        socket.bind(addr);
-        assertTrue(socket.isBound());
-        assertEquals(addr, socket.getLocalSocketAddress());
-
-        String str = socket.toString();
-        assertTrue(str.contains("impl:android.net.LocalSocketImpl"));
-
-        socket.setReceiveBufferSize(1999);
-        assertEquals(1999 << 1, socket.getReceiveBufferSize());
-
-        socket.setSendBufferSize(3998);
-        assertEquals(3998 << 1, socket.getSendBufferSize());
-
-        assertEquals(0, socket.getSoTimeout());
-        socket.setSoTimeout(1996);
-        assertTrue(socket.getSoTimeout() > 0);
-
-        try {
-            socket.getRemoteSocketAddress();
-            fail("testLocalSocketSecondary shouldn't come to here");
-        } catch (UnsupportedOperationException e) {
-            // expected
-        }
-
-        try {
-            socket.isClosed();
-            fail("testLocalSocketSecondary shouldn't come to here");
-        } catch (UnsupportedOperationException e) {
-            // expected
-        }
-
-        try {
-            socket.isInputShutdown();
-            fail("testLocalSocketSecondary shouldn't come to here");
-        } catch (UnsupportedOperationException e) {
-            // expected
-        }
-
-        try {
-            socket.isOutputShutdown();
-            fail("testLocalSocketSecondary shouldn't come to here");
-        } catch (UnsupportedOperationException e) {
-            // expected
-        }
-
-        try {
-            socket.connect(addr, 2005);
-            fail("testLocalSocketSecondary shouldn't come to here");
-        } catch (UnsupportedOperationException e) {
-            // expected
-        }
-
-        socket.close();
-    }
-
-    // http://b/31205169
-    public void testSetSoTimeout_readTimeout() throws Exception {
-        String address = ADDRESS_PREFIX + "_testSetSoTimeout_readTimeout";
-
-        try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) {
-            final LocalSocket clientSocket = socketPair.clientSocket;
-
-            // Set the timeout in millis.
-            int timeoutMillis = 1000;
-            clientSocket.setSoTimeout(timeoutMillis);
-
-            // Avoid blocking the test run if timeout doesn't happen by using a separate thread.
-            Callable<Result> reader = () -> {
-                try {
-                    clientSocket.getInputStream().read();
-                    return Result.noException("Did not block");
-                } catch (IOException e) {
-                    return Result.exception(e);
-                }
-            };
-            // Allow the configured timeout, plus some slop.
-            int allowedTime = timeoutMillis + 2000;
-            Result result = runInSeparateThread(allowedTime, reader);
-
-            // Check the message was a timeout, it's all we have to go on.
-            String expectedMessage = Os.strerror(OsConstants.EAGAIN);
-            result.assertThrewIOException(expectedMessage);
-        }
-    }
-
-    // http://b/31205169
-    public void testSetSoTimeout_writeTimeout() throws Exception {
-        String address = ADDRESS_PREFIX + "_testSetSoTimeout_writeTimeout";
-
-        try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) {
-            final LocalSocket clientSocket = socketPair.clientSocket;
-
-            // Set the timeout in millis.
-            int timeoutMillis = 1000;
-            clientSocket.setSoTimeout(timeoutMillis);
-
-            // Set a small buffer size so we know we can flood it.
-            clientSocket.setSendBufferSize(100);
-            final int bufferSize = clientSocket.getSendBufferSize();
-
-            // Avoid blocking the test run if timeout doesn't happen by using a separate thread.
-            Callable<Result> writer = () -> {
-                try {
-                    byte[] toWrite = new byte[bufferSize * 2];
-                    clientSocket.getOutputStream().write(toWrite);
-                    return Result.noException("Did not block");
-                } catch (IOException e) {
-                    return Result.exception(e);
-                }
-            };
-            // Allow the configured timeout, plus some slop.
-            int allowedTime = timeoutMillis + 2000;
-
-            Result result = runInSeparateThread(allowedTime, writer);
-
-            // Check the message was a timeout, it's all we have to go on.
-            String expectedMessage = Os.strerror(OsConstants.EAGAIN);
-            result.assertThrewIOException(expectedMessage);
-        }
-    }
-
-    public void testAvailable() throws Exception {
-        String address = ADDRESS_PREFIX + "_testAvailable";
-
-        try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) {
-            LocalSocket clientSocket = socketPair.clientSocket;
-            LocalSocket serverSocket = socketPair.serverSocket.accept();
-
-            OutputStream clientOutputStream = clientSocket.getOutputStream();
-            InputStream serverInputStream = serverSocket.getInputStream();
-            assertEquals(0, serverInputStream.available());
-
-            byte[] buffer = new byte[50];
-            clientOutputStream.write(buffer);
-            assertEquals(50, serverInputStream.available());
-
-            InputStream clientInputStream = clientSocket.getInputStream();
-            OutputStream serverOutputStream = serverSocket.getOutputStream();
-            assertEquals(0, clientInputStream.available());
-            serverOutputStream.write(buffer);
-            assertEquals(50, serverInputStream.available());
-
-            serverSocket.close();
-        }
-    }
-
-    // http://b/34095140
-    public void testLocalSocketCreatedFromFileDescriptor() throws Exception {
-        String address = ADDRESS_PREFIX + "_testLocalSocketCreatedFromFileDescriptor";
-
-        // Establish connection between a local client and server to get a valid client socket file
-        // descriptor.
-        try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) {
-            // Extract the client FileDescriptor we can use.
-            FileDescriptor fileDescriptor = socketPair.clientSocket.getFileDescriptor();
-            assertTrue(fileDescriptor.valid());
-
-            // Create the LocalSocket we want to test.
-            LocalSocket clientSocketCreatedFromFileDescriptor =
-                    LocalSocket.createConnectedLocalSocket(fileDescriptor);
-            assertTrue(clientSocketCreatedFromFileDescriptor.isConnected());
-            assertTrue(clientSocketCreatedFromFileDescriptor.isBound());
-
-            // Test the LocalSocket can be used for communication.
-            LocalSocket serverSocket = socketPair.serverSocket.accept();
-            OutputStream clientOutputStream =
-                    clientSocketCreatedFromFileDescriptor.getOutputStream();
-            InputStream serverInputStream = serverSocket.getInputStream();
-
-            clientOutputStream.write(12);
-            assertEquals(12, serverInputStream.read());
-
-            // Closing clientSocketCreatedFromFileDescriptor does not close the file descriptor.
-            clientSocketCreatedFromFileDescriptor.close();
-            assertTrue(fileDescriptor.valid());
-
-            // .. while closing the LocalSocket that owned the file descriptor does.
-            socketPair.clientSocket.close();
-            assertFalse(fileDescriptor.valid());
-        }
-    }
-
-    public void testFlush() throws Exception {
-        String address = ADDRESS_PREFIX + "_testFlush";
-
-        try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) {
-            LocalSocket clientSocket = socketPair.clientSocket;
-            LocalSocket serverSocket = socketPair.serverSocket.accept();
-
-            OutputStream clientOutputStream = clientSocket.getOutputStream();
-            InputStream serverInputStream = serverSocket.getInputStream();
-            testFlushWorks(clientOutputStream, serverInputStream);
-
-            OutputStream serverOutputStream = serverSocket.getOutputStream();
-            InputStream clientInputStream = clientSocket.getInputStream();
-            testFlushWorks(serverOutputStream, clientInputStream);
-
-            serverSocket.close();
-        }
-    }
-
-    private void testFlushWorks(OutputStream outputStream, InputStream inputStream)
-            throws Exception {
-        final int bytesToTransfer = 50;
-        StreamReader inputStreamReader = new StreamReader(inputStream, bytesToTransfer);
-
-        byte[] buffer = new byte[bytesToTransfer];
-        outputStream.write(buffer);
-        assertEquals(bytesToTransfer, inputStream.available());
-
-        // Start consuming the data.
-        inputStreamReader.start();
-
-        // This doesn't actually flush any buffers, it just polls until the reader has read all the
-        // bytes.
-        outputStream.flush();
-
-        inputStreamReader.waitForCompletion(5000);
-        inputStreamReader.assertBytesRead(bytesToTransfer);
-        assertEquals(0, inputStream.available());
-    }
-
-    private static class StreamReader extends Thread {
-        private final InputStream is;
-        private final int expectedByteCount;
-        private final CountDownLatch completeLatch = new CountDownLatch(1);
-
-        private volatile Exception exception;
-        private int bytesRead;
-
-        private StreamReader(InputStream is, int expectedByteCount) {
-            this.is = is;
-            this.expectedByteCount = expectedByteCount;
-        }
-
-        @Override
-        public void run() {
-            try {
-                byte[] buffer = new byte[10];
-                int readCount;
-                while ((readCount = is.read(buffer)) >= 0) {
-                    bytesRead += readCount;
-                    if (bytesRead >= expectedByteCount) {
-                        break;
-                    }
-                }
-            } catch (IOException e) {
-                exception = e;
-            } finally {
-                completeLatch.countDown();
-            }
-        }
-
-        public void waitForCompletion(long waitMillis) throws Exception {
-            if (!completeLatch.await(waitMillis, TimeUnit.MILLISECONDS)) {
-                fail("Timeout waiting for completion");
-            }
-            if (exception != null) {
-                throw new Exception("Read failed", exception);
-            }
-        }
-
-        public void assertBytesRead(int expected) {
-            assertEquals(expected, bytesRead);
-        }
-    }
-
-    private static class Result {
-        private final String type;
-        private final Exception e;
-
-        private Result(String type, Exception e) {
-            this.type = type;
-            this.e = e;
-        }
-
-        static Result noException(String description) {
-            return new Result(description, null);
-        }
-
-        static Result exception(Exception e) {
-            return new Result(e.getClass().getName(), e);
-        }
-
-        void assertThrewIOException(String expectedMessage) {
-            assertEquals("Unexpected result type", IOException.class.getName(), type);
-            assertEquals("Unexpected exception message", expectedMessage, e.getMessage());
-        }
-    }
-
-    private static Result runInSeparateThread(int allowedTime, final Callable<Result> callable)
-            throws Exception {
-        ExecutorService service = Executors.newSingleThreadScheduledExecutor();
-        Future<Result> future = service.submit(callable);
-        Result result = future.get(allowedTime, TimeUnit.MILLISECONDS);
-        if (!future.isDone()) {
-            fail("Worker thread appears blocked");
-        }
-        return result;
-    }
-
-    private static class LocalSocketPair implements AutoCloseable {
-        static LocalSocketPair createConnectedSocketPair(String address) throws Exception {
-            LocalServerSocket localServerSocket = new LocalServerSocket(address);
-            final LocalSocket clientSocket = new LocalSocket();
-
-            // Establish connection between client and server
-            LocalSocketAddress locSockAddr = new LocalSocketAddress(address);
-            clientSocket.connect(locSockAddr);
-            assertTrue(clientSocket.isConnected());
-            return new LocalSocketPair(localServerSocket, clientSocket);
-        }
-
-        final LocalServerSocket serverSocket;
-        final LocalSocket clientSocket;
-
-        LocalSocketPair(LocalServerSocket serverSocket, LocalSocket clientSocket) {
-            this.serverSocket = serverSocket;
-            this.clientSocket = clientSocket;
-        }
-
-        public void close() throws Exception {
-            serverSocket.close();
-            clientSocket.close();
-        }
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/MacAddressTest.java b/tests/cts/net/src/android/net/cts/MacAddressTest.java
deleted file mode 100644
index 3fd3bba..0000000
--- a/tests/cts/net/src/android/net/cts/MacAddressTest.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * 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 com.android.testutils.ParcelUtils.assertParcelSane;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.net.MacAddress;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.net.Inet6Address;
-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) {
-        }
-    }
-
-    @Test
-    public void testMatches() {
-        // match 4 bytes prefix
-        assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
-                MacAddress.fromString("aa:bb:cc:dd:00:00"),
-                MacAddress.fromString("ff:ff:ff:ff:00:00")));
-
-        // match bytes 0,1,2 and 5
-        assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
-                MacAddress.fromString("aa:bb:cc:00:00:11"),
-                MacAddress.fromString("ff:ff:ff:00:00:ff")));
-
-        // match 34 bit prefix
-        assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
-                MacAddress.fromString("aa:bb:cc:dd:c0:00"),
-                MacAddress.fromString("ff:ff:ff:ff:c0:00")));
-
-        // fail to match 36 bit prefix
-        assertFalse(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
-                MacAddress.fromString("aa:bb:cc:dd:40:00"),
-                MacAddress.fromString("ff:ff:ff:ff:f0:00")));
-
-        // match all 6 bytes
-        assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
-                MacAddress.fromString("aa:bb:cc:dd:ee:11"),
-                MacAddress.fromString("ff:ff:ff:ff:ff:ff")));
-
-        // match none of 6 bytes
-        assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
-                MacAddress.fromString("00:00:00:00:00:00"),
-                MacAddress.fromString("00:00:00:00:00:00")));
-    }
-
-    /**
-     * Tests that link-local address generation from MAC is valid.
-     */
-    @Test
-    public void testLinkLocalFromMacGeneration() {
-        final MacAddress mac = MacAddress.fromString("52:74:f2:b1:a8:7f");
-        final byte[] inet6ll = {(byte) 0xfe, (byte) 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
-                0x74, (byte) 0xf2, (byte) 0xff, (byte) 0xfe, (byte) 0xb1, (byte) 0xa8, 0x7f};
-        final Inet6Address llv6 = mac.getLinkLocalIpv6FromEui48Mac();
-        assertTrue(llv6.isLinkLocalAddress());
-        assertArrayEquals(inet6ll, llv6.getAddress());
-    }
-
-    @Test
-    public void testParcelMacAddress() {
-        final MacAddress mac = MacAddress.fromString("52:74:f2:b1:a8:7f");
-
-        assertParcelSane(mac, 1);
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/MailToTest.java b/tests/cts/net/src/android/net/cts/MailToTest.java
deleted file mode 100644
index e454d20..0000000
--- a/tests/cts/net/src/android/net/cts/MailToTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-import android.net.MailTo;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-public class MailToTest extends AndroidTestCase {
-    private static final String MAILTOURI_1 = "mailto:chris@example.com";
-    private static final String MAILTOURI_2 = "mailto:infobot@example.com?subject=current-issue";
-    private static final String MAILTOURI_3 =
-            "mailto:infobot@example.com?body=send%20current-issue";
-    private static final String MAILTOURI_4 = "mailto:infobot@example.com?body=send%20current-" +
-                                              "issue%0D%0Asend%20index";
-    private static final String MAILTOURI_5 = "mailto:joe@example.com?" +
-                                              "cc=bob@example.com&body=hello";
-    private static final String MAILTOURI_6 = "mailto:?to=joe@example.com&" +
-                                              "cc=bob@example.com&body=hello";
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    public void testParseMailToURI() {
-        assertFalse(MailTo.isMailTo(null));
-        assertFalse(MailTo.isMailTo(""));
-        assertFalse(MailTo.isMailTo("http://www.google.com"));
-
-        assertTrue(MailTo.isMailTo(MAILTOURI_1));
-        MailTo mailTo_1 = MailTo.parse(MAILTOURI_1);
-        Log.d("Trace", mailTo_1.toString());
-        assertEquals("chris@example.com", mailTo_1.getTo());
-        assertEquals(1, mailTo_1.getHeaders().size());
-        assertNull(mailTo_1.getBody());
-        assertNull(mailTo_1.getCc());
-        assertNull(mailTo_1.getSubject());
-        assertEquals("mailto:?to=chris%40example.com&", mailTo_1.toString());
-
-        assertTrue(MailTo.isMailTo(MAILTOURI_2));
-        MailTo mailTo_2 = MailTo.parse(MAILTOURI_2);
-        Log.d("Trace", mailTo_2.toString());
-        assertEquals(2, mailTo_2.getHeaders().size());
-        assertEquals("infobot@example.com", mailTo_2.getTo());
-        assertEquals("current-issue", mailTo_2.getSubject());
-        assertNull(mailTo_2.getBody());
-        assertNull(mailTo_2.getCc());
-        String stringUrl = mailTo_2.toString();
-        assertTrue(stringUrl.startsWith("mailto:?"));
-        assertTrue(stringUrl.contains("to=infobot%40example.com&"));
-        assertTrue(stringUrl.contains("subject=current-issue&"));
-
-        assertTrue(MailTo.isMailTo(MAILTOURI_3));
-        MailTo mailTo_3 = MailTo.parse(MAILTOURI_3);
-        Log.d("Trace", mailTo_3.toString());
-        assertEquals(2, mailTo_3.getHeaders().size());
-        assertEquals("infobot@example.com", mailTo_3.getTo());
-        assertEquals("send current-issue", mailTo_3.getBody());
-        assertNull(mailTo_3.getCc());
-        assertNull(mailTo_3.getSubject());
-        stringUrl = mailTo_3.toString();
-        assertTrue(stringUrl.startsWith("mailto:?"));
-        assertTrue(stringUrl.contains("to=infobot%40example.com&"));
-        assertTrue(stringUrl.contains("body=send%20current-issue&"));
-
-        assertTrue(MailTo.isMailTo(MAILTOURI_4));
-        MailTo mailTo_4 = MailTo.parse(MAILTOURI_4);
-        Log.d("Trace", mailTo_4.toString() + " " + mailTo_4.getBody());
-        assertEquals(2, mailTo_4.getHeaders().size());
-        assertEquals("infobot@example.com", mailTo_4.getTo());
-        assertEquals("send current-issue\r\nsend index", mailTo_4.getBody());
-        assertNull(mailTo_4.getCc());
-        assertNull(mailTo_4.getSubject());
-        stringUrl = mailTo_4.toString();
-        assertTrue(stringUrl.startsWith("mailto:?"));
-        assertTrue(stringUrl.contains("to=infobot%40example.com&"));
-        assertTrue(stringUrl.contains("body=send%20current-issue%0D%0Asend%20index&"));
-
-
-        assertTrue(MailTo.isMailTo(MAILTOURI_5));
-        MailTo mailTo_5 = MailTo.parse(MAILTOURI_5);
-        Log.d("Trace", mailTo_5.toString() + mailTo_5.getHeaders().toString()
-                + mailTo_5.getHeaders().size());
-        assertEquals(3, mailTo_5.getHeaders().size());
-        assertEquals("joe@example.com", mailTo_5.getTo());
-        assertEquals("bob@example.com", mailTo_5.getCc());
-        assertEquals("hello", mailTo_5.getBody());
-        assertNull(mailTo_5.getSubject());
-        stringUrl = mailTo_5.toString();
-        assertTrue(stringUrl.startsWith("mailto:?"));
-        assertTrue(stringUrl.contains("cc=bob%40example.com&"));
-        assertTrue(stringUrl.contains("body=hello&"));
-        assertTrue(stringUrl.contains("to=joe%40example.com&"));
-
-        assertTrue(MailTo.isMailTo(MAILTOURI_6));
-        MailTo mailTo_6 = MailTo.parse(MAILTOURI_6);
-        Log.d("Trace", mailTo_6.toString() + mailTo_6.getHeaders().toString()
-                + mailTo_6.getHeaders().size());
-        assertEquals(3, mailTo_6.getHeaders().size());
-        assertEquals(", joe@example.com", mailTo_6.getTo());
-        assertEquals("bob@example.com", mailTo_6.getCc());
-        assertEquals("hello", mailTo_6.getBody());
-        assertNull(mailTo_6.getSubject());
-        stringUrl = mailTo_6.toString();
-        assertTrue(stringUrl.startsWith("mailto:?"));
-        assertTrue(stringUrl.contains("cc=bob%40example.com&"));
-        assertTrue(stringUrl.contains("body=hello&"));
-        assertTrue(stringUrl.contains("to=%2C%20joe%40example.com&"));
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/MultinetworkApiTest.java b/tests/cts/net/src/android/net/cts/MultinetworkApiTest.java
deleted file mode 100644
index 6d3db89..0000000
--- a/tests/cts/net/src/android/net/cts/MultinetworkApiTest.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2015 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.TRANSPORT_CELLULAR;
-
-import android.content.Context;
-import android.content.ContentResolver;
-import android.net.ConnectivityManager;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkUtils;
-import android.net.cts.util.CtsNetUtils;
-import android.platform.test.annotations.AppModeFull;
-import android.provider.Settings;
-import android.system.ErrnoException;
-import android.system.OsConstants;
-import android.test.AndroidTestCase;
-
-import java.util.ArrayList;
-
-public class MultinetworkApiTest extends AndroidTestCase {
-
-    static {
-        System.loadLibrary("nativemultinetwork_jni");
-    }
-
-    private static final String TAG = "MultinetworkNativeApiTest";
-    static final String GOOGLE_PRIVATE_DNS_SERVER = "dns.google";
-
-    /**
-     * @return 0 on success
-     */
-    private static native int runGetaddrinfoCheck(long networkHandle);
-    private static native int runSetprocnetwork(long networkHandle);
-    private static native int runSetsocknetwork(long networkHandle);
-    private static native int runDatagramCheck(long networkHandle);
-    private static native void runResNapiMalformedCheck(long networkHandle);
-    private static native void runResNcancelCheck(long networkHandle);
-    private static native void runResNqueryCheck(long networkHandle);
-    private static native void runResNsendCheck(long networkHandle);
-    private static native void runResNnxDomainCheck(long networkHandle);
-
-
-    private ContentResolver mCR;
-    private ConnectivityManager mCM;
-    private CtsNetUtils mCtsNetUtils;
-    private String mOldMode;
-    private String mOldDnsSpecifier;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
-        mCR = getContext().getContentResolver();
-        mCtsNetUtils = new CtsNetUtils(getContext());
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    private Network[] getTestableNetworks() {
-        final ArrayList<Network> testableNetworks = new ArrayList<Network>();
-        for (Network network : mCM.getAllNetworks()) {
-            final NetworkCapabilities nc = mCM.getNetworkCapabilities(network);
-            if (nc != null
-                    && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
-                    && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
-                testableNetworks.add(network);
-            }
-        }
-
-        assertTrue(
-                "This test requires that at least one network be connected. " +
-                "Please ensure that the device is connected to a network.",
-                testableNetworks.size() >= 1);
-        return testableNetworks.toArray(new Network[0]);
-    }
-
-    public void testGetaddrinfo() throws ErrnoException {
-        for (Network network : getTestableNetworks()) {
-            int errno = runGetaddrinfoCheck(network.getNetworkHandle());
-            if (errno != 0) {
-                throw new ErrnoException(
-                        "getaddrinfo on " + mCM.getNetworkInfo(network), -errno);
-            }
-        }
-    }
-
-    public void testSetprocnetwork() throws ErrnoException {
-        // Hopefully no prior test in this process space has set a default network.
-        assertNull(mCM.getProcessDefaultNetwork());
-        assertEquals(0, NetworkUtils.getBoundNetworkForProcess());
-
-        for (Network network : getTestableNetworks()) {
-            mCM.setProcessDefaultNetwork(null);
-            assertNull(mCM.getProcessDefaultNetwork());
-
-            int errno = runSetprocnetwork(network.getNetworkHandle());
-            if (errno != 0) {
-                throw new ErrnoException(
-                        "setprocnetwork on " + mCM.getNetworkInfo(network), -errno);
-            }
-            Network processDefault = mCM.getProcessDefaultNetwork();
-            assertNotNull(processDefault);
-            assertEquals(network, processDefault);
-            // TODO: open DatagramSockets, connect them to 192.0.2.1 and 2001:db8::,
-            // and ensure that the source address is in fact on this network as
-            // determined by mCM.getLinkProperties(network).
-
-            mCM.setProcessDefaultNetwork(null);
-        }
-
-        for (Network network : getTestableNetworks()) {
-            NetworkUtils.bindProcessToNetwork(0);
-            assertNull(mCM.getBoundNetworkForProcess());
-
-            int errno = runSetprocnetwork(network.getNetworkHandle());
-            if (errno != 0) {
-                throw new ErrnoException(
-                        "setprocnetwork on " + mCM.getNetworkInfo(network), -errno);
-            }
-            assertEquals(network, new Network(mCM.getBoundNetworkForProcess()));
-            // TODO: open DatagramSockets, connect them to 192.0.2.1 and 2001:db8::,
-            // and ensure that the source address is in fact on this network as
-            // determined by mCM.getLinkProperties(network).
-
-            NetworkUtils.bindProcessToNetwork(0);
-        }
-    }
-
-    public void testSetsocknetwork() throws ErrnoException {
-        for (Network network : getTestableNetworks()) {
-            int errno = runSetsocknetwork(network.getNetworkHandle());
-            if (errno != 0) {
-                throw new ErrnoException(
-                        "setsocknetwork on " + mCM.getNetworkInfo(network), -errno);
-            }
-        }
-    }
-
-    public void testNativeDatagramTransmission() throws ErrnoException {
-        for (Network network : getTestableNetworks()) {
-            int errno = runDatagramCheck(network.getNetworkHandle());
-            if (errno != 0) {
-                throw new ErrnoException(
-                        "DatagramCheck on " + mCM.getNetworkInfo(network), -errno);
-            }
-        }
-    }
-
-    public void testNoSuchNetwork() {
-        final Network eNoNet = new Network(54321);
-        assertNull(mCM.getNetworkInfo(eNoNet));
-
-        final long eNoNetHandle = eNoNet.getNetworkHandle();
-        assertEquals(-OsConstants.ENONET, runSetsocknetwork(eNoNetHandle));
-        assertEquals(-OsConstants.ENONET, runSetprocnetwork(eNoNetHandle));
-        // TODO: correct test permissions so this call is not silently re-mapped
-        // 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) {}
-    }
-
-    public void testResNApi() throws Exception {
-        final Network[] testNetworks = getTestableNetworks();
-
-        for (Network network : testNetworks) {
-            // Throws AssertionError directly in jni function if test fail.
-            runResNqueryCheck(network.getNetworkHandle());
-            runResNsendCheck(network.getNetworkHandle());
-            runResNcancelCheck(network.getNetworkHandle());
-            runResNapiMalformedCheck(network.getNetworkHandle());
-
-            final NetworkCapabilities nc = mCM.getNetworkCapabilities(network);
-            // Some cellular networks configure their DNS servers never to return NXDOMAIN, so don't
-            // test NXDOMAIN on these DNS servers.
-            // b/144521720
-            if (nc != null && !nc.hasTransport(TRANSPORT_CELLULAR)) {
-                runResNnxDomainCheck(network.getNetworkHandle());
-            }
-        }
-    }
-
-    @AppModeFull(reason = "WRITE_SECURE_SETTINGS permission can't be granted to instant apps")
-    public void testResNApiNXDomainPrivateDns() throws InterruptedException {
-        mCtsNetUtils.storePrivateDnsSetting();
-        // Enable private DNS strict mode and set server to dns.google before doing NxDomain test.
-        // b/144521720
-        try {
-            mCtsNetUtils.setPrivateDnsStrictMode(GOOGLE_PRIVATE_DNS_SERVER);
-            for (Network network : getTestableNetworks()) {
-              // Wait for private DNS setting to propagate.
-              mCtsNetUtils.awaitPrivateDnsSetting("NxDomain test wait private DNS setting timeout",
-                        network, GOOGLE_PRIVATE_DNS_SERVER, true);
-              runResNnxDomainCheck(network.getNetworkHandle());
-            }
-        } finally {
-            mCtsNetUtils.restorePrivateDnsSetting();
-        }
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
deleted file mode 100644
index d2ca3f8..0000000
--- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
+++ /dev/null
@@ -1,641 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net.cts
-
-import android.app.Instrumentation
-import android.content.Context
-import android.net.ConnectivityManager
-import android.net.KeepalivePacketData
-import android.net.LinkAddress
-import android.net.LinkProperties
-import android.net.Network
-import android.net.NetworkAgent
-import android.net.NetworkAgent.CMD_ADD_KEEPALIVE_PACKET_FILTER
-import android.net.NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT
-import android.net.NetworkAgent.CMD_REMOVE_KEEPALIVE_PACKET_FILTER
-import android.net.NetworkAgent.CMD_REPORT_NETWORK_STATUS
-import android.net.NetworkAgent.CMD_SAVE_ACCEPT_UNVALIDATED
-import android.net.NetworkAgent.CMD_START_SOCKET_KEEPALIVE
-import android.net.NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE
-import android.net.NetworkAgent.INVALID_NETWORK
-import android.net.NetworkAgent.VALID_NETWORK
-import android.net.NetworkAgentConfig
-import android.net.NetworkCapabilities
-import android.net.NetworkProvider
-import android.net.NetworkRequest
-import android.net.SocketKeepalive
-import android.net.StringNetworkSpecifier
-import android.net.Uri
-import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnAddKeepalivePacketFilter
-import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnAutomaticReconnectDisabled
-import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnBandwidthUpdateRequested
-import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnNetworkUnwanted
-import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnRemoveKeepalivePacketFilter
-import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnSaveAcceptUnvalidated
-import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnSignalStrengthThresholdsUpdated
-import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStartSocketKeepalive
-import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStopSocketKeepalive
-import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnValidationStatus
-import android.os.Build
-import android.os.Bundle
-import android.os.Handler
-import android.os.HandlerThread
-import android.os.Looper
-import android.os.Message
-import android.os.Messenger
-import androidx.test.InstrumentationRegistry
-import androidx.test.runner.AndroidJUnit4
-import com.android.internal.util.AsyncChannel
-import com.android.net.module.util.ArrayTrackRecord
-import com.android.testutils.DevSdkIgnoreRule
-import com.android.testutils.RecorderCallback.CallbackEntry.Available
-import com.android.testutils.RecorderCallback.CallbackEntry.Lost
-import com.android.testutils.TestableNetworkCallback
-import org.junit.After
-import org.junit.Assert.assertArrayEquals
-import org.junit.Assert.fail
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-import java.net.InetAddress
-import java.time.Duration
-import java.util.UUID
-import kotlin.test.assertEquals
-import kotlin.test.assertFailsWith
-import kotlin.test.assertFalse
-import kotlin.test.assertNotNull
-import kotlin.test.assertNull
-import kotlin.test.assertTrue
-
-// This test doesn't really have a constraint on how fast the methods should return. If it's
-// going to fail, it will simply wait forever, so setting a high timeout lowers the flake ratio
-// without affecting the run time of successful runs. Thus, set a very high timeout.
-private const val DEFAULT_TIMEOUT_MS = 5000L
-// When waiting for a NetworkCallback to determine there was no timeout, waiting is the
-// only possible thing (the relevant handler is the one in the real ConnectivityService,
-// and then there is the Binder call), so have a short timeout for this as it will be
-// exhausted every time.
-private const val NO_CALLBACK_TIMEOUT = 200L
-// Any legal score (0~99) for the test network would do, as it is going to be kept up by the
-// requests filed by the test and should never match normal internet requests. 70 is the default
-// score of Ethernet networks, it's as good a value as any other.
-private const val TEST_NETWORK_SCORE = 70
-private const val BETTER_NETWORK_SCORE = 75
-private const val FAKE_NET_ID = 1098
-private val instrumentation: Instrumentation
-    get() = InstrumentationRegistry.getInstrumentation()
-private val context: Context
-    get() = InstrumentationRegistry.getContext()
-private fun Message(what: Int, arg1: Int, arg2: Int, obj: Any?) = Message.obtain().also {
-    it.what = what
-    it.arg1 = arg1
-    it.arg2 = arg2
-    it.obj = obj
-}
-
-@RunWith(AndroidJUnit4::class)
-class NetworkAgentTest {
-    @Rule @JvmField
-    val ignoreRule = DevSdkIgnoreRule(ignoreClassUpTo = Build.VERSION_CODES.Q)
-
-    private val LOCAL_IPV4_ADDRESS = InetAddress.parseNumericAddress("192.0.2.1")
-    private val REMOTE_IPV4_ADDRESS = InetAddress.parseNumericAddress("192.0.2.2")
-
-    private val mCM = context.getSystemService(ConnectivityManager::class.java)
-    private val mHandlerThread = HandlerThread("${javaClass.simpleName} handler thread")
-    private val mFakeConnectivityService by lazy { FakeConnectivityService(mHandlerThread.looper) }
-
-    private class Provider(context: Context, looper: Looper) :
-            NetworkProvider(context, looper, "NetworkAgentTest NetworkProvider")
-
-    private val agentsToCleanUp = mutableListOf<NetworkAgent>()
-    private val callbacksToCleanUp = mutableListOf<TestableNetworkCallback>()
-
-    @Before
-    fun setUp() {
-        instrumentation.getUiAutomation().adoptShellPermissionIdentity()
-        mHandlerThread.start()
-    }
-
-    @After
-    fun tearDown() {
-        agentsToCleanUp.forEach { it.unregister() }
-        callbacksToCleanUp.forEach { mCM.unregisterNetworkCallback(it) }
-        mHandlerThread.quitSafely()
-        instrumentation.getUiAutomation().dropShellPermissionIdentity()
-    }
-
-    /**
-     * A fake that helps simulating ConnectivityService talking to a harnessed agent.
-     * This fake only supports speaking to one harnessed agent at a time because it
-     * only keeps track of one async channel.
-     */
-    private class FakeConnectivityService(looper: Looper) {
-        private val CMD_EXPECT_DISCONNECT = 1
-        private var disconnectExpected = false
-        private val msgHistory = ArrayTrackRecord<Message>().newReadHead()
-        private val asyncChannel = AsyncChannel()
-        private val handler = object : Handler(looper) {
-            override fun handleMessage(msg: Message) {
-                msgHistory.add(Message.obtain(msg)) // make a copy as the original will be recycled
-                when (msg.what) {
-                    CMD_EXPECT_DISCONNECT -> disconnectExpected = true
-                    AsyncChannel.CMD_CHANNEL_HALF_CONNECTED ->
-                        asyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION)
-                    AsyncChannel.CMD_CHANNEL_DISCONNECTED ->
-                        if (!disconnectExpected) {
-                            fail("Agent unexpectedly disconnected")
-                        } else {
-                            disconnectExpected = false
-                        }
-                }
-            }
-        }
-
-        fun connect(agentMsngr: Messenger) = asyncChannel.connect(context, handler, agentMsngr)
-
-        fun disconnect() = asyncChannel.disconnect()
-
-        fun sendMessage(what: Int, arg1: Int = 0, arg2: Int = 0, obj: Any? = null) =
-            asyncChannel.sendMessage(Message(what, arg1, arg2, obj))
-
-        fun expectMessage(what: Int) =
-            assertNotNull(msgHistory.poll(DEFAULT_TIMEOUT_MS) { it.what == what })
-
-        fun willExpectDisconnectOnce() = handler.sendEmptyMessage(CMD_EXPECT_DISCONNECT)
-    }
-
-    private open class TestableNetworkAgent(
-        looper: Looper,
-        val nc: NetworkCapabilities,
-        val lp: LinkProperties,
-        conf: NetworkAgentConfig
-    ) : NetworkAgent(context, looper, TestableNetworkAgent::class.java.simpleName /* tag */,
-            nc, lp, TEST_NETWORK_SCORE, conf, Provider(context, looper)) {
-        private val history = ArrayTrackRecord<CallbackEntry>().newReadHead()
-
-        sealed class CallbackEntry {
-            object OnBandwidthUpdateRequested : CallbackEntry()
-            object OnNetworkUnwanted : CallbackEntry()
-            data class OnAddKeepalivePacketFilter(
-                val slot: Int,
-                val packet: KeepalivePacketData
-            ) : CallbackEntry()
-            data class OnRemoveKeepalivePacketFilter(val slot: Int) : CallbackEntry()
-            data class OnStartSocketKeepalive(
-                val slot: Int,
-                val interval: Int,
-                val packet: KeepalivePacketData
-            ) : CallbackEntry()
-            data class OnStopSocketKeepalive(val slot: Int) : CallbackEntry()
-            data class OnSaveAcceptUnvalidated(val accept: Boolean) : CallbackEntry()
-            object OnAutomaticReconnectDisabled : CallbackEntry()
-            data class OnValidationStatus(val status: Int, val uri: Uri?) : CallbackEntry()
-            data class OnSignalStrengthThresholdsUpdated(val thresholds: IntArray) : CallbackEntry()
-        }
-
-        fun getName(): String? = (nc.getNetworkSpecifier() as? StringNetworkSpecifier)?.specifier
-
-        override fun onBandwidthUpdateRequested() {
-            history.add(OnBandwidthUpdateRequested)
-        }
-
-        override fun onNetworkUnwanted() {
-            history.add(OnNetworkUnwanted)
-        }
-
-        override fun onAddKeepalivePacketFilter(slot: Int, packet: KeepalivePacketData) {
-            history.add(OnAddKeepalivePacketFilter(slot, packet))
-        }
-
-        override fun onRemoveKeepalivePacketFilter(slot: Int) {
-            history.add(OnRemoveKeepalivePacketFilter(slot))
-        }
-
-        override fun onStartSocketKeepalive(
-            slot: Int,
-            interval: Duration,
-            packet: KeepalivePacketData
-        ) {
-            history.add(OnStartSocketKeepalive(slot, interval.seconds.toInt(), packet))
-        }
-
-        override fun onStopSocketKeepalive(slot: Int) {
-            history.add(OnStopSocketKeepalive(slot))
-        }
-
-        override fun onSaveAcceptUnvalidated(accept: Boolean) {
-            history.add(OnSaveAcceptUnvalidated(accept))
-        }
-
-        override fun onAutomaticReconnectDisabled() {
-            history.add(OnAutomaticReconnectDisabled)
-        }
-
-        override fun onSignalStrengthThresholdsUpdated(thresholds: IntArray) {
-            history.add(OnSignalStrengthThresholdsUpdated(thresholds))
-        }
-
-        fun expectEmptySignalStrengths() {
-            expectCallback<OnSignalStrengthThresholdsUpdated>().let {
-                // intArrayOf() without arguments makes an empty array
-                assertArrayEquals(intArrayOf(), it.thresholds)
-            }
-        }
-
-        override fun onValidationStatus(status: Int, uri: Uri?) {
-            history.add(OnValidationStatus(status, uri))
-        }
-
-        // Expects the initial validation event that always occurs immediately after registering
-        // a NetworkAgent whose network does not require validation (which test networks do
-        // not, since they lack the INTERNET capability). It always contains the default argument
-        // for the URI.
-        fun expectNoInternetValidationStatus() = expectCallback<OnValidationStatus>().let {
-            assertEquals(it.status, VALID_NETWORK)
-            // The returned Uri is parsed from the empty string, which means it's an
-            // instance of the (private) Uri.StringUri. There are no real good ways
-            // to check this, the least bad is to just convert it to a string and
-            // make sure it's empty.
-            assertEquals("", it.uri.toString())
-        }
-
-        inline fun <reified T : CallbackEntry> expectCallback(): T {
-            val foundCallback = history.poll(DEFAULT_TIMEOUT_MS)
-            assertTrue(foundCallback is T, "Expected ${T::class} but found $foundCallback")
-            return foundCallback
-        }
-
-        fun assertNoCallback() {
-            assertTrue(waitForIdle(DEFAULT_TIMEOUT_MS),
-                    "Handler didn't became idle after ${DEFAULT_TIMEOUT_MS}ms")
-            assertNull(history.peek())
-        }
-    }
-
-    private fun requestNetwork(request: NetworkRequest, callback: TestableNetworkCallback) {
-        mCM.requestNetwork(request, callback)
-        callbacksToCleanUp.add(callback)
-    }
-
-    private fun registerNetworkCallback(
-        request: NetworkRequest,
-        callback: TestableNetworkCallback
-    ) {
-        mCM.registerNetworkCallback(request, callback)
-        callbacksToCleanUp.add(callback)
-    }
-
-    private fun createNetworkAgent(name: String? = null): TestableNetworkAgent {
-        val nc = NetworkCapabilities().apply {
-            addTransportType(NetworkCapabilities.TRANSPORT_TEST)
-            removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
-            removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-            addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)
-            addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)
-            addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
-            if (null != name) {
-                setNetworkSpecifier(StringNetworkSpecifier(name))
-            }
-        }
-        val lp = LinkProperties().apply {
-            addLinkAddress(LinkAddress(LOCAL_IPV4_ADDRESS, 0))
-        }
-        val config = NetworkAgentConfig.Builder().build()
-        return TestableNetworkAgent(mHandlerThread.looper, nc, lp, config).also {
-            agentsToCleanUp.add(it)
-        }
-    }
-
-    private fun createConnectedNetworkAgent(name: String? = null):
-            Pair<TestableNetworkAgent, TestableNetworkCallback> {
-        val request: NetworkRequest = NetworkRequest.Builder()
-                .clearCapabilities()
-                .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
-                .build()
-        val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
-        requestNetwork(request, callback)
-        val agent = createNetworkAgent(name)
-        agent.register()
-        agent.markConnected()
-        return agent to callback
-    }
-
-    private fun createNetworkAgentWithFakeCS() = createNetworkAgent().also {
-        mFakeConnectivityService.connect(it.registerForTest(Network(FAKE_NET_ID)))
-    }
-
-    @Test
-    fun testConnectAndUnregister() {
-        val (agent, callback) = createConnectedNetworkAgent()
-        callback.expectAvailableThenValidatedCallbacks(agent.network)
-        agent.expectEmptySignalStrengths()
-        agent.expectNoInternetValidationStatus()
-        agent.unregister()
-        callback.expectCallback<Lost>(agent.network)
-        agent.expectCallback<OnNetworkUnwanted>()
-        assertFailsWith<IllegalStateException>("Must not be able to register an agent twice") {
-            agent.register()
-        }
-    }
-
-    @Test
-    fun testOnBandwidthUpdateRequested() {
-        val (agent, callback) = createConnectedNetworkAgent()
-        callback.expectAvailableThenValidatedCallbacks(agent.network)
-        agent.expectEmptySignalStrengths()
-        agent.expectNoInternetValidationStatus()
-        mCM.requestBandwidthUpdate(agent.network)
-        agent.expectCallback<OnBandwidthUpdateRequested>()
-        agent.unregister()
-    }
-
-    @Test
-    fun testSignalStrengthThresholds() {
-        val thresholds = intArrayOf(30, 50, 65)
-        val callbacks = thresholds.map { strength ->
-            val request = NetworkRequest.Builder()
-                    .clearCapabilities()
-                    .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
-                    .setSignalStrength(strength)
-                    .build()
-            TestableNetworkCallback(DEFAULT_TIMEOUT_MS).also {
-                registerNetworkCallback(request, it)
-            }
-        }
-        createConnectedNetworkAgent().let { (agent, callback) ->
-            callback.expectAvailableThenValidatedCallbacks(agent.network)
-            agent.expectCallback<OnSignalStrengthThresholdsUpdated>().let {
-                assertArrayEquals(it.thresholds, thresholds)
-            }
-            agent.expectNoInternetValidationStatus()
-
-            // Send signal strength and check that the callbacks are called appropriately.
-            val nc = NetworkCapabilities(agent.nc)
-            nc.setSignalStrength(20)
-            agent.sendNetworkCapabilities(nc)
-            callbacks.forEach { it.assertNoCallback(NO_CALLBACK_TIMEOUT) }
-
-            nc.setSignalStrength(40)
-            agent.sendNetworkCapabilities(nc)
-            callbacks[0].expectAvailableCallbacks(agent.network)
-            callbacks[1].assertNoCallback(NO_CALLBACK_TIMEOUT)
-            callbacks[2].assertNoCallback(NO_CALLBACK_TIMEOUT)
-
-            nc.setSignalStrength(80)
-            agent.sendNetworkCapabilities(nc)
-            callbacks[0].expectCapabilitiesThat(agent.network) { it.signalStrength == 80 }
-            callbacks[1].expectAvailableCallbacks(agent.network)
-            callbacks[2].expectAvailableCallbacks(agent.network)
-
-            nc.setSignalStrength(55)
-            agent.sendNetworkCapabilities(nc)
-            callbacks[0].expectCapabilitiesThat(agent.network) { it.signalStrength == 55 }
-            callbacks[1].expectCapabilitiesThat(agent.network) { it.signalStrength == 55 }
-            callbacks[2].expectCallback<Lost>(agent.network)
-        }
-        callbacks.forEach {
-            mCM.unregisterNetworkCallback(it)
-        }
-    }
-
-    @Test
-    fun testSocketKeepalive(): Unit = createNetworkAgentWithFakeCS().let { agent ->
-        val packet = object : KeepalivePacketData(
-                LOCAL_IPV4_ADDRESS /* srcAddress */, 1234 /* srcPort */,
-                REMOTE_IPV4_ADDRESS /* dstAddress */, 4567 /* dstPort */,
-                ByteArray(100 /* size */) { it.toByte() /* init */ }) {}
-        val slot = 4
-        val interval = 37
-
-        mFakeConnectivityService.sendMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER,
-                arg1 = slot, obj = packet)
-        mFakeConnectivityService.sendMessage(CMD_START_SOCKET_KEEPALIVE,
-                arg1 = slot, arg2 = interval, obj = packet)
-
-        agent.expectCallback<OnAddKeepalivePacketFilter>().let {
-            assertEquals(it.slot, slot)
-            assertEquals(it.packet, packet)
-        }
-        agent.expectCallback<OnStartSocketKeepalive>().let {
-            assertEquals(it.slot, slot)
-            assertEquals(it.interval, interval)
-            assertEquals(it.packet, packet)
-        }
-
-        agent.assertNoCallback()
-
-        // Check that when the agent sends a keepalive event, ConnectivityService receives the
-        // expected message.
-        agent.sendSocketKeepaliveEvent(slot, SocketKeepalive.ERROR_UNSUPPORTED)
-        mFakeConnectivityService.expectMessage(NetworkAgent.EVENT_SOCKET_KEEPALIVE).let() {
-            assertEquals(slot, it.arg1)
-            assertEquals(SocketKeepalive.ERROR_UNSUPPORTED, it.arg2)
-        }
-
-        mFakeConnectivityService.sendMessage(CMD_STOP_SOCKET_KEEPALIVE, arg1 = slot)
-        mFakeConnectivityService.sendMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER, arg1 = slot)
-        agent.expectCallback<OnStopSocketKeepalive>().let {
-            assertEquals(it.slot, slot)
-        }
-        agent.expectCallback<OnRemoveKeepalivePacketFilter>().let {
-            assertEquals(it.slot, slot)
-        }
-    }
-
-    @Test
-    fun testSendUpdates(): Unit = createConnectedNetworkAgent().let { (agent, callback) ->
-        callback.expectAvailableThenValidatedCallbacks(agent.network)
-        agent.expectEmptySignalStrengths()
-        agent.expectNoInternetValidationStatus()
-        val ifaceName = "adhocIface"
-        val lp = LinkProperties(agent.lp)
-        lp.setInterfaceName(ifaceName)
-        agent.sendLinkProperties(lp)
-        callback.expectLinkPropertiesThat(agent.network) {
-            it.getInterfaceName() == ifaceName
-        }
-        val nc = NetworkCapabilities(agent.nc)
-        nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
-        agent.sendNetworkCapabilities(nc)
-        callback.expectCapabilitiesThat(agent.network) {
-            it.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
-        }
-    }
-
-    @Test
-    fun testSendScore() {
-        // This test will create two networks and check that the one with the stronger
-        // score wins out for a request that matches them both.
-        // First create requests to make sure both networks are kept up, using the
-        // specifier so they are specific to each network
-        val name1 = UUID.randomUUID().toString()
-        val name2 = UUID.randomUUID().toString()
-        val request1 = NetworkRequest.Builder()
-                .clearCapabilities()
-                .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
-                .setNetworkSpecifier(StringNetworkSpecifier(name1))
-                .build()
-        val request2 = NetworkRequest.Builder()
-                .clearCapabilities()
-                .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
-                .setNetworkSpecifier(StringNetworkSpecifier(name2))
-                .build()
-        val callback1 = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
-        val callback2 = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
-        requestNetwork(request1, callback1)
-        requestNetwork(request2, callback2)
-
-        // Then file the interesting request
-        val request = NetworkRequest.Builder()
-                .clearCapabilities()
-                .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
-                .build()
-        val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
-        requestNetwork(request, callback)
-
-        // Connect the first Network
-        createConnectedNetworkAgent(name1).let { (agent1, _) ->
-            callback.expectAvailableThenValidatedCallbacks(agent1.network)
-            // Upgrade agent1 to a better score so that there is no ambiguity when
-            // agent2 connects that agent1 is still better
-            agent1.sendNetworkScore(BETTER_NETWORK_SCORE - 1)
-            // Connect the second agent
-            createConnectedNetworkAgent(name2).let { (agent2, _) ->
-                agent2.markConnected()
-                // The callback should not see anything yet
-                callback.assertNoCallback(NO_CALLBACK_TIMEOUT)
-                // Now update the score and expect the callback now prefers agent2
-                agent2.sendNetworkScore(BETTER_NETWORK_SCORE)
-                callback.expectCallback<Available>(agent2.network)
-            }
-        }
-
-        // tearDown() will unregister the requests and agents
-    }
-
-    @Test
-    fun testSetAcceptUnvalidated() {
-        createNetworkAgentWithFakeCS().let { agent ->
-            mFakeConnectivityService.sendMessage(CMD_SAVE_ACCEPT_UNVALIDATED, 1)
-            agent.expectCallback<OnSaveAcceptUnvalidated>().let {
-                assertTrue(it.accept)
-            }
-            agent.assertNoCallback()
-        }
-    }
-
-    @Test
-    fun testSetAcceptUnvalidatedPreventAutomaticReconnect() {
-        createNetworkAgentWithFakeCS().let { agent ->
-            mFakeConnectivityService.sendMessage(CMD_SAVE_ACCEPT_UNVALIDATED, 0)
-            mFakeConnectivityService.sendMessage(CMD_PREVENT_AUTOMATIC_RECONNECT)
-            agent.expectCallback<OnSaveAcceptUnvalidated>().let {
-                assertFalse(it.accept)
-            }
-            agent.expectCallback<OnAutomaticReconnectDisabled>()
-            agent.assertNoCallback()
-            // When automatic reconnect is turned off, the network is torn down and
-            // ConnectivityService sends a disconnect. This in turn causes the agent
-            // to send a DISCONNECTED message to CS.
-            mFakeConnectivityService.willExpectDisconnectOnce()
-            mFakeConnectivityService.disconnect()
-            mFakeConnectivityService.expectMessage(AsyncChannel.CMD_CHANNEL_DISCONNECTED)
-            agent.expectCallback<OnNetworkUnwanted>()
-        }
-    }
-
-    @Test
-    fun testPreventAutomaticReconnect() {
-        createNetworkAgentWithFakeCS().let { agent ->
-            mFakeConnectivityService.sendMessage(CMD_PREVENT_AUTOMATIC_RECONNECT)
-            agent.expectCallback<OnAutomaticReconnectDisabled>()
-            agent.assertNoCallback()
-            mFakeConnectivityService.willExpectDisconnectOnce()
-            mFakeConnectivityService.disconnect()
-            mFakeConnectivityService.expectMessage(AsyncChannel.CMD_CHANNEL_DISCONNECTED)
-            agent.expectCallback<OnNetworkUnwanted>()
-        }
-    }
-
-    @Test
-    fun testValidationStatus() = createNetworkAgentWithFakeCS().let { agent ->
-        val uri = Uri.parse("http://www.google.com")
-        val bundle = Bundle().apply {
-            putString(NetworkAgent.REDIRECT_URL_KEY, uri.toString())
-        }
-        mFakeConnectivityService.sendMessage(CMD_REPORT_NETWORK_STATUS,
-                arg1 = VALID_NETWORK, obj = bundle)
-        agent.expectCallback<OnValidationStatus>().let {
-            assertEquals(it.status, VALID_NETWORK)
-            assertEquals(it.uri, uri)
-        }
-
-        mFakeConnectivityService.sendMessage(CMD_REPORT_NETWORK_STATUS,
-                arg1 = INVALID_NETWORK, obj = Bundle())
-        agent.expectCallback<OnValidationStatus>().let {
-            assertEquals(it.status, INVALID_NETWORK)
-            assertNull(it.uri)
-        }
-    }
-
-    @Test
-    fun testTemporarilyUnmeteredCapability() {
-        // This test will create a networks with/without NET_CAPABILITY_TEMPORARILY_NOT_METERED
-        // and check that the callback reflects the capability changes.
-        // First create a request to make sure the network is kept up
-        val request1 = NetworkRequest.Builder()
-                .clearCapabilities()
-                .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
-                .build()
-        val callback1 = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS).also {
-            registerNetworkCallback(request1, it)
-        }
-        requestNetwork(request1, callback1)
-
-        // Then file the interesting request
-        val request = NetworkRequest.Builder()
-                .clearCapabilities()
-                .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
-                .build()
-        val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
-        requestNetwork(request, callback)
-
-        // Connect the network
-        createConnectedNetworkAgent().let { (agent, _) ->
-            callback.expectAvailableThenValidatedCallbacks(agent.network)
-
-            // Send TEMP_NOT_METERED and check that the callback is called appropriately.
-            val nc1 = NetworkCapabilities(agent.nc)
-                    .addCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED)
-            agent.sendNetworkCapabilities(nc1)
-            callback.expectCapabilitiesThat(agent.network) {
-                it.hasCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED)
-            }
-
-            // Remove TEMP_NOT_METERED and check that the callback is called appropriately.
-            val nc2 = NetworkCapabilities(agent.nc)
-                    .removeCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED)
-            agent.sendNetworkCapabilities(nc2)
-            callback.expectCapabilitiesThat(agent.network) {
-                !it.hasCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED)
-            }
-        }
-
-        // tearDown() will unregister the requests and agents
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.kt b/tests/cts/net/src/android/net/cts/NetworkInfoTest.kt
deleted file mode 100644
index fa15e8f..0000000
--- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.kt
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts
-
-import android.os.Build
-import android.content.Context
-import android.net.ConnectivityManager
-import android.net.NetworkInfo
-import android.net.NetworkInfo.DetailedState
-import android.net.NetworkInfo.State
-import android.telephony.TelephonyManager
-import androidx.test.filters.SmallTest
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.runner.AndroidJUnit4
-import com.android.testutils.DevSdkIgnoreRule
-import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertNotNull
-import org.junit.Assert.assertNull
-import org.junit.Assert.assertTrue
-import org.junit.Assert.fail
-import org.junit.Rule
-import org.junit.runner.RunWith
-import org.junit.Test
-
-const val TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE
-const val TYPE_WIFI = ConnectivityManager.TYPE_WIFI
-const val MOBILE_TYPE_NAME = "mobile"
-const val WIFI_TYPE_NAME = "WIFI"
-const val LTE_SUBTYPE_NAME = "LTE"
-
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class NetworkInfoTest {
-    @Rule @JvmField
-    val ignoreRule = DevSdkIgnoreRule()
-
-    @Test
-    fun testAccessNetworkInfoProperties() {
-        val cm = InstrumentationRegistry.getInstrumentation().context
-                .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
-        val ni = cm.getAllNetworkInfo()
-        assertTrue(ni.isNotEmpty())
-
-        for (netInfo in ni) {
-            when (netInfo.getType()) {
-                TYPE_MOBILE -> assertNetworkInfo(netInfo, MOBILE_TYPE_NAME)
-                TYPE_WIFI -> assertNetworkInfo(netInfo, WIFI_TYPE_NAME)
-                // TODO: Add BLUETOOTH_TETHER testing
-            }
-        }
-    }
-
-    private fun assertNetworkInfo(netInfo: NetworkInfo, expectedTypeName: String) {
-        assertTrue(expectedTypeName.equals(netInfo.getTypeName(), ignoreCase = true))
-        assertNotNull(netInfo.toString())
-
-        if (!netInfo.isConnectedOrConnecting()) return
-
-        assertTrue(netInfo.isAvailable())
-        if (State.CONNECTED == netInfo.getState()) {
-            assertTrue(netInfo.isConnected())
-        }
-        assertTrue(State.CONNECTING == netInfo.getState() ||
-                State.CONNECTED == netInfo.getState())
-        assertTrue(DetailedState.SCANNING == netInfo.getDetailedState() ||
-                DetailedState.CONNECTING == netInfo.getDetailedState() ||
-                DetailedState.AUTHENTICATING == netInfo.getDetailedState() ||
-                DetailedState.CONNECTED == netInfo.getDetailedState())
-    }
-
-    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
-    fun testConstructor() {
-        val networkInfo = NetworkInfo(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_LTE,
-                MOBILE_TYPE_NAME, LTE_SUBTYPE_NAME)
-
-        assertEquals(TYPE_MOBILE, networkInfo.type)
-        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, networkInfo.subtype)
-        assertEquals(MOBILE_TYPE_NAME, networkInfo.typeName)
-        assertEquals(LTE_SUBTYPE_NAME, networkInfo.subtypeName)
-        assertEquals(DetailedState.IDLE, networkInfo.detailedState)
-        assertEquals(State.UNKNOWN, networkInfo.state)
-        assertNull(networkInfo.reason)
-        assertNull(networkInfo.extraInfo)
-
-        try {
-            NetworkInfo(ConnectivityManager.MAX_NETWORK_TYPE + 1,
-                    TelephonyManager.NETWORK_TYPE_LTE, MOBILE_TYPE_NAME, LTE_SUBTYPE_NAME)
-            fail("Unexpected behavior. Network type is invalid.")
-        } catch (e: IllegalArgumentException) {
-            // Expected behavior.
-        }
-    }
-
-    @Test
-    fun testSetDetailedState() {
-        val networkInfo = NetworkInfo(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_LTE,
-                MOBILE_TYPE_NAME, LTE_SUBTYPE_NAME)
-        val reason = "TestNetworkInfo"
-        val extraReason = "setDetailedState test"
-
-        networkInfo.setDetailedState(DetailedState.CONNECTED, reason, extraReason)
-        assertEquals(DetailedState.CONNECTED, networkInfo.detailedState)
-        assertEquals(State.CONNECTED, networkInfo.state)
-        assertEquals(reason, networkInfo.reason)
-        assertEquals(extraReason, networkInfo.extraInfo)
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java
deleted file mode 100644
index 590ce89..0000000
--- a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-
-import android.net.NetworkInfo.DetailedState;
-import android.test.AndroidTestCase;
-
-public class NetworkInfo_DetailedStateTest extends AndroidTestCase {
-
-    public void testValueOf() {
-        assertEquals(DetailedState.AUTHENTICATING, DetailedState.valueOf("AUTHENTICATING"));
-        assertEquals(DetailedState.CONNECTED, DetailedState.valueOf("CONNECTED"));
-        assertEquals(DetailedState.CONNECTING, DetailedState.valueOf("CONNECTING"));
-        assertEquals(DetailedState.DISCONNECTED, DetailedState.valueOf("DISCONNECTED"));
-        assertEquals(DetailedState.DISCONNECTING, DetailedState.valueOf("DISCONNECTING"));
-        assertEquals(DetailedState.FAILED, DetailedState.valueOf("FAILED"));
-        assertEquals(DetailedState.IDLE, DetailedState.valueOf("IDLE"));
-        assertEquals(DetailedState.OBTAINING_IPADDR, DetailedState.valueOf("OBTAINING_IPADDR"));
-        assertEquals(DetailedState.SCANNING, DetailedState.valueOf("SCANNING"));
-        assertEquals(DetailedState.SUSPENDED, DetailedState.valueOf("SUSPENDED"));
-    }
-
-    public void testValues() {
-        DetailedState[] expected = DetailedState.values();
-        assertEquals(13, expected.length);
-        assertEquals(DetailedState.IDLE, expected[0]);
-        assertEquals(DetailedState.SCANNING, expected[1]);
-        assertEquals(DetailedState.CONNECTING, expected[2]);
-        assertEquals(DetailedState.AUTHENTICATING, expected[3]);
-        assertEquals(DetailedState.OBTAINING_IPADDR, expected[4]);
-        assertEquals(DetailedState.CONNECTED, expected[5]);
-        assertEquals(DetailedState.SUSPENDED, expected[6]);
-        assertEquals(DetailedState.DISCONNECTING, expected[7]);
-        assertEquals(DetailedState.DISCONNECTED, expected[8]);
-        assertEquals(DetailedState.FAILED, expected[9]);
-        assertEquals(DetailedState.BLOCKED, expected[10]);
-        assertEquals(DetailedState.VERIFYING_POOR_LINK, expected[11]);
-        assertEquals(DetailedState.CAPTIVE_PORTAL_CHECK, expected[12]);
-    }
-
-}
diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java
deleted file mode 100644
index 5303ef1..0000000
--- a/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-import android.net.NetworkInfo.State;
-import android.test.AndroidTestCase;
-
-public class NetworkInfo_StateTest extends AndroidTestCase {
-
-    public void testValueOf() {
-        assertEquals(State.CONNECTED, State.valueOf("CONNECTED"));
-        assertEquals(State.CONNECTING, State.valueOf("CONNECTING"));
-        assertEquals(State.DISCONNECTED, State.valueOf("DISCONNECTED"));
-        assertEquals(State.DISCONNECTING, State.valueOf("DISCONNECTING"));
-        assertEquals(State.SUSPENDED, State.valueOf("SUSPENDED"));
-        assertEquals(State.UNKNOWN, State.valueOf("UNKNOWN"));
-    }
-
-    public void testValues() {
-        State[] expected = State.values();
-        assertEquals(6, expected.length);
-        assertEquals(State.CONNECTING, expected[0]);
-        assertEquals(State.CONNECTED, expected[1]);
-        assertEquals(State.SUSPENDED, expected[2]);
-        assertEquals(State.DISCONNECTING, expected[3]);
-        assertEquals(State.DISCONNECTED, expected[4]);
-        assertEquals(State.UNKNOWN, expected[5]);
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java
deleted file mode 100644
index d118c8a..0000000
--- a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * 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_INTERNET;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED;
-import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH;
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.net.NetworkCapabilities.TRANSPORT_VPN;
-import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import android.net.MacAddress;
-import android.net.MatchAllNetworkSpecifier;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.net.NetworkSpecifier;
-import android.net.UidRange;
-import android.net.wifi.WifiNetworkSpecifier;
-import android.os.Build;
-import android.os.PatternMatcher;
-import android.os.Process;
-import android.util.ArraySet;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class NetworkRequestTest {
-    @Rule
-    public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
-
-    private static final String TEST_SSID = "TestSSID";
-    private static final String OTHER_SSID = "OtherSSID";
-    private static final int TEST_UID = 2097;
-    private static final String TEST_PACKAGE_NAME = "test.package.name";
-    private static final MacAddress ARBITRARY_ADDRESS = MacAddress.fromString("3:5:8:12:9:2");
-
-    private class LocalNetworkSpecifier extends NetworkSpecifier {
-        private final int mId;
-
-        LocalNetworkSpecifier(int id) {
-            mId = id;
-        }
-
-        @Override
-        public boolean canBeSatisfiedBy(NetworkSpecifier other) {
-            return other instanceof LocalNetworkSpecifier
-                && mId == ((LocalNetworkSpecifier) other).mId;
-        }
-    }
-
-    @Test
-    public void testCapabilities() {
-        assertTrue(new NetworkRequest.Builder().addCapability(NET_CAPABILITY_MMS).build()
-                .hasCapability(NET_CAPABILITY_MMS));
-        assertFalse(new NetworkRequest.Builder().removeCapability(NET_CAPABILITY_MMS).build()
-                .hasCapability(NET_CAPABILITY_MMS));
-
-        final NetworkRequest nr = new NetworkRequest.Builder().clearCapabilities().build();
-        // Verify request has no capabilities
-        verifyNoCapabilities(nr);
-    }
-
-    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
-    public void testTemporarilyNotMeteredCapability() {
-        assertTrue(new NetworkRequest.Builder()
-                .addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED).build()
-                .hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
-        assertFalse(new NetworkRequest.Builder()
-                .removeCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED).build()
-                .hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
-    }
-
-    private void verifyNoCapabilities(NetworkRequest nr) {
-        // NetworkCapabilities.mNetworkCapabilities is defined as type long
-        final int MAX_POSSIBLE_CAPABILITY = Long.SIZE;
-        for(int bit = 0; bit < MAX_POSSIBLE_CAPABILITY; bit++) {
-            assertFalse(nr.hasCapability(bit));
-        }
-    }
-
-    @Test
-    public void testTransports() {
-        assertTrue(new NetworkRequest.Builder().addTransportType(TRANSPORT_BLUETOOTH).build()
-                .hasTransport(TRANSPORT_BLUETOOTH));
-        assertFalse(new NetworkRequest.Builder().removeTransportType(TRANSPORT_BLUETOOTH).build()
-                .hasTransport(TRANSPORT_BLUETOOTH));
-    }
-
-    @Test
-    @IgnoreUpTo(Build.VERSION_CODES.Q)
-    public void testSpecifier() {
-        assertNull(new NetworkRequest.Builder().build().getNetworkSpecifier());
-        final WifiNetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
-                .setSsidPattern(new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL))
-                .setBssidPattern(ARBITRARY_ADDRESS, ARBITRARY_ADDRESS)
-                .build();
-        final NetworkSpecifier obtainedSpecifier = new NetworkRequest.Builder()
-                .addTransportType(TRANSPORT_WIFI)
-                .setNetworkSpecifier(specifier)
-                .build()
-                .getNetworkSpecifier();
-        assertEquals(obtainedSpecifier, specifier);
-
-        assertNull(new NetworkRequest.Builder()
-                .clearCapabilities()
-                .build()
-                .getNetworkSpecifier());
-    }
-
-    @Test
-    @IgnoreUpTo(Build.VERSION_CODES.Q)
-    public void testRequestorPackageName() {
-        assertNull(new NetworkRequest.Builder().build().getRequestorPackageName());
-        final String pkgName = "android.net.test";
-        final NetworkCapabilities nc = new NetworkCapabilities.Builder()
-                .setRequestorPackageName(pkgName)
-                .build();
-        final NetworkRequest nr = new NetworkRequest.Builder()
-                .setCapabilities(nc)
-                .build();
-        assertEquals(pkgName, nr.getRequestorPackageName());
-        assertNull(new NetworkRequest.Builder()
-                .clearCapabilities()
-                .build()
-                .getRequestorPackageName());
-    }
-
-    @Test
-    @IgnoreUpTo(Build.VERSION_CODES.Q)
-    public void testCanBeSatisfiedBy() {
-        final LocalNetworkSpecifier specifier1 = new LocalNetworkSpecifier(1234 /* id */);
-        final LocalNetworkSpecifier specifier2 = new LocalNetworkSpecifier(5678 /* id */);
-
-        final NetworkCapabilities capCellularMmsInternet = new NetworkCapabilities()
-                .addTransportType(TRANSPORT_CELLULAR)
-                .addCapability(NET_CAPABILITY_MMS)
-                .addCapability(NET_CAPABILITY_INTERNET);
-        final NetworkCapabilities capCellularVpnMmsInternet =
-                new NetworkCapabilities(capCellularMmsInternet).addTransportType(TRANSPORT_VPN);
-        final NetworkCapabilities capCellularMmsInternetSpecifier1 =
-                new NetworkCapabilities(capCellularMmsInternet).setNetworkSpecifier(specifier1);
-        final NetworkCapabilities capVpnInternetSpecifier1 = new NetworkCapabilities()
-                .addCapability(NET_CAPABILITY_INTERNET)
-                .addTransportType(TRANSPORT_VPN)
-                .setNetworkSpecifier(specifier1);
-        final NetworkCapabilities capCellularMmsInternetMatchallspecifier =
-                new NetworkCapabilities(capCellularMmsInternet)
-                    .setNetworkSpecifier(new MatchAllNetworkSpecifier());
-        final NetworkCapabilities capCellularMmsInternetSpecifier2 =
-                new NetworkCapabilities(capCellularMmsInternet).setNetworkSpecifier(specifier2);
-
-        final NetworkRequest requestCellularInternetSpecifier1 = new NetworkRequest.Builder()
-                .addTransportType(TRANSPORT_CELLULAR)
-                .addCapability(NET_CAPABILITY_INTERNET)
-                .setNetworkSpecifier(specifier1)
-                .build();
-        assertFalse(requestCellularInternetSpecifier1.canBeSatisfiedBy(null));
-        assertFalse(requestCellularInternetSpecifier1.canBeSatisfiedBy(new NetworkCapabilities()));
-        assertTrue(requestCellularInternetSpecifier1.canBeSatisfiedBy(
-                capCellularMmsInternetMatchallspecifier));
-        assertFalse(requestCellularInternetSpecifier1.canBeSatisfiedBy(capCellularMmsInternet));
-        assertTrue(requestCellularInternetSpecifier1.canBeSatisfiedBy(
-                capCellularMmsInternetSpecifier1));
-        assertFalse(requestCellularInternetSpecifier1.canBeSatisfiedBy(capCellularVpnMmsInternet));
-        assertFalse(requestCellularInternetSpecifier1.canBeSatisfiedBy(
-                capCellularMmsInternetSpecifier2));
-
-        final NetworkRequest requestCellularInternet = new NetworkRequest.Builder()
-                .addTransportType(TRANSPORT_CELLULAR)
-                .addCapability(NET_CAPABILITY_INTERNET)
-                .build();
-        assertTrue(requestCellularInternet.canBeSatisfiedBy(capCellularMmsInternet));
-        assertTrue(requestCellularInternet.canBeSatisfiedBy(capCellularMmsInternetSpecifier1));
-        assertTrue(requestCellularInternet.canBeSatisfiedBy(capCellularMmsInternetSpecifier2));
-        assertFalse(requestCellularInternet.canBeSatisfiedBy(capVpnInternetSpecifier1));
-        assertTrue(requestCellularInternet.canBeSatisfiedBy(capCellularVpnMmsInternet));
-    }
-
-    @Test
-    @IgnoreUpTo(Build.VERSION_CODES.Q)
-    public void testInvariantInCanBeSatisfiedBy() {
-        // Test invariant that result of NetworkRequest.canBeSatisfiedBy() should be the same with
-        // NetworkCapabilities.satisfiedByNetworkCapabilities().
-        final LocalNetworkSpecifier specifier1 = new LocalNetworkSpecifier(1234 /* id */);
-        final int uid = Process.myUid();
-        final ArraySet<UidRange> ranges = new ArraySet<>();
-        ranges.add(new UidRange(uid, uid));
-        final NetworkRequest requestCombination = new NetworkRequest.Builder()
-                .addTransportType(TRANSPORT_CELLULAR)
-                .addCapability(NET_CAPABILITY_INTERNET)
-                .setLinkUpstreamBandwidthKbps(1000)
-                .setNetworkSpecifier(specifier1)
-                .setSignalStrength(-123)
-                .setUids(ranges).build();
-        final NetworkCapabilities capCell = new NetworkCapabilities.Builder()
-                .addTransportType(TRANSPORT_CELLULAR).build();
-        assertCorrectlySatisfies(false, requestCombination, capCell);
-
-        final NetworkCapabilities capCellInternet = new NetworkCapabilities.Builder(capCell)
-                .addCapability(NET_CAPABILITY_INTERNET).build();
-        assertCorrectlySatisfies(false, requestCombination, capCellInternet);
-
-        final NetworkCapabilities capCellInternetBW =
-                new NetworkCapabilities.Builder(capCellInternet)
-                    .setLinkUpstreamBandwidthKbps(1024).build();
-        assertCorrectlySatisfies(false, requestCombination, capCellInternetBW);
-
-        final NetworkCapabilities capCellInternetBWSpecifier1 =
-                new NetworkCapabilities.Builder(capCellInternetBW)
-                    .setNetworkSpecifier(specifier1).build();
-        assertCorrectlySatisfies(false, requestCombination, capCellInternetBWSpecifier1);
-
-        final NetworkCapabilities capCellInternetBWSpecifier1Signal =
-                new NetworkCapabilities.Builder(capCellInternetBWSpecifier1)
-                    .setSignalStrength(-123).build();
-        assertCorrectlySatisfies(true, requestCombination,
-                capCellInternetBWSpecifier1Signal);
-
-        final NetworkCapabilities capCellInternetBWSpecifier1SignalUid =
-                new NetworkCapabilities.Builder(capCellInternetBWSpecifier1Signal)
-                    .setOwnerUid(uid)
-                    .setAdministratorUids(new int [] {uid}).build();
-        assertCorrectlySatisfies(true, requestCombination,
-                capCellInternetBWSpecifier1SignalUid);
-    }
-
-    private void assertCorrectlySatisfies(boolean expect, NetworkRequest request,
-            NetworkCapabilities nc) {
-        assertEquals(expect, request.canBeSatisfiedBy(nc));
-        assertEquals(
-                request.canBeSatisfiedBy(nc),
-                request.networkCapabilities.satisfiedByNetworkCapabilities(nc));
-    }
-
-    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
-    public void testRequestorUid() {
-        final NetworkCapabilities nc = new NetworkCapabilities();
-        // Verify default value is INVALID_UID
-        assertEquals(Process.INVALID_UID, new NetworkRequest.Builder()
-                 .setCapabilities(nc).build().getRequestorUid());
-
-        nc.setRequestorUid(1314);
-        final NetworkRequest nr = new NetworkRequest.Builder().setCapabilities(nc).build();
-        assertEquals(1314, nr.getRequestorUid());
-
-        assertEquals(Process.INVALID_UID, new NetworkRequest.Builder()
-                .clearCapabilities().build().getRequestorUid());
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/NetworkStackDependenciesTest.kt b/tests/cts/net/src/android/net/cts/NetworkStackDependenciesTest.kt
deleted file mode 100644
index 1a7f955..0000000
--- a/tests/cts/net/src/android/net/cts/NetworkStackDependenciesTest.kt
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts
-
-import android.content.pm.PackageManager
-import android.net.cts.util.CtsNetUtils
-import android.net.wifi.WifiManager
-import android.os.Build
-import androidx.test.filters.SdkSuppress
-import androidx.test.platform.app.InstrumentationRegistry
-import org.junit.Assume.assumeTrue
-import org.junit.Test
-import kotlin.test.assertNotNull
-import kotlin.test.assertTrue
-
-/**
- * Basic tests for APIs used by the network stack module.
- */
-class NetworkStackDependenciesTest {
-    @Test
-    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.Q)
-    fun testGetFrequency() {
-        // WifiInfo#getFrequency was missing a CTS test in Q: this test is run as part of MTS on Q
-        // devices to ensure it behaves correctly.
-        val context = InstrumentationRegistry.getInstrumentation().getContext()
-        assumeTrue("This test only applies to devices that support wifi",
-                context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI))
-        val wifiManager = context.getSystemService(WifiManager::class.java)
-        assertNotNull(wifiManager, "Device supports wifi but there is no WifiManager")
-
-        CtsNetUtils(context).ensureWifiConnected()
-        val wifiInfo = wifiManager.getConnectionInfo()
-        // The NetworkStack can handle any value of getFrequency; unknown frequencies will not be
-        // classified in metrics, but this is expected behavior. It is only important that the
-        // method does not crash. Still verify that the frequency is positive
-        val frequency = wifiInfo.getFrequency()
-        assertTrue(frequency > 0, "Frequency must be > 0")
-    }
-}
\ No newline at end of file
diff --git a/tests/cts/net/src/android/net/cts/NetworkStatsBinderTest.java b/tests/cts/net/src/android/net/cts/NetworkStatsBinderTest.java
deleted file mode 100644
index 1a48983..0000000
--- a/tests/cts/net/src/android/net/cts/NetworkStatsBinderTest.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-import static android.os.Process.INVALID_UID;
-
-import static org.junit.Assert.assertEquals;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.net.INetworkStatsService;
-import android.net.TrafficStats;
-import android.os.Build;
-import android.os.IBinder;
-import android.os.Process;
-import android.os.RemoteException;
-import android.test.AndroidTestCase;
-import android.util.SparseArray;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.util.CollectionUtils;
-import com.android.testutils.DevSdkIgnoreRule;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Function;
-import java.util.function.Predicate;
-
-@RunWith(AndroidJUnit4.class)
-public class NetworkStatsBinderTest {
-    // NOTE: These are shamelessly copied from TrafficStats.
-    private static final int TYPE_RX_BYTES = 0;
-    private static final int TYPE_RX_PACKETS = 1;
-    private static final int TYPE_TX_BYTES = 2;
-    private static final int TYPE_TX_PACKETS = 3;
-
-    @Rule
-    public DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule(
-            Build.VERSION_CODES.Q /* ignoreClassUpTo */);
-
-    private final SparseArray<Function<Integer, Long>> mUidStatsQueryOpArray = new SparseArray<>();
-
-    @Before
-    public void setUp() throws Exception {
-        mUidStatsQueryOpArray.put(TYPE_RX_BYTES, uid -> TrafficStats.getUidRxBytes(uid));
-        mUidStatsQueryOpArray.put(TYPE_RX_PACKETS, uid -> TrafficStats.getUidRxPackets(uid));
-        mUidStatsQueryOpArray.put(TYPE_TX_BYTES, uid -> TrafficStats.getUidTxBytes(uid));
-        mUidStatsQueryOpArray.put(TYPE_TX_PACKETS, uid -> TrafficStats.getUidTxPackets(uid));
-    }
-
-    private long getUidStatsFromBinder(int uid, int type) throws Exception {
-        Method getServiceMethod = Class.forName("android.os.ServiceManager")
-                .getDeclaredMethod("getService", new Class[]{String.class});
-        IBinder binder = (IBinder) getServiceMethod.invoke(null, Context.NETWORK_STATS_SERVICE);
-        INetworkStatsService nss = INetworkStatsService.Stub.asInterface(binder);
-        return nss.getUidStats(uid, type);
-    }
-
-    private int getFirstAppUidThat(@NonNull Predicate<Integer> predicate) {
-        PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
-        List<PackageInfo> apps = pm.getInstalledPackages(0 /* flags */);
-        final PackageInfo match = CollectionUtils.find(apps,
-                it -> it.applicationInfo != null && predicate.test(it.applicationInfo.uid));
-        if (match != null) return match.applicationInfo.uid;
-        return INVALID_UID;
-    }
-
-    @Test
-    public void testAccessUidStatsFromBinder() throws Exception {
-        final int myUid = Process.myUid();
-        final List<Integer> testUidList = new ArrayList<>();
-
-        // Prepare uid list for testing.
-        testUidList.add(INVALID_UID);
-        testUidList.add(Process.ROOT_UID);
-        testUidList.add(Process.SYSTEM_UID);
-        testUidList.add(myUid);
-        testUidList.add(Process.LAST_APPLICATION_UID);
-        testUidList.add(Process.LAST_APPLICATION_UID + 1);
-        // If available, pick another existing uid for testing that is not already contained
-        // in the list above.
-        final int notMyUid = getFirstAppUidThat(uid -> uid >= 0 && !testUidList.contains(uid));
-        if (notMyUid != INVALID_UID) testUidList.add(notMyUid);
-
-        for (final int uid : testUidList) {
-            for (int i = 0; i < mUidStatsQueryOpArray.size(); i++) {
-                final int type = mUidStatsQueryOpArray.keyAt(i);
-                try {
-                    final long uidStatsFromBinder = getUidStatsFromBinder(uid, type);
-                    final long uidTrafficStats = mUidStatsQueryOpArray.get(type).apply(uid);
-
-                    // Verify that UNSUPPORTED is returned if the uid is not current app uid.
-                    if (uid != myUid) {
-                        assertEquals(uidStatsFromBinder, TrafficStats.UNSUPPORTED);
-                    }
-                    // Verify that returned result is the same with the result get from
-                    // TrafficStats.
-                    // TODO: If the test is flaky then it should instead assert that the values
-                    //  are approximately similar.
-                    assertEquals("uidStats is not matched for query type " + type
-                                    + ", uid=" + uid + ", myUid=" + myUid, uidTrafficStats,
-                            uidStatsFromBinder);
-                } catch (IllegalAccessException e) {
-                    /* Java language access prevents exploitation. */
-                    return;
-                } catch (InvocationTargetException e) {
-                    /* Underlying method has been changed. */
-                    return;
-                } catch (ClassNotFoundException e) {
-                    /* not vulnerable if hidden API no longer available */
-                    return;
-                } catch (NoSuchMethodException e) {
-                    /* not vulnerable if hidden API no longer available */
-                    return;
-                } catch (RemoteException e) {
-                    return;
-                }
-            }
-        }
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/NetworkValidationTest.kt b/tests/cts/net/src/android/net/cts/NetworkValidationTest.kt
deleted file mode 100644
index 5290f0d..0000000
--- a/tests/cts/net/src/android/net/cts/NetworkValidationTest.kt
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts
-
-import android.Manifest.permission.MANAGE_TEST_NETWORKS
-import android.Manifest.permission.NETWORK_SETTINGS
-import android.content.Context
-import android.content.pm.PackageManager
-import android.net.ConnectivityManager
-import android.net.EthernetManager
-import android.net.InetAddresses
-import android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL
-import android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED
-import android.net.NetworkCapabilities.TRANSPORT_ETHERNET
-import android.net.NetworkCapabilities.TRANSPORT_TEST
-import android.net.NetworkRequest
-import android.net.TestNetworkInterface
-import android.net.TestNetworkManager
-import android.net.Uri
-import android.net.dhcp.DhcpDiscoverPacket
-import android.net.dhcp.DhcpPacket
-import android.net.dhcp.DhcpPacket.DHCP_MESSAGE_TYPE
-import android.net.dhcp.DhcpPacket.DHCP_MESSAGE_TYPE_DISCOVER
-import android.net.dhcp.DhcpPacket.DHCP_MESSAGE_TYPE_REQUEST
-import android.net.dhcp.DhcpRequestPacket
-import android.os.Build
-import android.os.HandlerThread
-import android.platform.test.annotations.AppModeFull
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.runner.AndroidJUnit4
-import com.android.net.module.util.Inet4AddressUtils.getBroadcastAddress
-import com.android.net.module.util.Inet4AddressUtils.getPrefixMaskAsInet4Address
-import com.android.net.module.util.NetworkStackConstants.IPV4_ADDR_ANY
-import com.android.testutils.DevSdkIgnoreRule
-import com.android.testutils.DhcpClientPacketFilter
-import com.android.testutils.DhcpOptionFilter
-import com.android.testutils.RecorderCallback.CallbackEntry
-import com.android.testutils.TapPacketReader
-import com.android.testutils.TestHttpServer
-import com.android.testutils.TestableNetworkCallback
-import com.android.testutils.runAsShell
-import fi.iki.elonen.NanoHTTPD.Response.Status
-import org.junit.After
-import org.junit.Assume.assumeFalse
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-import java.net.Inet4Address
-import kotlin.test.assertEquals
-import kotlin.test.assertNotNull
-import kotlin.test.assertTrue
-import kotlin.test.fail
-
-private const val MAX_PACKET_LENGTH = 1500
-private const val TEST_TIMEOUT_MS = 10_000L
-
-private const val TEST_LEASE_TIMEOUT_SECS = 3600 * 12
-private const val TEST_PREFIX_LENGTH = 24
-
-private const val TEST_LOGIN_URL = "https://login.capport.android.com"
-private const val TEST_VENUE_INFO_URL = "https://venueinfo.capport.android.com"
-private const val TEST_DOMAIN_NAME = "lan"
-private const val TEST_MTU = 1500.toShort()
-
-@AppModeFull(reason = "Instant apps cannot create test networks")
-@RunWith(AndroidJUnit4::class)
-class NetworkValidationTest {
-    @JvmField
-    @Rule
-    val ignoreRule = DevSdkIgnoreRule(ignoreClassUpTo = Build.VERSION_CODES.Q)
-
-    private val context by lazy { InstrumentationRegistry.getInstrumentation().context }
-    private val tnm by lazy { context.assertHasService(TestNetworkManager::class.java) }
-    private val eth by lazy { context.assertHasService(EthernetManager::class.java) }
-    private val cm by lazy { context.assertHasService(ConnectivityManager::class.java) }
-
-    private val handlerThread = HandlerThread(NetworkValidationTest::class.java.simpleName)
-    private val serverIpAddr = InetAddresses.parseNumericAddress("192.0.2.222") as Inet4Address
-    private val clientIpAddr = InetAddresses.parseNumericAddress("192.0.2.111") as Inet4Address
-    private val httpServer = TestHttpServer()
-    private val ethRequest = NetworkRequest.Builder()
-            // ETHERNET|TEST transport networks do not have NET_CAPABILITY_TRUSTED
-            .removeCapability(NET_CAPABILITY_TRUSTED)
-            .addTransportType(TRANSPORT_ETHERNET)
-            .addTransportType(TRANSPORT_TEST).build()
-    private val ethRequestCb = TestableNetworkCallback()
-
-    private lateinit var iface: TestNetworkInterface
-    private lateinit var reader: TapPacketReader
-    private lateinit var capportUrl: Uri
-
-    private var testSkipped = false
-
-    @Before
-    fun setUp() {
-        // This test requires using a tap interface as an ethernet interface.
-        val pm = context.getPackageManager()
-        testSkipped = !pm.hasSystemFeature(PackageManager.FEATURE_ETHERNET) &&
-                context.getSystemService(EthernetManager::class.java) == null
-        assumeFalse(testSkipped)
-
-        // Register a request so the network does not get torn down
-        cm.requestNetwork(ethRequest, ethRequestCb)
-        runAsShell(NETWORK_SETTINGS, MANAGE_TEST_NETWORKS) {
-            eth.setIncludeTestInterfaces(true)
-            // Keeping a reference to the test interface also makes sure the ParcelFileDescriptor
-            // does not go out of scope, which would cause it to close the underlying FileDescriptor
-            // in its finalizer.
-            iface = tnm.createTapInterface()
-        }
-
-        handlerThread.start()
-        reader = TapPacketReader(
-                handlerThread.threadHandler,
-                iface.fileDescriptor.fileDescriptor,
-                MAX_PACKET_LENGTH)
-        reader.startAsyncForTest()
-        httpServer.start()
-
-        // Pad the listening port to make sure it is always of length 5. This ensures the URL has
-        // always the same length so the test can use constant IP and UDP header lengths.
-        // The maximum port number is 65535 so a length of 5 is always enough.
-        capportUrl = Uri.parse("http://localhost:${httpServer.listeningPort}/testapi.html?par=val")
-    }
-
-    @After
-    fun tearDown() {
-        if (testSkipped) return
-        cm.unregisterNetworkCallback(ethRequestCb)
-
-        runAsShell(NETWORK_SETTINGS) { eth.setIncludeTestInterfaces(false) }
-
-        httpServer.stop()
-        handlerThread.threadHandler.post { reader.stop() }
-        handlerThread.quitSafely()
-
-        iface.fileDescriptor.close()
-    }
-
-    @Test
-    fun testCapportApiCallbacks() {
-        httpServer.addResponse(capportUrl, Status.OK, content = """
-                |{
-                |  "captive": true,
-                |  "user-portal-url": "$TEST_LOGIN_URL",
-                |  "venue-info-url": "$TEST_VENUE_INFO_URL"
-                |}
-            """.trimMargin())
-
-        // Handle the DHCP handshake that includes the capport API URL
-        val discover = reader.assertDhcpPacketReceived(
-                DhcpDiscoverPacket::class.java, TEST_TIMEOUT_MS, DHCP_MESSAGE_TYPE_DISCOVER)
-        reader.sendResponse(makeOfferPacket(discover.clientMac, discover.transactionId))
-
-        val request = reader.assertDhcpPacketReceived(
-                DhcpRequestPacket::class.java, TEST_TIMEOUT_MS, DHCP_MESSAGE_TYPE_REQUEST)
-        assertEquals(discover.transactionId, request.transactionId)
-        assertEquals(clientIpAddr, request.mRequestedIp)
-        reader.sendResponse(makeAckPacket(request.clientMac, request.transactionId))
-
-        // The first request received by the server should be for the portal API
-        assertTrue(httpServer.requestsRecord.poll(TEST_TIMEOUT_MS, 0)?.matches(capportUrl) ?: false,
-                "The device did not fetch captive portal API data within timeout")
-
-        // Expect network callbacks with capport info
-        val testCb = TestableNetworkCallback(TEST_TIMEOUT_MS)
-        // LinkProperties do not contain captive portal info if the callback is registered without
-        // NETWORK_SETTINGS permissions.
-        val lp = runAsShell(NETWORK_SETTINGS) {
-            cm.registerNetworkCallback(ethRequest, testCb)
-
-            try {
-                val ncCb = testCb.eventuallyExpect<CallbackEntry.CapabilitiesChanged> {
-                    it.caps.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)
-                }
-                testCb.eventuallyExpect<CallbackEntry.LinkPropertiesChanged> {
-                    it.network == ncCb.network && it.lp.captivePortalData != null
-                }.lp
-            } finally {
-                cm.unregisterNetworkCallback(testCb)
-            }
-        }
-
-        assertEquals(capportUrl, lp.captivePortalApiUrl)
-        with(lp.captivePortalData) {
-            assertNotNull(this)
-            assertTrue(isCaptive)
-            assertEquals(Uri.parse(TEST_LOGIN_URL), userPortalUrl)
-            assertEquals(Uri.parse(TEST_VENUE_INFO_URL), venueInfoUrl)
-        }
-    }
-
-    private fun makeOfferPacket(clientMac: ByteArray, transactionId: Int) =
-            DhcpPacket.buildOfferPacket(DhcpPacket.ENCAP_L2, transactionId,
-                    false /* broadcast */, serverIpAddr, IPV4_ADDR_ANY /* relayIp */, clientIpAddr,
-                    clientMac, TEST_LEASE_TIMEOUT_SECS,
-                    getPrefixMaskAsInet4Address(TEST_PREFIX_LENGTH),
-                    getBroadcastAddress(clientIpAddr, TEST_PREFIX_LENGTH),
-                    listOf(serverIpAddr) /* gateways */, listOf(serverIpAddr) /* dnsServers */,
-                    serverIpAddr, TEST_DOMAIN_NAME, null /* hostname */, true /* metered */,
-                    TEST_MTU, capportUrl.toString())
-
-    private fun makeAckPacket(clientMac: ByteArray, transactionId: Int) =
-            DhcpPacket.buildAckPacket(DhcpPacket.ENCAP_L2, transactionId,
-                    false /* broadcast */, serverIpAddr, IPV4_ADDR_ANY /* relayIp */, clientIpAddr,
-                    clientIpAddr /* requestClientIp */, clientMac, TEST_LEASE_TIMEOUT_SECS,
-                    getPrefixMaskAsInet4Address(TEST_PREFIX_LENGTH),
-                    getBroadcastAddress(clientIpAddr, TEST_PREFIX_LENGTH),
-                    listOf(serverIpAddr) /* gateways */, listOf(serverIpAddr) /* dnsServers */,
-                    serverIpAddr, TEST_DOMAIN_NAME, null /* hostname */, true /* metered */,
-                    TEST_MTU, false /* rapidCommit */, capportUrl.toString())
-}
-
-private fun <T : DhcpPacket> TapPacketReader.assertDhcpPacketReceived(
-    packetType: Class<T>,
-    timeoutMs: Long,
-    type: Byte
-): T {
-    val packetBytes = poll(timeoutMs, DhcpClientPacketFilter()
-            .and(DhcpOptionFilter(DHCP_MESSAGE_TYPE, type)))
-            ?: fail("${packetType.simpleName} not received within timeout")
-    val packet = DhcpPacket.decodeFullPacket(packetBytes, packetBytes.size, DhcpPacket.ENCAP_L2)
-    assertTrue(packetType.isInstance(packet),
-            "Expected ${packetType.simpleName} but got ${packet.javaClass.simpleName}")
-    return packetType.cast(packet)
-}
-
-private fun <T> Context.assertHasService(manager: Class<T>): T {
-    return getSystemService(manager) ?: fail("Service $manager not found")
-}
diff --git a/tests/cts/net/src/android/net/cts/NetworkValidationTestUtil.kt b/tests/cts/net/src/android/net/cts/NetworkValidationTestUtil.kt
deleted file mode 100644
index f6fc75b..0000000
--- a/tests/cts/net/src/android/net/cts/NetworkValidationTestUtil.kt
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts
-
-import android.Manifest
-import android.net.util.NetworkStackUtils
-import android.provider.DeviceConfig
-import com.android.testutils.runAsShell
-
-/**
- * Collection of utility methods for configuring network validation.
- */
-internal object NetworkValidationTestUtil {
-
-    /**
-     * Clear the test network validation URLs.
-     */
-    fun clearValidationTestUrlsDeviceConfig() {
-        setHttpsUrlDeviceConfig(null)
-        setHttpUrlDeviceConfig(null)
-        setUrlExpirationDeviceConfig(null)
-    }
-
-    /**
-     * Set the test validation HTTPS URL.
-     *
-     * @see NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTPS_URL
-     */
-    fun setHttpsUrlDeviceConfig(url: String?) =
-            setConfig(NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTPS_URL, url)
-
-    /**
-     * Set the test validation HTTP URL.
-     *
-     * @see NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTP_URL
-     */
-    fun setHttpUrlDeviceConfig(url: String?) =
-            setConfig(NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTP_URL, url)
-
-    /**
-     * Set the test validation URL expiration.
-     *
-     * @see NetworkStackUtils.TEST_URL_EXPIRATION_TIME
-     */
-    fun setUrlExpirationDeviceConfig(timestamp: Long?) =
-            setConfig(NetworkStackUtils.TEST_URL_EXPIRATION_TIME, timestamp?.toString())
-
-    private fun setConfig(configKey: String, value: String?) {
-        runAsShell(Manifest.permission.WRITE_DEVICE_CONFIG) {
-            DeviceConfig.setProperty(
-                    DeviceConfig.NAMESPACE_CONNECTIVITY, configKey, value, false /* makeDefault */)
-        }
-    }
-}
\ No newline at end of file
diff --git a/tests/cts/net/src/android/net/cts/NetworkWatchlistTest.java b/tests/cts/net/src/android/net/cts/NetworkWatchlistTest.java
deleted file mode 100644
index 81a9e30..0000000
--- a/tests/cts/net/src/android/net/cts/NetworkWatchlistTest.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * 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.Assert.assertNotNull;
-import static org.junit.Assume.assumeTrue;
-
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.platform.test.annotations.AppModeFull;
-import android.os.FileUtils;
-import android.os.ParcelFileDescriptor;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-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.FileOutputStream;
-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 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();
-        assertNotNull("Watchlist config does not exist", result);
-        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 IOException {
-        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
-    @AppModeFull(reason = "Cannot access resource file in instant app mode")
-    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 {
-        // App can't access /data/local/tmp directly, so we pipe resource to file through stdin.
-        ParcelFileDescriptor stdin = pipeFromStdin(filePath);
-        pipeResourceToFileDescriptor(res, stdin);
-    }
-
-    /* Pipe stdin to a file in filePath. Returns PFD for stdin. */
-    private ParcelFileDescriptor pipeFromStdin(String filePath) {
-        // Not all devices have symlink for /dev/stdin, so use /proc/self/fd/0 directly.
-        // /dev/stdin maps to /proc/self/fd/0.
-        return runRwCommand("cp /proc/self/fd/0 " + filePath)[1];
-    }
-
-    private void pipeResourceToFileDescriptor(String res, ParcelFileDescriptor pfd)
-            throws IOException {
-        InputStream resStream = getClass().getClassLoader().getResourceAsStream(res);
-        FileOutputStream fdStream = new ParcelFileDescriptor.AutoCloseOutputStream(pfd);
-
-        FileUtils.copy(resStream, fdStream);
-
-        try {
-            fdStream.close();
-        } catch (IOException e) {
-        }
-    }
-
-    private static String runCommand(String command) throws IOException {
-        return SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(), command);
-    }
-
-    private static ParcelFileDescriptor[] runRwCommand(String command) {
-        return InstrumentationRegistry.getInstrumentation()
-                .getUiAutomation().executeShellCommandRw(command);
-    }
-
-    private void setWatchlistConfig(String watchlistConfigFile) throws Exception {
-        cleanup();
-        saveResourceToFile(watchlistConfigFile, TMP_CONFIG_PATH);
-        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/PacketUtils.java b/tests/cts/net/src/android/net/cts/PacketUtils.java
deleted file mode 100644
index 0aedecb..0000000
--- a/tests/cts/net/src/android/net/cts/PacketUtils.java
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * 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.system.OsConstants.IPPROTO_IPV6;
-import static android.system.OsConstants.IPPROTO_UDP;
-
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.nio.ByteBuffer;
-import java.nio.ShortBuffer;
-import java.security.GeneralSecurityException;
-import java.security.SecureRandom;
-import java.util.Arrays;
-
-import javax.crypto.Cipher;
-import javax.crypto.Mac;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-
-public class PacketUtils {
-    private static final String TAG = PacketUtils.class.getSimpleName();
-
-    private static final int DATA_BUFFER_LEN = 4096;
-
-    static final int IP4_HDRLEN = 20;
-    static final int IP6_HDRLEN = 40;
-    static final int UDP_HDRLEN = 8;
-    static final int TCP_HDRLEN = 20;
-    static final int TCP_HDRLEN_WITH_TIMESTAMP_OPT = TCP_HDRLEN + 12;
-
-    // Not defined in OsConstants
-    static final int IPPROTO_IPV4 = 4;
-    static final int IPPROTO_ESP = 50;
-
-    // Encryption parameters
-    static final int AES_GCM_IV_LEN = 8;
-    static final int AES_CBC_IV_LEN = 16;
-    static final int AES_GCM_BLK_SIZE = 4;
-    static final int AES_CBC_BLK_SIZE = 16;
-
-    // Encryption algorithms
-    static final String AES = "AES";
-    static final String AES_CBC = "AES/CBC/NoPadding";
-    static final String HMAC_SHA_256 = "HmacSHA256";
-
-    public interface Payload {
-        byte[] getPacketBytes(IpHeader header) throws Exception;
-
-        void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) throws Exception;
-
-        short length();
-
-        int getProtocolId();
-    }
-
-    public abstract static class IpHeader {
-
-        public final byte proto;
-        public final InetAddress srcAddr;
-        public final InetAddress dstAddr;
-        public final Payload payload;
-
-        public IpHeader(int proto, InetAddress src, InetAddress dst, Payload payload) {
-            this.proto = (byte) proto;
-            this.srcAddr = src;
-            this.dstAddr = dst;
-            this.payload = payload;
-        }
-
-        public abstract byte[] getPacketBytes() throws Exception;
-
-        public abstract int getProtocolId();
-    }
-
-    public static class Ip4Header extends IpHeader {
-        private short checksum;
-
-        public Ip4Header(int proto, Inet4Address src, Inet4Address dst, Payload payload) {
-            super(proto, src, dst, payload);
-        }
-
-        public byte[] getPacketBytes() throws Exception {
-            ByteBuffer resultBuffer = buildHeader();
-            payload.addPacketBytes(this, resultBuffer);
-
-            return getByteArrayFromBuffer(resultBuffer);
-        }
-
-        public ByteBuffer buildHeader() {
-            ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN);
-
-            // Version, IHL
-            bb.put((byte) (0x45));
-
-            // DCSP, ECN
-            bb.put((byte) 0);
-
-            // Total Length
-            bb.putShort((short) (IP4_HDRLEN + payload.length()));
-
-            // Empty for Identification, Flags and Fragment Offset
-            bb.putShort((short) 0);
-            bb.put((byte) 0x40);
-            bb.put((byte) 0x00);
-
-            // TTL
-            bb.put((byte) 64);
-
-            // Protocol
-            bb.put(proto);
-
-            // Header Checksum
-            final int ipChecksumOffset = bb.position();
-            bb.putShort((short) 0);
-
-            // Src/Dst addresses
-            bb.put(srcAddr.getAddress());
-            bb.put(dstAddr.getAddress());
-
-            bb.putShort(ipChecksumOffset, calculateChecksum(bb));
-
-            return bb;
-        }
-
-        private short calculateChecksum(ByteBuffer bb) {
-            int checksum = 0;
-
-            // Calculate sum of 16-bit values, excluding checksum. IPv4 headers are always 32-bit
-            // aligned, so no special cases needed for unaligned values.
-            ShortBuffer shortBuffer = ByteBuffer.wrap(getByteArrayFromBuffer(bb)).asShortBuffer();
-            while (shortBuffer.hasRemaining()) {
-                short val = shortBuffer.get();
-
-                // Wrap as needed
-                checksum = addAndWrapForChecksum(checksum, val);
-            }
-
-            return onesComplement(checksum);
-        }
-
-        public int getProtocolId() {
-            return IPPROTO_IPV4;
-        }
-    }
-
-    public static class Ip6Header extends IpHeader {
-        public Ip6Header(int nextHeader, Inet6Address src, Inet6Address dst, Payload payload) {
-            super(nextHeader, src, dst, payload);
-        }
-
-        public byte[] getPacketBytes() throws Exception {
-            ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN);
-
-            // Version | Traffic Class (First 4 bits)
-            bb.put((byte) 0x60);
-
-            // Traffic class (Last 4 bits), Flow Label
-            bb.put((byte) 0);
-            bb.put((byte) 0);
-            bb.put((byte) 0);
-
-            // Payload Length
-            bb.putShort((short) payload.length());
-
-            // Next Header
-            bb.put(proto);
-
-            // Hop Limit
-            bb.put((byte) 64);
-
-            // Src/Dst addresses
-            bb.put(srcAddr.getAddress());
-            bb.put(dstAddr.getAddress());
-
-            // Payload
-            payload.addPacketBytes(this, bb);
-
-            return getByteArrayFromBuffer(bb);
-        }
-
-        public int getProtocolId() {
-            return IPPROTO_IPV6;
-        }
-    }
-
-    public static class BytePayload implements Payload {
-        public final byte[] payload;
-
-        public BytePayload(byte[] payload) {
-            this.payload = payload;
-        }
-
-        public int getProtocolId() {
-            return -1;
-        }
-
-        public byte[] getPacketBytes(IpHeader header) {
-            ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN);
-
-            addPacketBytes(header, bb);
-            return getByteArrayFromBuffer(bb);
-        }
-
-        public void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) {
-            resultBuffer.put(payload);
-        }
-
-        public short length() {
-            return (short) payload.length;
-        }
-    }
-
-    public static class UdpHeader implements Payload {
-
-        public final short srcPort;
-        public final short dstPort;
-        public final Payload payload;
-
-        public UdpHeader(int srcPort, int dstPort, Payload payload) {
-            this.srcPort = (short) srcPort;
-            this.dstPort = (short) dstPort;
-            this.payload = payload;
-        }
-
-        public int getProtocolId() {
-            return IPPROTO_UDP;
-        }
-
-        public short length() {
-            return (short) (payload.length() + 8);
-        }
-
-        public byte[] getPacketBytes(IpHeader header) throws Exception {
-            ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN);
-
-            addPacketBytes(header, bb);
-            return getByteArrayFromBuffer(bb);
-        }
-
-        public void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) throws Exception {
-            // Source, Destination port
-            resultBuffer.putShort(srcPort);
-            resultBuffer.putShort(dstPort);
-
-            // Payload Length
-            resultBuffer.putShort(length());
-
-            // Get payload bytes for checksum + payload
-            ByteBuffer payloadBuffer = ByteBuffer.allocate(DATA_BUFFER_LEN);
-            payload.addPacketBytes(header, payloadBuffer);
-            byte[] payloadBytes = getByteArrayFromBuffer(payloadBuffer);
-
-            // Checksum
-            resultBuffer.putShort(calculateChecksum(header, payloadBytes));
-
-            // Payload
-            resultBuffer.put(payloadBytes);
-        }
-
-        private short calculateChecksum(IpHeader header, byte[] payloadBytes) throws Exception {
-            int newChecksum = 0;
-            ShortBuffer srcBuffer = ByteBuffer.wrap(header.srcAddr.getAddress()).asShortBuffer();
-            ShortBuffer dstBuffer = ByteBuffer.wrap(header.dstAddr.getAddress()).asShortBuffer();
-
-            while (srcBuffer.hasRemaining() || dstBuffer.hasRemaining()) {
-                short val = srcBuffer.hasRemaining() ? srcBuffer.get() : dstBuffer.get();
-
-                // Wrap as needed
-                newChecksum = addAndWrapForChecksum(newChecksum, val);
-            }
-
-            // Add pseudo-header values. Proto is 0-padded, so just use the byte.
-            newChecksum = addAndWrapForChecksum(newChecksum, header.proto);
-            newChecksum = addAndWrapForChecksum(newChecksum, length());
-            newChecksum = addAndWrapForChecksum(newChecksum, srcPort);
-            newChecksum = addAndWrapForChecksum(newChecksum, dstPort);
-            newChecksum = addAndWrapForChecksum(newChecksum, length());
-
-            ShortBuffer payloadShortBuffer = ByteBuffer.wrap(payloadBytes).asShortBuffer();
-            while (payloadShortBuffer.hasRemaining()) {
-                newChecksum = addAndWrapForChecksum(newChecksum, payloadShortBuffer.get());
-            }
-            if (payload.length() % 2 != 0) {
-                newChecksum =
-                        addAndWrapForChecksum(
-                                newChecksum, (payloadBytes[payloadBytes.length - 1] << 8));
-            }
-
-            return onesComplement(newChecksum);
-        }
-    }
-
-    public static class EspHeader implements Payload {
-        public final int nextHeader;
-        public final int spi;
-        public final int seqNum;
-        public final byte[] key;
-        public final byte[] payload;
-
-        /**
-         * Generic constructor for ESP headers.
-         *
-         * <p>For Tunnel mode, payload will be a full IP header + attached payloads
-         *
-         * <p>For Transport mode, payload will be only the attached payloads, but with the checksum
-         * calculated using the pre-encryption IP header
-         */
-        public EspHeader(int nextHeader, int spi, int seqNum, byte[] key, byte[] payload) {
-            this.nextHeader = nextHeader;
-            this.spi = spi;
-            this.seqNum = seqNum;
-            this.key = key;
-            this.payload = payload;
-        }
-
-        public int getProtocolId() {
-            return IPPROTO_ESP;
-        }
-
-        public short length() {
-            // ALWAYS uses AES-CBC, HMAC-SHA256 (128b trunc len)
-            return (short)
-                    calculateEspPacketSize(payload.length, AES_CBC_IV_LEN, AES_CBC_BLK_SIZE, 128);
-        }
-
-        public byte[] getPacketBytes(IpHeader header) throws Exception {
-            ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN);
-
-            addPacketBytes(header, bb);
-            return getByteArrayFromBuffer(bb);
-        }
-
-        public void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) throws Exception {
-            ByteBuffer espPayloadBuffer = ByteBuffer.allocate(DATA_BUFFER_LEN);
-            espPayloadBuffer.putInt(spi);
-            espPayloadBuffer.putInt(seqNum);
-            espPayloadBuffer.put(getCiphertext(key));
-
-            espPayloadBuffer.put(getIcv(getByteArrayFromBuffer(espPayloadBuffer)), 0, 16);
-            resultBuffer.put(getByteArrayFromBuffer(espPayloadBuffer));
-        }
-
-        private byte[] getIcv(byte[] authenticatedSection) throws GeneralSecurityException {
-            Mac sha256HMAC = Mac.getInstance(HMAC_SHA_256);
-            SecretKeySpec authKey = new SecretKeySpec(key, HMAC_SHA_256);
-            sha256HMAC.init(authKey);
-
-            return sha256HMAC.doFinal(authenticatedSection);
-        }
-
-        /**
-         * Encrypts and builds ciphertext block. Includes the IV, Padding and Next-Header blocks
-         *
-         * <p>The ciphertext does NOT include the SPI/Sequence numbers, or the ICV.
-         */
-        private byte[] getCiphertext(byte[] key) throws GeneralSecurityException {
-            int paddedLen = calculateEspEncryptedLength(payload.length, AES_CBC_BLK_SIZE);
-            ByteBuffer paddedPayload = ByteBuffer.allocate(paddedLen);
-            paddedPayload.put(payload);
-
-            // Add padding - consecutive integers from 0x01
-            int pad = 1;
-            while (paddedPayload.position() < paddedPayload.limit()) {
-                paddedPayload.put((byte) pad++);
-            }
-
-            paddedPayload.position(paddedPayload.limit() - 2);
-            paddedPayload.put((byte) (paddedLen - 2 - payload.length)); // Pad length
-            paddedPayload.put((byte) nextHeader);
-
-            // Generate Initialization Vector
-            byte[] iv = new byte[AES_CBC_IV_LEN];
-            new SecureRandom().nextBytes(iv);
-            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
-            SecretKeySpec secretKeySpec = new SecretKeySpec(key, AES);
-
-            // Encrypt payload
-            Cipher cipher = Cipher.getInstance(AES_CBC);
-            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
-            byte[] encrypted = cipher.doFinal(getByteArrayFromBuffer(paddedPayload));
-
-            // Build ciphertext
-            ByteBuffer cipherText = ByteBuffer.allocate(AES_CBC_IV_LEN + encrypted.length);
-            cipherText.put(iv);
-            cipherText.put(encrypted);
-
-            return getByteArrayFromBuffer(cipherText);
-        }
-    }
-
-    private static int addAndWrapForChecksum(int currentChecksum, int value) {
-        currentChecksum += value & 0x0000ffff;
-
-        // Wrap anything beyond the first 16 bits, and add to lower order bits
-        return (currentChecksum >>> 16) + (currentChecksum & 0x0000ffff);
-    }
-
-    private static short onesComplement(int val) {
-        val = (val >>> 16) + (val & 0xffff);
-
-        if (val == 0) return 0;
-        return (short) ((~val) & 0xffff);
-    }
-
-    public static int calculateEspPacketSize(
-            int payloadLen, int cryptIvLength, int cryptBlockSize, int authTruncLen) {
-        final int ESP_HDRLEN = 4 + 4; // SPI + Seq#
-        final int ICV_LEN = authTruncLen / 8; // Auth trailer; based on truncation length
-        payloadLen += cryptIvLength; // Initialization Vector
-
-        // Align to block size of encryption algorithm
-        payloadLen = calculateEspEncryptedLength(payloadLen, cryptBlockSize);
-        return payloadLen + ESP_HDRLEN + ICV_LEN;
-    }
-
-    private static int calculateEspEncryptedLength(int payloadLen, int cryptBlockSize) {
-        payloadLen += 2; // ESP trailer
-
-        // Align to block size of encryption algorithm
-        return payloadLen + calculateEspPadLen(payloadLen, cryptBlockSize);
-    }
-
-    private static int calculateEspPadLen(int payloadLen, int cryptBlockSize) {
-        return (cryptBlockSize - (payloadLen % cryptBlockSize)) % cryptBlockSize;
-    }
-
-    private static byte[] getByteArrayFromBuffer(ByteBuffer buffer) {
-        return Arrays.copyOfRange(buffer.array(), 0, buffer.position());
-    }
-
-    public static IpHeader getIpHeader(
-            int protocol, InetAddress src, InetAddress dst, Payload payload) {
-        if ((src instanceof Inet6Address) != (dst instanceof Inet6Address)) {
-            throw new IllegalArgumentException("Invalid src/dst address combination");
-        }
-
-        if (src instanceof Inet6Address) {
-            return new Ip6Header(protocol, (Inet6Address) src, (Inet6Address) dst, payload);
-        } else {
-            return new Ip4Header(protocol, (Inet4Address) src, (Inet4Address) dst, payload);
-        }
-    }
-
-    /*
-     * Debug printing
-     */
-    private static final char[] hexArray = "0123456789ABCDEF".toCharArray();
-
-    public static String bytesToHex(byte[] bytes) {
-        StringBuilder sb = new StringBuilder();
-        for (byte b : bytes) {
-            sb.append(hexArray[b >>> 4]);
-            sb.append(hexArray[b & 0x0F]);
-            sb.append(' ');
-        }
-        return sb.toString();
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/ProxyInfoTest.java b/tests/cts/net/src/android/net/cts/ProxyInfoTest.java
deleted file mode 100644
index 1c5624c..0000000
--- a/tests/cts/net/src/android/net/cts/ProxyInfoTest.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import android.net.ProxyInfo;
-import android.net.Uri;
-import android.os.Build;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-
-@RunWith(AndroidJUnit4.class)
-public final class ProxyInfoTest {
-    private static final String TEST_HOST = "test.example.com";
-    private static final int TEST_PORT = 5566;
-    private static final Uri TEST_URI = Uri.parse("https://test.example.com");
-    // This matches android.net.ProxyInfo#LOCAL_EXCL_LIST
-    private static final String LOCAL_EXCL_LIST = "";
-    // This matches android.net.ProxyInfo#LOCAL_HOST
-    private static final String LOCAL_HOST = "localhost";
-    // This matches android.net.ProxyInfo#LOCAL_PORT
-    private static final int LOCAL_PORT = -1;
-
-    @Rule
-    public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
-
-    @Test
-    public void testConstructor() {
-        final ProxyInfo proxy = new ProxyInfo((ProxyInfo) null);
-        checkEmpty(proxy);
-
-        assertEquals(proxy, new ProxyInfo(proxy));
-    }
-
-    @Test
-    public void testBuildDirectProxy() {
-        final ProxyInfo proxy1 = ProxyInfo.buildDirectProxy(TEST_HOST, TEST_PORT);
-
-        assertEquals(TEST_HOST, proxy1.getHost());
-        assertEquals(TEST_PORT, proxy1.getPort());
-        assertArrayEquals(new String[0], proxy1.getExclusionList());
-        assertEquals(Uri.EMPTY, proxy1.getPacFileUrl());
-
-        final List<String> exclList = new ArrayList<>();
-        exclList.add("localhost");
-        exclList.add("*.exclusion.com");
-        final ProxyInfo proxy2 = ProxyInfo.buildDirectProxy(TEST_HOST, TEST_PORT, exclList);
-
-        assertEquals(TEST_HOST, proxy2.getHost());
-        assertEquals(TEST_PORT, proxy2.getPort());
-        assertArrayEquals(exclList.toArray(new String[0]), proxy2.getExclusionList());
-        assertEquals(Uri.EMPTY, proxy2.getPacFileUrl());
-    }
-
-    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
-    public void testBuildPacProxy() {
-        final ProxyInfo proxy1 = ProxyInfo.buildPacProxy(TEST_URI);
-
-        assertEquals(LOCAL_HOST, proxy1.getHost());
-        assertEquals(LOCAL_PORT, proxy1.getPort());
-        assertArrayEquals(LOCAL_EXCL_LIST.toLowerCase(Locale.ROOT).split(","),
-                proxy1.getExclusionList());
-        assertEquals(TEST_URI, proxy1.getPacFileUrl());
-
-        final ProxyInfo proxy2 = ProxyInfo.buildPacProxy(TEST_URI, TEST_PORT);
-
-        assertEquals(LOCAL_HOST, proxy2.getHost());
-        assertEquals(TEST_PORT, proxy2.getPort());
-        assertArrayEquals(LOCAL_EXCL_LIST.toLowerCase(Locale.ROOT).split(","),
-                proxy2.getExclusionList());
-        assertEquals(TEST_URI, proxy2.getPacFileUrl());
-    }
-
-    @Test
-    public void testIsValid() {
-        final ProxyInfo proxy1 = ProxyInfo.buildDirectProxy(TEST_HOST, TEST_PORT);
-        assertTrue(proxy1.isValid());
-
-        // Given empty host
-        final ProxyInfo proxy2 = ProxyInfo.buildDirectProxy("", TEST_PORT);
-        assertFalse(proxy2.isValid());
-        // Given invalid host
-        final ProxyInfo proxy3 = ProxyInfo.buildDirectProxy(".invalid.com", TEST_PORT);
-        assertFalse(proxy3.isValid());
-        // Given invalid port.
-        final ProxyInfo proxy4 = ProxyInfo.buildDirectProxy(TEST_HOST, 0);
-        assertFalse(proxy4.isValid());
-        // Given another invalid port
-        final ProxyInfo proxy5 = ProxyInfo.buildDirectProxy(TEST_HOST, 65536);
-        assertFalse(proxy5.isValid());
-        // Given invalid exclusion list
-        final List<String> exclList = new ArrayList<>();
-        exclList.add(".invalid.com");
-        exclList.add("%.test.net");
-        final ProxyInfo proxy6 = ProxyInfo.buildDirectProxy(TEST_HOST, TEST_PORT, exclList);
-        assertFalse(proxy6.isValid());
-    }
-
-    private void checkEmpty(ProxyInfo proxy) {
-        assertNull(proxy.getHost());
-        assertEquals(0, proxy.getPort());
-        assertNull(proxy.getExclusionList());
-        assertEquals(Uri.EMPTY, proxy.getPacFileUrl());
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/ProxyTest.java b/tests/cts/net/src/android/net/cts/ProxyTest.java
deleted file mode 100644
index 467d12f..0000000
--- a/tests/cts/net/src/android/net/cts/ProxyTest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-
-import android.net.Proxy;
-import android.test.AndroidTestCase;
-
-public class ProxyTest extends AndroidTestCase {
-
-    public void testConstructor() {
-        new Proxy();
-    }
-
-    public void testAccessProperties() {
-        final int minValidPort = 0;
-        final int maxValidPort = 65535;
-        int defaultPort = Proxy.getDefaultPort();
-        if(null == Proxy.getDefaultHost()) {
-            assertEquals(-1, defaultPort);
-        } else {
-            assertTrue(defaultPort >= minValidPort && defaultPort <= maxValidPort);
-        }
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/RssiCurveTest.java b/tests/cts/net/src/android/net/cts/RssiCurveTest.java
deleted file mode 100644
index d651b71..0000000
--- a/tests/cts/net/src/android/net/cts/RssiCurveTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.net.RssiCurve;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/** CTS tests for {@link RssiCurve}. */
-@RunWith(AndroidJUnit4.class)
-public class RssiCurveTest {
-
-    @Test
-    public void lookupScore_constantCurve() {
-        // One bucket from rssi=-100 to 100 with score 10.
-        RssiCurve curve = new RssiCurve(-100, 200, new byte[] { 10 });
-        assertThat(curve.lookupScore(-200)).isEqualTo(10);
-        assertThat(curve.lookupScore(-100)).isEqualTo(10);
-        assertThat(curve.lookupScore(0)).isEqualTo(10);
-        assertThat(curve.lookupScore(100)).isEqualTo(10);
-        assertThat(curve.lookupScore(200)).isEqualTo(10);
-    }
-
-    @Test
-    public void lookupScore_changingCurve() {
-        // One bucket from -100 to 0 with score -10, and one bucket from 0 to 100 with score 10.
-        RssiCurve curve = new RssiCurve(-100, 100, new byte[] { -10, 10 });
-        assertThat(curve.lookupScore(-200)).isEqualTo(-10);
-        assertThat(curve.lookupScore(-100)).isEqualTo(-10);
-        assertThat(curve.lookupScore(-50)).isEqualTo(-10);
-        assertThat(curve.lookupScore(0)).isEqualTo(10);
-        assertThat(curve.lookupScore(50)).isEqualTo(10);
-        assertThat(curve.lookupScore(100)).isEqualTo(10);
-        assertThat(curve.lookupScore(200)).isEqualTo(10);
-    }
-
-    @Test
-    public void lookupScore_linearCurve() {
-        // Curve starting at -110, with 15 buckets of width 10 whose scores increases by 10 with
-        // each bucket. The current active network gets a boost of 15 to its RSSI.
-        RssiCurve curve = new RssiCurve(
-                -110,
-                10,
-                new byte[] { -20, -10, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120 },
-                15);
-
-        assertThat(curve.lookupScore(-120)).isEqualTo(-20);
-        assertThat(curve.lookupScore(-120, false)).isEqualTo(-20);
-        assertThat(curve.lookupScore(-120, true)).isEqualTo(-20);
-
-        assertThat(curve.lookupScore(-111)).isEqualTo(-20);
-        assertThat(curve.lookupScore(-111, false)).isEqualTo(-20);
-        assertThat(curve.lookupScore(-111, true)).isEqualTo(-10);
-
-        assertThat(curve.lookupScore(-110)).isEqualTo(-20);
-        assertThat(curve.lookupScore(-110, false)).isEqualTo(-20);
-        assertThat(curve.lookupScore(-110, true)).isEqualTo(-10);
-
-        assertThat(curve.lookupScore(-105)).isEqualTo(-20);
-        assertThat(curve.lookupScore(-105, false)).isEqualTo(-20);
-        assertThat(curve.lookupScore(-105, true)).isEqualTo(0);
-
-        assertThat(curve.lookupScore(-100)).isEqualTo(-10);
-        assertThat(curve.lookupScore(-100, false)).isEqualTo(-10);
-        assertThat(curve.lookupScore(-100, true)).isEqualTo(0);
-
-        assertThat(curve.lookupScore(-50)).isEqualTo(40);
-        assertThat(curve.lookupScore(-50, false)).isEqualTo(40);
-        assertThat(curve.lookupScore(-50, true)).isEqualTo(50);
-
-        assertThat(curve.lookupScore(0)).isEqualTo(90);
-        assertThat(curve.lookupScore(0, false)).isEqualTo(90);
-        assertThat(curve.lookupScore(0, true)).isEqualTo(100);
-
-        assertThat(curve.lookupScore(30)).isEqualTo(120);
-        assertThat(curve.lookupScore(30, false)).isEqualTo(120);
-        assertThat(curve.lookupScore(30, true)).isEqualTo(120);
-
-        assertThat(curve.lookupScore(40)).isEqualTo(120);
-        assertThat(curve.lookupScore(40, false)).isEqualTo(120);
-        assertThat(curve.lookupScore(40, true)).isEqualTo(120);
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java
deleted file mode 100644
index cbe54f8..0000000
--- a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-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 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;
-
-@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;
-
-    @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(mSocketFactory);
-    }
-
-    @Test
-    public void testAccessProperties() {
-        mSocketFactory.getSupportedCipherSuites();
-        mSocketFactory.getDefaultCipherSuites();
-    }
-
-    /**
-     * 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 {
-            mSocketFactory.createSocket(localhostAddress, HTTPS_PORT);
-            fail();
-        } catch (IOException e) {
-            // expected
-        }
-
-        // Same, but also binding to a local address.
-        try {
-            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();
-            mSocketFactory.createSocket(socket, "localhost", HTTPS_PORT, true);
-            fail();
-        } catch (IOException e) {
-            // expected
-        }
-    }
-
-    /**
-     * 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);
-        assertTrue(socket.isConnected());
-        assertNotNull(socket.getInputStream());
-        assertNotNull(socket.getOutputStream());
-        assertTrue(mTestSocketAddresses.contains(socket.getRemoteSocketAddress()));
-    }
-
-    /**
-     * A HostnameVerifier which always returns false to simulate a server returning a
-     * certificate which does not match the expected hostname.
-     */
-    private static class NegativeHostnameVerifier implements HostnameVerifier {
-        @Override
-        public boolean verify(String hostname, SSLSession sslSession) {
-            return false;
-        }
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/TheaterModeTest.java b/tests/cts/net/src/android/net/cts/TheaterModeTest.java
deleted file mode 100644
index d1ddeaa..0000000
--- a/tests/cts/net/src/android/net/cts/TheaterModeTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2016 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.content.ContentResolver;
-import android.content.Context;
-import android.platform.test.annotations.AppModeFull;
-import android.provider.Settings;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-public class TheaterModeTest extends AndroidTestCase {
-    private static final String TAG = "TheaterModeTest";
-    private static final String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
-    private static final String FEATURE_WIFI = "android.hardware.wifi";
-    private static final int TIMEOUT_MS = 10 * 1000;
-    private boolean mHasFeature;
-    private Context mContext;
-    private ContentResolver resolver;
-
-    public void setup() {
-        mContext= getContext();
-        resolver = mContext.getContentResolver();
-        mHasFeature = (mContext.getPackageManager().hasSystemFeature(FEATURE_BLUETOOTH)
-                       || mContext.getPackageManager().hasSystemFeature(FEATURE_WIFI));
-    }
-
-    @AppModeFull(reason = "WRITE_SECURE_SETTINGS permission can't be granted to instant apps")
-    public void testTheaterMode() {
-        setup();
-        if (!mHasFeature) {
-            Log.i(TAG, "The device doesn't support network bluetooth or wifi feature");
-            return;
-        }
-
-        for (int testCount = 0; testCount < 2; testCount++) {
-            if (!doOneTest()) {
-                fail("Theater mode failed to change in " + TIMEOUT_MS + "msec");
-                return;
-            }
-        }
-    }
-
-    private boolean doOneTest() {
-        boolean theaterModeOn = isTheaterModeOn();
-
-        setTheaterModeOn(!theaterModeOn);
-        try {
-            Thread.sleep(TIMEOUT_MS);
-        } catch (InterruptedException e) {
-            Log.e(TAG, "Sleep time interrupted.", e);
-        }
-
-        if (theaterModeOn == isTheaterModeOn()) {
-            return false;
-        }
-        return true;
-    }
-
-    private void setTheaterModeOn(boolean enabling) {
-        // Change the system setting for theater mode
-        Settings.Global.putInt(resolver, Settings.Global.THEATER_MODE_ON, enabling ? 1 : 0);
-    }
-
-    private boolean isTheaterModeOn() {
-        // Read the system setting for theater mode
-        return Settings.Global.getInt(mContext.getContentResolver(),
-                                      Settings.Global.THEATER_MODE_ON, 0) != 0;
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java
deleted file mode 100755
index 37bdd44..0000000
--- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-import android.net.NetworkStats;
-import android.net.TrafficStats;
-import android.os.Process;
-import android.platform.test.annotations.AppModeFull;
-import android.test.AndroidTestCase;
-import android.util.Log;
-import android.util.Range;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-public class TrafficStatsTest extends AndroidTestCase {
-    private static final String LOG_TAG = "TrafficStatsTest";
-
-    /** Verify the given value is in range [lower, upper] */
-    private void assertInRange(String tag, long value, long lower, long upper) {
-        final Range range = new Range(lower, upper);
-        assertTrue(tag + ": " + value + " is not within range [" + lower + ", " + upper + "]",
-                range.contains(value));
-    }
-
-    public void testValidMobileStats() {
-        // We can't assume a mobile network is even present in this test, so
-        // we simply assert that a valid value is returned.
-
-        assertTrue(TrafficStats.getMobileTxPackets() >= 0);
-        assertTrue(TrafficStats.getMobileRxPackets() >= 0);
-        assertTrue(TrafficStats.getMobileTxBytes() >= 0);
-        assertTrue(TrafficStats.getMobileRxBytes() >= 0);
-    }
-
-    public void testValidTotalStats() {
-        assertTrue(TrafficStats.getTotalTxPackets() >= 0);
-        assertTrue(TrafficStats.getTotalRxPackets() >= 0);
-        assertTrue(TrafficStats.getTotalTxBytes() >= 0);
-        assertTrue(TrafficStats.getTotalRxBytes() >= 0);
-    }
-
-    public void testValidPacketStats() {
-        assertTrue(TrafficStats.getTxPackets("lo") >= 0);
-        assertTrue(TrafficStats.getRxPackets("lo") >= 0);
-    }
-
-    public void testThreadStatsTag() throws Exception {
-        TrafficStats.setThreadStatsTag(0xf00d);
-        assertTrue("Tag didn't stick", TrafficStats.getThreadStatsTag() == 0xf00d);
-
-        final CountDownLatch latch = new CountDownLatch(1);
-
-        new Thread("TrafficStatsTest.testThreadStatsTag") {
-            @Override
-            public void run() {
-                assertTrue("Tag leaked", TrafficStats.getThreadStatsTag() != 0xf00d);
-                TrafficStats.setThreadStatsTag(0xcafe);
-                assertTrue("Tag didn't stick", TrafficStats.getThreadStatsTag() == 0xcafe);
-                latch.countDown();
-            }
-        }.start();
-
-        latch.await(5, TimeUnit.SECONDS);
-        assertTrue("Tag lost", TrafficStats.getThreadStatsTag() == 0xf00d);
-
-        TrafficStats.clearThreadStatsTag();
-        assertTrue("Tag not cleared", TrafficStats.getThreadStatsTag() != 0xf00d);
-    }
-
-    long tcpPacketToIpBytes(long packetCount, long bytes) {
-        // ip header + tcp header + data.
-        // Tcp header is mostly 32. Syn has different tcp options -> 40. Don't care.
-        return packetCount * (20 + 32 + bytes);
-    }
-
-    @AppModeFull(reason = "Socket cannot bind in instant app mode")
-    public void testTrafficStatsForLocalhost() throws IOException {
-        final long mobileTxPacketsBefore = TrafficStats.getMobileTxPackets();
-        final long mobileRxPacketsBefore = TrafficStats.getMobileRxPackets();
-        final long mobileTxBytesBefore = TrafficStats.getMobileTxBytes();
-        final long mobileRxBytesBefore = TrafficStats.getMobileRxBytes();
-        final long totalTxPacketsBefore = TrafficStats.getTotalTxPackets();
-        final long totalRxPacketsBefore = TrafficStats.getTotalRxPackets();
-        final long totalTxBytesBefore = TrafficStats.getTotalTxBytes();
-        final long totalRxBytesBefore = TrafficStats.getTotalRxBytes();
-        final long uidTxBytesBefore = TrafficStats.getUidTxBytes(Process.myUid());
-        final long uidRxBytesBefore = TrafficStats.getUidRxBytes(Process.myUid());
-        final long uidTxPacketsBefore = TrafficStats.getUidTxPackets(Process.myUid());
-        final long uidRxPacketsBefore = TrafficStats.getUidRxPackets(Process.myUid());
-        final long ifaceTxPacketsBefore = TrafficStats.getTxPackets("lo");
-        final long ifaceRxPacketsBefore = TrafficStats.getRxPackets("lo");
-
-        // Transfer 1MB of data across an explicitly localhost socket.
-        final int byteCount = 1024;
-        final int packetCount = 1024;
-
-        TrafficStats.startDataProfiling(null);
-        final ServerSocket server = new ServerSocket(0);
-        new Thread("TrafficStatsTest.testTrafficStatsForLocalhost") {
-            @Override
-            public void run() {
-                try {
-                    final Socket socket = new Socket("localhost", server.getLocalPort());
-                    // Make sure that each write()+flush() turns into a packet:
-                    // disable Nagle.
-                    socket.setTcpNoDelay(true);
-                    final OutputStream out = socket.getOutputStream();
-                    final byte[] buf = new byte[byteCount];
-                    TrafficStats.setThreadStatsTag(0x42);
-                    TrafficStats.tagSocket(socket);
-                    for (int i = 0; i < packetCount; i++) {
-                        out.write(buf);
-                        out.flush();
-                        try {
-                            // Bug: 10668088, Even with Nagle disabled, and flushing the 1024 bytes
-                            // the kernel still regroups data into a larger packet.
-                            Thread.sleep(5);
-                        } catch (InterruptedException e) {
-                        }
-                    }
-                    out.close();
-                    socket.close();
-                } catch (IOException e) {
-                    Log.i(LOG_TAG, "Badness during writes to socket: " + e);
-                }
-            }
-        }.start();
-
-        int read = 0;
-        try {
-            final Socket socket = server.accept();
-            socket.setTcpNoDelay(true);
-            TrafficStats.setThreadStatsTag(0x43);
-            TrafficStats.tagSocket(socket);
-            final InputStream in = socket.getInputStream();
-            final byte[] buf = new byte[byteCount];
-            while (read < byteCount * packetCount) {
-                int n = in.read(buf);
-                assertTrue("Unexpected EOF", n > 0);
-                read += n;
-            }
-        } finally {
-            server.close();
-        }
-        assertTrue("Not all data read back", read >= byteCount * packetCount);
-
-        // It's too fast to call getUidTxBytes function.
-        try {
-            Thread.sleep(1000);
-        } catch (InterruptedException e) {
-        }
-        final NetworkStats testStats = TrafficStats.stopDataProfiling(null);
-
-        final long mobileTxPacketsAfter = TrafficStats.getMobileTxPackets();
-        final long mobileRxPacketsAfter = TrafficStats.getMobileRxPackets();
-        final long mobileTxBytesAfter = TrafficStats.getMobileTxBytes();
-        final long mobileRxBytesAfter = TrafficStats.getMobileRxBytes();
-        final long totalTxPacketsAfter = TrafficStats.getTotalTxPackets();
-        final long totalRxPacketsAfter = TrafficStats.getTotalRxPackets();
-        final long totalTxBytesAfter = TrafficStats.getTotalTxBytes();
-        final long totalRxBytesAfter = TrafficStats.getTotalRxBytes();
-        final long uidTxBytesAfter = TrafficStats.getUidTxBytes(Process.myUid());
-        final long uidRxBytesAfter = TrafficStats.getUidRxBytes(Process.myUid());
-        final long uidTxPacketsAfter = TrafficStats.getUidTxPackets(Process.myUid());
-        final long uidRxPacketsAfter = TrafficStats.getUidRxPackets(Process.myUid());
-        final long uidTxDeltaBytes = uidTxBytesAfter - uidTxBytesBefore;
-        final long uidTxDeltaPackets = uidTxPacketsAfter - uidTxPacketsBefore;
-        final long uidRxDeltaBytes = uidRxBytesAfter - uidRxBytesBefore;
-        final long uidRxDeltaPackets = uidRxPacketsAfter - uidRxPacketsBefore;
-        final long ifaceTxPacketsAfter = TrafficStats.getTxPackets("lo");
-        final long ifaceRxPacketsAfter = TrafficStats.getRxPackets("lo");
-        final long ifaceTxDeltaPackets = ifaceTxPacketsAfter - ifaceTxPacketsBefore;
-        final long ifaceRxDeltaPackets = ifaceRxPacketsAfter - ifaceRxPacketsBefore;
-
-        // Localhost traffic *does* count against per-UID stats.
-        /*
-         * Calculations:
-         *  - bytes
-         *   bytes is approx: packets * data + packets * acks;
-         *   but sometimes there are less acks than packets, so we set a lower
-         *   limit of 1 ack.
-         *  - setup/teardown
-         *   + 7 approx.: syn, syn-ack, ack, fin-ack, ack, fin-ack, ack;
-         *   but sometimes the last find-acks just vanish, so we set a lower limit of +5.
-         */
-        final int maxExpectedExtraPackets = 7;
-        final int minExpectedExtraPackets = 5;
-
-        // Some other tests don't cleanup connections correctly.
-        // They have the same UID, so we discount their lingering traffic
-        // which happens only on non-localhost, such as TCP FIN retranmission packets
-        final long deltaTxOtherPackets = (totalTxPacketsAfter - totalTxPacketsBefore)
-                - uidTxDeltaPackets;
-        final long deltaRxOtherPackets = (totalRxPacketsAfter - totalRxPacketsBefore)
-                - uidRxDeltaPackets;
-        if (deltaTxOtherPackets > 0 || deltaRxOtherPackets > 0) {
-            Log.i(LOG_TAG, "lingering traffic data: " + deltaTxOtherPackets + "/"
-                    + deltaRxOtherPackets);
-        }
-
-        // Check that the per-uid stats obtained from data profiling contain the expected values.
-        // The data profiling snapshot is generated from the readNetworkStatsDetail() method in
-        // networkStatsService, so it's possible to verify that the detailed stats for a given
-        // uid are correct.
-        final NetworkStats.Entry entry = testStats.getTotal(null, Process.myUid());
-        final long pktBytes = tcpPacketToIpBytes(packetCount, byteCount);
-        final long pktWithNoDataBytes = tcpPacketToIpBytes(packetCount, 0);
-        final long minExpExtraPktBytes = tcpPacketToIpBytes(minExpectedExtraPackets, 0);
-        final long maxExpExtraPktBytes = tcpPacketToIpBytes(maxExpectedExtraPackets, 0);
-        final long deltaTxOtherPktBytes = tcpPacketToIpBytes(deltaTxOtherPackets, 0);
-        final long deltaRxOtherPktBytes  = tcpPacketToIpBytes(deltaRxOtherPackets, 0);
-        assertInRange("txPackets detail", entry.txPackets, packetCount + minExpectedExtraPackets,
-                uidTxDeltaPackets);
-        assertInRange("rxPackets detail", entry.rxPackets, packetCount + minExpectedExtraPackets,
-                uidRxDeltaPackets);
-        assertInRange("txBytes detail", entry.txBytes, pktBytes + minExpExtraPktBytes,
-                uidTxDeltaBytes);
-        assertInRange("rxBytes detail", entry.rxBytes, pktBytes + minExpExtraPktBytes,
-                uidRxDeltaBytes);
-        assertInRange("uidtxp", uidTxDeltaPackets, packetCount + minExpectedExtraPackets,
-                packetCount + packetCount + maxExpectedExtraPackets + deltaTxOtherPackets);
-        assertInRange("uidrxp", uidRxDeltaPackets, packetCount + minExpectedExtraPackets,
-                packetCount + packetCount + maxExpectedExtraPackets + deltaRxOtherPackets);
-        assertInRange("uidtxb", uidTxDeltaBytes, pktBytes + minExpExtraPktBytes,
-                pktBytes + pktWithNoDataBytes + maxExpExtraPktBytes + deltaTxOtherPktBytes);
-        assertInRange("uidrxb", uidRxDeltaBytes, pktBytes + minExpExtraPktBytes,
-                pktBytes + pktWithNoDataBytes + maxExpExtraPktBytes + deltaRxOtherPktBytes);
-        assertInRange("iftxp", ifaceTxDeltaPackets, packetCount + minExpectedExtraPackets,
-                packetCount + packetCount + maxExpectedExtraPackets + deltaTxOtherPackets);
-        assertInRange("ifrxp", ifaceRxDeltaPackets, packetCount + minExpectedExtraPackets,
-                packetCount + packetCount + maxExpectedExtraPackets + deltaRxOtherPackets);
-
-        // Localhost traffic *does* count against total stats.
-        // Check the total stats increased after test data transfer over localhost has been made.
-        assertTrue("ttxp: " + totalTxPacketsBefore + " -> " + totalTxPacketsAfter,
-                totalTxPacketsAfter >= totalTxPacketsBefore + uidTxDeltaPackets);
-        assertTrue("trxp: " + totalRxPacketsBefore + " -> " + totalRxPacketsAfter,
-                totalRxPacketsAfter >= totalRxPacketsBefore + uidRxDeltaPackets);
-        assertTrue("ttxb: " + totalTxBytesBefore + " -> " + totalTxBytesAfter,
-                totalTxBytesAfter >= totalTxBytesBefore + uidTxDeltaBytes);
-        assertTrue("trxb: " + totalRxBytesBefore + " -> " + totalRxBytesAfter,
-                totalRxBytesAfter >= totalRxBytesBefore + uidRxDeltaBytes);
-        assertTrue("iftxp: " + ifaceTxPacketsBefore + " -> " + ifaceTxPacketsAfter,
-                totalTxPacketsAfter >= totalTxPacketsBefore + ifaceTxDeltaPackets);
-        assertTrue("ifrxp: " + ifaceRxPacketsBefore + " -> " + ifaceRxPacketsAfter,
-                totalRxPacketsAfter >= totalRxPacketsBefore + ifaceRxDeltaPackets);
-
-        // Localhost traffic should *not* count against mobile stats,
-        // There might be some other traffic, but nowhere near 1MB.
-        assertInRange("mtxp", mobileTxPacketsAfter, mobileTxPacketsBefore,
-                mobileTxPacketsBefore + 500);
-        assertInRange("mrxp", mobileRxPacketsAfter, mobileRxPacketsBefore,
-                mobileRxPacketsBefore + 500);
-        assertInRange("mtxb", mobileTxBytesAfter, mobileTxBytesBefore,
-                mobileTxBytesBefore + 200000);
-        assertInRange("mrxb", mobileRxBytesAfter, mobileRxBytesBefore,
-                mobileRxBytesBefore + 200000);
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/TunUtils.java b/tests/cts/net/src/android/net/cts/TunUtils.java
deleted file mode 100644
index adaba9d..0000000
--- a/tests/cts/net/src/android/net/cts/TunUtils.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * 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.cts.PacketUtils.IP4_HDRLEN;
-import static android.net.cts.PacketUtils.IP6_HDRLEN;
-import static android.net.cts.PacketUtils.IPPROTO_ESP;
-import static android.net.cts.PacketUtils.UDP_HDRLEN;
-import static android.system.OsConstants.IPPROTO_UDP;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import android.os.ParcelFileDescriptor;
-
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.function.Predicate;
-
-public class TunUtils {
-    private static final String TAG = TunUtils.class.getSimpleName();
-
-    protected static final int IP4_ADDR_OFFSET = 12;
-    protected static final int IP4_ADDR_LEN = 4;
-    protected static final int IP6_ADDR_OFFSET = 8;
-    protected static final int IP6_ADDR_LEN = 16;
-    protected static final int IP4_PROTO_OFFSET = 9;
-    protected static final int IP6_PROTO_OFFSET = 6;
-
-    private static final int DATA_BUFFER_LEN = 4096;
-    private static final int TIMEOUT = 1000;
-
-    private final List<byte[]> mPackets = new ArrayList<>();
-    private final ParcelFileDescriptor mTunFd;
-    private final Thread mReaderThread;
-
-    public TunUtils(ParcelFileDescriptor tunFd) {
-        mTunFd = tunFd;
-
-        // Start background reader thread
-        mReaderThread =
-                new Thread(
-                        () -> {
-                            try {
-                                // Loop will exit and thread will quit when tunFd is closed.
-                                // Receiving either EOF or an exception will exit this reader loop.
-                                // FileInputStream in uninterruptable, so there's no good way to
-                                // ensure that this thread shuts down except upon FD closure.
-                                while (true) {
-                                    byte[] intercepted = receiveFromTun();
-                                    if (intercepted == null) {
-                                        // Exit once we've hit EOF
-                                        return;
-                                    } else if (intercepted.length > 0) {
-                                        // Only save packet if we've received any bytes.
-                                        synchronized (mPackets) {
-                                            mPackets.add(intercepted);
-                                            mPackets.notifyAll();
-                                        }
-                                    }
-                                }
-                            } catch (IOException ignored) {
-                                // Simply exit this reader thread
-                                return;
-                            }
-                        });
-        mReaderThread.start();
-    }
-
-    private byte[] receiveFromTun() throws IOException {
-        FileInputStream in = new FileInputStream(mTunFd.getFileDescriptor());
-        byte[] inBytes = new byte[DATA_BUFFER_LEN];
-        int bytesRead = in.read(inBytes);
-
-        if (bytesRead < 0) {
-            return null; // return null for EOF
-        } else if (bytesRead >= DATA_BUFFER_LEN) {
-            throw new IllegalStateException("Too big packet. Fragmentation unsupported");
-        }
-        return Arrays.copyOf(inBytes, bytesRead);
-    }
-
-    private byte[] getFirstMatchingPacket(Predicate<byte[]> verifier, int startIndex) {
-        synchronized (mPackets) {
-            for (int i = startIndex; i < mPackets.size(); i++) {
-                byte[] pkt = mPackets.get(i);
-                if (verifier.test(pkt)) {
-                    return pkt;
-                }
-            }
-        }
-        return null;
-    }
-
-    protected byte[] awaitPacket(Predicate<byte[]> verifier) throws Exception {
-        long endTime = System.currentTimeMillis() + TIMEOUT;
-        int startIndex = 0;
-
-        synchronized (mPackets) {
-            while (System.currentTimeMillis() < endTime) {
-                final byte[] pkt = getFirstMatchingPacket(verifier, startIndex);
-                if (pkt != null) {
-                    return pkt; // We've found the packet we're looking for.
-                }
-
-                startIndex = mPackets.size();
-
-                // Try to prevent waiting too long. If waitTimeout <= 0, we've already hit timeout
-                long waitTimeout = endTime - System.currentTimeMillis();
-                if (waitTimeout > 0) {
-                    mPackets.wait(waitTimeout);
-                }
-            }
-        }
-
-        fail("No packet found matching verifier");
-        throw new IllegalStateException("Impossible condition; should have thrown in fail()");
-    }
-
-    public byte[] awaitEspPacketNoPlaintext(
-            int spi, byte[] plaintext, boolean useEncap, int expectedPacketSize) throws Exception {
-        final byte[] espPkt = awaitPacket(
-                (pkt) -> isEspFailIfSpecifiedPlaintextFound(pkt, spi, useEncap, plaintext));
-
-        // Validate packet size
-        assertEquals(expectedPacketSize, espPkt.length);
-
-        return espPkt; // We've found the packet we're looking for.
-    }
-
-    private static boolean isSpiEqual(byte[] pkt, int espOffset, int spi) {
-        // Check SPI byte by byte.
-        return pkt[espOffset] == (byte) ((spi >>> 24) & 0xff)
-                && pkt[espOffset + 1] == (byte) ((spi >>> 16) & 0xff)
-                && pkt[espOffset + 2] == (byte) ((spi >>> 8) & 0xff)
-                && pkt[espOffset + 3] == (byte) (spi & 0xff);
-    }
-
-    /**
-     * Variant of isEsp that also fails the test if the provided plaintext is found
-     *
-     * @param pkt the packet bytes to verify
-     * @param spi the expected SPI to look for
-     * @param encap whether encap was enabled, and the packet has a UDP header
-     * @param plaintext the plaintext packet before outbound encryption, which MUST not appear in
-     *     the provided packet.
-     */
-    private static boolean isEspFailIfSpecifiedPlaintextFound(
-            byte[] pkt, int spi, boolean encap, byte[] plaintext) {
-        if (Collections.indexOfSubList(Arrays.asList(pkt), Arrays.asList(plaintext)) != -1) {
-            fail("Banned plaintext packet found");
-        }
-
-        return isEsp(pkt, spi, encap);
-    }
-
-    private static boolean isEsp(byte[] pkt, int spi, boolean encap) {
-        if (isIpv6(pkt)) {
-            // IPv6 UDP encap not supported by kernels; assume non-encap.
-            return pkt[IP6_PROTO_OFFSET] == IPPROTO_ESP && isSpiEqual(pkt, IP6_HDRLEN, spi);
-        } else {
-            // Use default IPv4 header length (assuming no options)
-            if (encap) {
-                return pkt[IP4_PROTO_OFFSET] == IPPROTO_UDP
-                        && isSpiEqual(pkt, IP4_HDRLEN + UDP_HDRLEN, spi);
-            } else {
-                return pkt[IP4_PROTO_OFFSET] == IPPROTO_ESP && isSpiEqual(pkt, IP4_HDRLEN, spi);
-            }
-        }
-    }
-
-    public static boolean isIpv6(byte[] pkt) {
-        // First nibble shows IP version. 0x60 for IPv6
-        return (pkt[0] & (byte) 0xF0) == (byte) 0x60;
-    }
-
-    private static byte[] getReflectedPacket(byte[] pkt) {
-        byte[] reflected = Arrays.copyOf(pkt, pkt.length);
-
-        if (isIpv6(pkt)) {
-            // Set reflected packet's dst to that of the original's src
-            System.arraycopy(
-                    pkt, // src
-                    IP6_ADDR_OFFSET + IP6_ADDR_LEN, // src offset
-                    reflected, // dst
-                    IP6_ADDR_OFFSET, // dst offset
-                    IP6_ADDR_LEN); // len
-            // Set reflected packet's src IP to that of the original's dst IP
-            System.arraycopy(
-                    pkt, // src
-                    IP6_ADDR_OFFSET, // src offset
-                    reflected, // dst
-                    IP6_ADDR_OFFSET + IP6_ADDR_LEN, // dst offset
-                    IP6_ADDR_LEN); // len
-        } else {
-            // Set reflected packet's dst to that of the original's src
-            System.arraycopy(
-                    pkt, // src
-                    IP4_ADDR_OFFSET + IP4_ADDR_LEN, // src offset
-                    reflected, // dst
-                    IP4_ADDR_OFFSET, // dst offset
-                    IP4_ADDR_LEN); // len
-            // Set reflected packet's src IP to that of the original's dst IP
-            System.arraycopy(
-                    pkt, // src
-                    IP4_ADDR_OFFSET, // src offset
-                    reflected, // dst
-                    IP4_ADDR_OFFSET + IP4_ADDR_LEN, // dst offset
-                    IP4_ADDR_LEN); // len
-        }
-        return reflected;
-    }
-
-    /** Takes all captured packets, flips the src/dst, and re-injects them. */
-    public void reflectPackets() throws IOException {
-        synchronized (mPackets) {
-            for (byte[] pkt : mPackets) {
-                injectPacket(getReflectedPacket(pkt));
-            }
-        }
-    }
-
-    public void injectPacket(byte[] pkt) throws IOException {
-        FileOutputStream out = new FileOutputStream(mTunFd.getFileDescriptor());
-        out.write(pkt);
-        out.flush();
-    }
-
-    /** Resets the intercepted packets. */
-    public void reset() throws IOException {
-        synchronized (mPackets) {
-            mPackets.clear();
-        }
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/UriTest.java b/tests/cts/net/src/android/net/cts/UriTest.java
deleted file mode 100644
index 40b8fb7..0000000
--- a/tests/cts/net/src/android/net/cts/UriTest.java
+++ /dev/null
@@ -1,590 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-import android.content.ContentUris;
-import android.net.Uri;
-import android.os.Parcel;
-import android.test.AndroidTestCase;
-import java.io.File;
-import java.util.Arrays;
-import java.util.ArrayList;
-
-public class UriTest extends AndroidTestCase {
-    public void testParcelling() {
-        parcelAndUnparcel(Uri.parse("foo:bob%20lee"));
-        parcelAndUnparcel(Uri.fromParts("foo", "bob lee", "fragment"));
-        parcelAndUnparcel(new Uri.Builder()
-             .scheme("http")
-            .authority("crazybob.org")
-            .path("/rss/")
-            .encodedQuery("a=b")
-            .fragment("foo")
-            .build());
-     }
-
-    private void parcelAndUnparcel(Uri u) {
-        Parcel p = Parcel.obtain();
-        Uri.writeToParcel(p, u);
-        p.setDataPosition(0);
-        assertEquals(u, Uri.CREATOR.createFromParcel(p));
-
-        p.setDataPosition(0);
-        u = u.buildUpon().build();
-        Uri.writeToParcel(p, u);
-        p.setDataPosition(0);
-        assertEquals(u, Uri.CREATOR.createFromParcel(p));
-    }
-
-    public void testBuildUpon() {
-        Uri u = Uri.parse("bob:lee").buildUpon().scheme("robert").build();
-        assertEquals("robert", u.getScheme());
-        assertEquals("lee", u.getEncodedSchemeSpecificPart());
-        assertEquals("lee", u.getSchemeSpecificPart());
-        assertNull(u.getQuery());
-        assertNull(u.getPath());
-        assertNull(u.getAuthority());
-        assertNull(u.getHost());
-
-        Uri a = Uri.fromParts("foo", "bar", "tee");
-        Uri b = a.buildUpon().fragment("new").build();
-        assertEquals("new", b.getFragment());
-        assertEquals("bar", b.getSchemeSpecificPart());
-        assertEquals("foo", b.getScheme());
-        a = new Uri.Builder()
-                .scheme("foo")
-                .encodedOpaquePart("bar")
-                .fragment("tee")
-                .build();
-        b = a.buildUpon().fragment("new").build();
-        assertEquals("new", b.getFragment());
-        assertEquals("bar", b.getSchemeSpecificPart());
-        assertEquals("foo", b.getScheme());
-
-        a = Uri.fromParts("scheme", "[2001:db8::dead:e1f]/foo", "bar");
-        b = a.buildUpon().fragment("qux").build();
-        assertEquals("qux", b.getFragment());
-        assertEquals("[2001:db8::dead:e1f]/foo", b.getSchemeSpecificPart());
-        assertEquals("scheme", b.getScheme());
-    }
-
-    public void testStringUri() {
-        assertEquals("bob lee",
-                Uri.parse("foo:bob%20lee").getSchemeSpecificPart());
-        assertEquals("bob%20lee",
-                Uri.parse("foo:bob%20lee").getEncodedSchemeSpecificPart());
-
-        assertEquals("/bob%20lee",
-                Uri.parse("foo:/bob%20lee").getEncodedPath());
-        assertNull(Uri.parse("foo:bob%20lee").getPath());
-
-        assertEquals("bob%20lee",
-                Uri.parse("foo:?bob%20lee").getEncodedQuery());
-        assertNull(Uri.parse("foo:bob%20lee").getEncodedQuery());
-        assertNull(Uri.parse("foo:bar#?bob%20lee").getQuery());
-
-        assertEquals("bob%20lee",
-                Uri.parse("foo:#bob%20lee").getEncodedFragment());
-
-        Uri uri = Uri.parse("http://localhost:42");
-        assertEquals("localhost", uri.getHost());
-        assertEquals(42, uri.getPort());
-
-        uri = Uri.parse("http://bob@localhost:42");
-        assertEquals("bob", uri.getUserInfo());
-        assertEquals("localhost", uri.getHost());
-        assertEquals(42, uri.getPort());
-
-        uri = Uri.parse("http://bob%20lee@localhost:42");
-        assertEquals("bob lee", uri.getUserInfo());
-        assertEquals("bob%20lee", uri.getEncodedUserInfo());
-
-        uri = Uri.parse("http://localhost");
-        assertEquals("localhost", uri.getHost());
-        assertEquals(-1, uri.getPort());
-
-        uri = Uri.parse("http://a:a@example.com:a@example2.com/path");
-        assertEquals("a:a@example.com:a@example2.com", uri.getAuthority());
-        assertEquals("example2.com", uri.getHost());
-        assertEquals(-1, uri.getPort());
-        assertEquals("/path", uri.getPath());
-
-        uri = Uri.parse("http://a.foo.com\\.example.com/path");
-        assertEquals("a.foo.com", uri.getHost());
-        assertEquals(-1, uri.getPort());
-        assertEquals("\\.example.com/path", uri.getPath());
-
-        uri = Uri.parse("https://[2001:db8::dead:e1f]/foo");
-        assertEquals("[2001:db8::dead:e1f]", uri.getAuthority());
-        assertNull(uri.getUserInfo());
-        assertEquals("[2001:db8::dead:e1f]", uri.getHost());
-        assertEquals(-1, uri.getPort());
-        assertEquals("/foo", uri.getPath());
-        assertEquals(null, uri.getFragment());
-        assertEquals("//[2001:db8::dead:e1f]/foo", uri.getSchemeSpecificPart());
-
-        uri = Uri.parse("https://[2001:db8::dead:e1f]/#foo");
-        assertEquals("[2001:db8::dead:e1f]", uri.getAuthority());
-        assertNull(uri.getUserInfo());
-        assertEquals("[2001:db8::dead:e1f]", uri.getHost());
-        assertEquals(-1, uri.getPort());
-        assertEquals("/", uri.getPath());
-        assertEquals("foo", uri.getFragment());
-        assertEquals("//[2001:db8::dead:e1f]/", uri.getSchemeSpecificPart());
-
-        uri = Uri.parse(
-                "https://some:user@[2001:db8::dead:e1f]:1234/foo?corge=thud&corge=garp#bar");
-        assertEquals("some:user@[2001:db8::dead:e1f]:1234", uri.getAuthority());
-        assertEquals("some:user", uri.getUserInfo());
-        assertEquals("[2001:db8::dead:e1f]", uri.getHost());
-        assertEquals(1234, uri.getPort());
-        assertEquals("/foo", uri.getPath());
-        assertEquals("bar", uri.getFragment());
-        assertEquals("//some:user@[2001:db8::dead:e1f]:1234/foo?corge=thud&corge=garp",
-                uri.getSchemeSpecificPart());
-        assertEquals("corge=thud&corge=garp", uri.getQuery());
-        assertEquals("thud", uri.getQueryParameter("corge"));
-        assertEquals(Arrays.asList("thud", "garp"), uri.getQueryParameters("corge"));
-    }
-
-    public void testCompareTo() {
-        Uri a = Uri.parse("foo:a");
-        Uri b = Uri.parse("foo:b");
-        Uri b2 = Uri.parse("foo:b");
-
-        assertTrue(a.compareTo(b) < 0);
-        assertTrue(b.compareTo(a) > 0);
-        assertEquals(0, b.compareTo(b2));
-    }
-
-    public void testEqualsAndHashCode() {
-        Uri a = Uri.parse("http://crazybob.org/test/?foo=bar#tee");
-
-        Uri b = new Uri.Builder()
-                .scheme("http")
-                .authority("crazybob.org")
-                .path("/test/")
-                .encodedQuery("foo=bar")
-                .fragment("tee")
-                .build();
-
-        // Try alternate builder methods.
-        Uri c = new Uri.Builder()
-                .scheme("http")
-                .encodedAuthority("crazybob.org")
-                .encodedPath("/test/")
-                .encodedQuery("foo=bar")
-                .encodedFragment("tee")
-                .build();
-
-        assertFalse(Uri.EMPTY.equals(null));
-        assertEquals(a, b);
-        assertEquals(b, c);
-        assertEquals(c, a);
-        assertEquals(a.hashCode(), b.hashCode());
-        assertEquals(b.hashCode(), c.hashCode());
-    }
-
-    public void testEncodeAndDecode() {
-        String encoded = Uri.encode("Bob:/", "/");
-        assertEquals(-1, encoded.indexOf(':'));
-        assertTrue(encoded.indexOf('/') > -1);
-        assertEncodeDecodeRoundtripExact(null);
-        assertEncodeDecodeRoundtripExact("");
-        assertEncodeDecodeRoundtripExact("Bob");
-        assertEncodeDecodeRoundtripExact(":Bob");
-        assertEncodeDecodeRoundtripExact("::Bob");
-        assertEncodeDecodeRoundtripExact("Bob::Lee");
-        assertEncodeDecodeRoundtripExact("Bob:Lee");
-        assertEncodeDecodeRoundtripExact("Bob::");
-        assertEncodeDecodeRoundtripExact("Bob:");
-        assertEncodeDecodeRoundtripExact("::Bob::");
-        assertEncodeDecodeRoundtripExact("https:/some:user@[2001:db8::dead:e1f]:1234/foo#bar");
-    }
-
-    private static void assertEncodeDecodeRoundtripExact(String s) {
-        assertEquals(s, Uri.decode(Uri.encode(s, null)));
-    }
-
-    public void testDecode_emptyString_returnsEmptyString() {
-        assertEquals("", Uri.decode(""));
-    }
-
-    public void testDecode_null_returnsNull() {
-        assertNull(Uri.decode(null));
-    }
-
-    public void testDecode_wrongHexDigit() {
-        // %p in the end.
-        assertEquals("ab/$\u0102%\u0840\uFFFD\u0000", Uri.decode("ab%2f$%C4%82%25%e0%a1%80%p"));
-    }
-
-    public void testDecode_secondHexDigitWrong() {
-        // %1p in the end.
-        assertEquals("ab/$\u0102%\u0840\uFFFD\u0001", Uri.decode("ab%2f$%c4%82%25%e0%a1%80%1p"));
-    }
-
-    public void testDecode_endsWithPercent_appendsUnknownCharacter() {
-        // % in the end.
-        assertEquals("ab/$\u0102%\u0840\uFFFD", Uri.decode("ab%2f$%c4%82%25%e0%a1%80%"));
-    }
-
-    public void testDecode_plusNotConverted() {
-        assertEquals("ab/$\u0102%+\u0840", Uri.decode("ab%2f$%c4%82%25+%e0%a1%80"));
-    }
-
-    // Last character needs decoding (make sure we are flushing the buffer with chars to decode).
-    public void testDecode_lastCharacter() {
-        assertEquals("ab/$\u0102%\u0840", Uri.decode("ab%2f$%c4%82%25%e0%a1%80"));
-    }
-
-    // Check that a second row of encoded characters is decoded properly (internal buffers are
-    // reset properly).
-    public void testDecode_secondRowOfEncoded() {
-        assertEquals("ab/$\u0102%\u0840aa\u0840",
-                Uri.decode("ab%2f$%c4%82%25%e0%a1%80aa%e0%a1%80"));
-    }
-
-    public void testFromFile() {
-        File f = new File("/tmp/bob");
-        Uri uri = Uri.fromFile(f);
-        assertEquals("file:///tmp/bob", uri.toString());
-        try {
-            Uri.fromFile(null);
-            fail("testFile fail");
-            } catch (NullPointerException e) {}
-    }
-
-    public void testQueryParameters() {
-        Uri uri = Uri.parse("content://user");
-        assertEquals(null, uri.getQueryParameter("a"));
-
-        uri = uri.buildUpon().appendQueryParameter("a", "b").build();
-        assertEquals("b", uri.getQueryParameter("a"));
-
-        uri = uri.buildUpon().appendQueryParameter("a", "b2").build();
-        assertEquals(Arrays.asList("b", "b2"), uri.getQueryParameters("a"));
-
-        uri = uri.buildUpon().appendQueryParameter("c", "d").build();
-        assertEquals(Arrays.asList("b", "b2"), uri.getQueryParameters("a"));
-        assertEquals("d", uri.getQueryParameter("c"));
-    }
-
-    public void testPathOperations() {
-        Uri uri = Uri.parse("content://user/a/b");
-
-        assertEquals(2, uri.getPathSegments().size());
-        assertEquals("a", uri.getPathSegments().get(0));
-        assertEquals("b", uri.getPathSegments().get(1));
-        assertEquals("b", uri.getLastPathSegment());
-
-        Uri first = uri;
-        uri = uri.buildUpon().appendPath("c").build();
-        assertEquals(3, uri.getPathSegments().size());
-        assertEquals("c", uri.getPathSegments().get(2));
-        assertEquals("c", uri.getLastPathSegment());
-        assertEquals("content://user/a/b/c", uri.toString());
-
-        uri = ContentUris.withAppendedId(uri, 100);
-        assertEquals(4, uri.getPathSegments().size());
-        assertEquals("100", uri.getPathSegments().get(3));
-        assertEquals("100", uri.getLastPathSegment());
-        assertEquals(100, ContentUris.parseId(uri));
-        assertEquals("content://user/a/b/c/100", uri.toString());
-
-        // Make sure the original URI is still intact.
-        assertEquals(2, first.getPathSegments().size());
-        assertEquals("b", first.getLastPathSegment());
-
-        try {
-        first.getPathSegments().get(2);
-        fail("test path operations");
-        } catch (IndexOutOfBoundsException e) {}
-
-        assertEquals(null, Uri.EMPTY.getLastPathSegment());
-
-        Uri withC = Uri.parse("foo:/a/b/").buildUpon().appendPath("c").build();
-        assertEquals("/a/b/c", withC.getPath());
-    }
-
-    public void testOpaqueUri() {
-        Uri uri = Uri.parse("mailto:nobody");
-        testOpaqueUri(uri);
-
-        uri = uri.buildUpon().build();
-        testOpaqueUri(uri);
-
-        uri = Uri.fromParts("mailto", "nobody", null);
-        testOpaqueUri(uri);
-
-        uri = uri.buildUpon().build();
-        testOpaqueUri(uri);
-
-        uri = new Uri.Builder()
-                .scheme("mailto")
-                .opaquePart("nobody")
-                .build();
-        testOpaqueUri(uri);
-
-        uri = uri.buildUpon().build();
-        testOpaqueUri(uri);
-    }
-
-    private void testOpaqueUri(Uri uri) {
-        assertEquals("mailto", uri.getScheme());
-        assertEquals("nobody", uri.getSchemeSpecificPart());
-        assertEquals("nobody", uri.getEncodedSchemeSpecificPart());
-
-        assertNull(uri.getFragment());
-        assertTrue(uri.isAbsolute());
-        assertTrue(uri.isOpaque());
-        assertFalse(uri.isRelative());
-        assertFalse(uri.isHierarchical());
-
-        assertNull(uri.getAuthority());
-        assertNull(uri.getEncodedAuthority());
-        assertNull(uri.getPath());
-        assertNull(uri.getEncodedPath());
-        assertNull(uri.getUserInfo());
-        assertNull(uri.getEncodedUserInfo());
-        assertNull(uri.getQuery());
-        assertNull(uri.getEncodedQuery());
-        assertNull(uri.getHost());
-        assertEquals(-1, uri.getPort());
-
-        assertTrue(uri.getPathSegments().isEmpty());
-        assertNull(uri.getLastPathSegment());
-
-        assertEquals("mailto:nobody", uri.toString());
-
-        Uri withFragment = uri.buildUpon().fragment("top").build();
-        assertEquals("mailto:nobody#top", withFragment.toString());
-    }
-
-    public void testHierarchicalUris() {
-        testHierarchical("http", "google.com", "/p1/p2", "query", "fragment");
-        testHierarchical("file", null, "/p1/p2", null, null);
-        testHierarchical("content", "contact", "/p1/p2", null, null);
-        testHierarchical("http", "google.com", "/p1/p2", null, "fragment");
-        testHierarchical("http", "google.com", "", null, "fragment");
-        testHierarchical("http", "google.com", "", "query", "fragment");
-        testHierarchical("http", "google.com", "", "query", null);
-        testHierarchical("http", null, "/", "query", null);
-    }
-
-    private static void testHierarchical(String scheme, String authority,
-        String path, String query, String fragment) {
-        StringBuilder sb = new StringBuilder();
-
-        if (authority != null) {
-            sb.append("//").append(authority);
-        }
-        if (path != null) {
-            sb.append(path);
-        }
-        if (query != null) {
-            sb.append('?').append(query);
-        }
-
-        String ssp = sb.toString();
-
-        if (scheme != null) {
-            sb.insert(0, scheme + ":");
-        }
-        if (fragment != null) {
-            sb.append('#').append(fragment);
-        }
-
-        String uriString = sb.toString();
-
-        Uri uri = Uri.parse(uriString);
-
-        // Run these twice to test caching.
-        compareHierarchical(
-        uriString, ssp, uri, scheme, authority, path, query, fragment);
-        compareHierarchical(
-        uriString, ssp, uri, scheme, authority, path, query, fragment);
-
-        // Test rebuilt version.
-        uri = uri.buildUpon().build();
-
-        // Run these twice to test caching.
-        compareHierarchical(
-                uriString, ssp, uri, scheme, authority, path, query, fragment);
-        compareHierarchical(
-                uriString, ssp, uri, scheme, authority, path, query, fragment);
-
-        // The decoded and encoded versions of the inputs are all the same.
-        // We'll test the actual encoding decoding separately.
-
-        // Test building with encoded versions.
-        Uri built = new Uri.Builder()
-            .scheme(scheme)
-                .encodedAuthority(authority)
-                .encodedPath(path)
-                .encodedQuery(query)
-                .encodedFragment(fragment)
-                .build();
-
-        compareHierarchical(
-                uriString, ssp, built, scheme, authority, path, query, fragment);
-        compareHierarchical(
-                uriString, ssp, built, scheme, authority, path, query, fragment);
-
-        // Test building with decoded versions.
-        built = new Uri.Builder()
-                .scheme(scheme)
-                .authority(authority)
-                .path(path)
-                .query(query)
-                .fragment(fragment)
-                .build();
-
-        compareHierarchical(
-                uriString, ssp, built, scheme, authority, path, query, fragment);
-        compareHierarchical(
-                uriString, ssp, built, scheme, authority, path, query, fragment);
-
-        // Rebuild.
-        built = built.buildUpon().build();
-
-        compareHierarchical(
-                uriString, ssp, built, scheme, authority, path, query, fragment);
-        compareHierarchical(
-                uriString, ssp, built, scheme, authority, path, query, fragment);
-    }
-
-    private static void compareHierarchical(String uriString, String ssp,
-        Uri uri,
-        String scheme, String authority, String path, String query,
-        String fragment) {
-        assertEquals(scheme, uri.getScheme());
-        assertEquals(authority, uri.getAuthority());
-        assertEquals(authority, uri.getEncodedAuthority());
-        assertEquals(path, uri.getPath());
-        assertEquals(path, uri.getEncodedPath());
-        assertEquals(query, uri.getQuery());
-        assertEquals(query, uri.getEncodedQuery());
-        assertEquals(fragment, uri.getFragment());
-        assertEquals(fragment, uri.getEncodedFragment());
-        assertEquals(ssp, uri.getSchemeSpecificPart());
-
-        if (scheme != null) {
-            assertTrue(uri.isAbsolute());
-            assertFalse(uri.isRelative());
-        } else {
-            assertFalse(uri.isAbsolute());
-            assertTrue(uri.isRelative());
-        }
-
-        assertFalse(uri.isOpaque());
-        assertTrue(uri.isHierarchical());
-        assertEquals(uriString, uri.toString());
-    }
-
-    public void testNormalizeScheme() {
-        assertEquals(Uri.parse(""), Uri.parse("").normalizeScheme());
-        assertEquals(Uri.parse("http://www.android.com"),
-                Uri.parse("http://www.android.com").normalizeScheme());
-        assertEquals(Uri.parse("http://USER@WWW.ANDROID.COM:100/ABOUT?foo=blah@bar=bleh#c"),
-                Uri.parse("HTTP://USER@WWW.ANDROID.COM:100/ABOUT?foo=blah@bar=bleh#c")
-                        .normalizeScheme());
-    }
-
-    public void testToSafeString_tel() {
-        checkToSafeString("tel:xxxxxx", "tel:Google");
-        checkToSafeString("tel:xxxxxxxxxx", "tel:1234567890");
-        checkToSafeString("tEl:xxx.xxx-xxxx", "tEl:123.456-7890");
-    }
-
-    public void testToSafeString_sip() {
-        checkToSafeString("sip:xxxxxxx@xxxxxxx.xxxxxxxx", "sip:android@android.com:1234");
-        checkToSafeString("sIp:xxxxxxx@xxxxxxx.xxx", "sIp:android@android.com");
-    }
-
-    public void testToSafeString_sms() {
-        checkToSafeString("sms:xxxxxx", "sms:123abc");
-        checkToSafeString("smS:xxx.xxx-xxxx", "smS:123.456-7890");
-    }
-
-    public void testToSafeString_smsto() {
-        checkToSafeString("smsto:xxxxxx", "smsto:123abc");
-        checkToSafeString("SMSTo:xxx.xxx-xxxx", "SMSTo:123.456-7890");
-    }
-
-    public void testToSafeString_mailto() {
-        checkToSafeString("mailto:xxxxxxx@xxxxxxx.xxx", "mailto:android@android.com");
-        checkToSafeString("Mailto:xxxxxxx@xxxxxxx.xxxxxxxxxx",
-                "Mailto:android@android.com/secret");
-    }
-
-    public void testToSafeString_nfc() {
-        checkToSafeString("nfc:xxxxxx", "nfc:123abc");
-        checkToSafeString("nfc:xxx.xxx-xxxx", "nfc:123.456-7890");
-        checkToSafeString("nfc:xxxxxxx@xxxxxxx.xxx", "nfc:android@android.com");
-    }
-
-    public void testToSafeString_http() {
-        checkToSafeString("http://www.android.com/...", "http://www.android.com");
-        checkToSafeString("HTTP://www.android.com/...", "HTTP://www.android.com");
-        checkToSafeString("http://www.android.com/...", "http://www.android.com/");
-        checkToSafeString("http://www.android.com/...", "http://www.android.com/secretUrl?param");
-        checkToSafeString("http://www.android.com/...",
-                "http://user:pwd@www.android.com/secretUrl?param");
-        checkToSafeString("http://www.android.com/...",
-                "http://user@www.android.com/secretUrl?param");
-        checkToSafeString("http://www.android.com/...", "http://www.android.com/secretUrl?param");
-        checkToSafeString("http:///...", "http:///path?param");
-        checkToSafeString("http:///...", "http://");
-        checkToSafeString("http://:12345/...", "http://:12345/");
-    }
-
-    public void testToSafeString_https() {
-        checkToSafeString("https://www.android.com/...", "https://www.android.com/secretUrl?param");
-        checkToSafeString("https://www.android.com:8443/...",
-                "https://user:pwd@www.android.com:8443/secretUrl?param");
-        checkToSafeString("https://www.android.com/...", "https://user:pwd@www.android.com");
-        checkToSafeString("Https://www.android.com/...", "Https://user:pwd@www.android.com");
-    }
-
-    public void testToSafeString_ftp() {
-        checkToSafeString("ftp://ftp.android.com/...", "ftp://ftp.android.com/");
-        checkToSafeString("ftP://ftp.android.com/...", "ftP://anonymous@ftp.android.com/");
-        checkToSafeString("ftp://ftp.android.com:2121/...",
-                "ftp://root:love@ftp.android.com:2121/");
-    }
-
-    public void testToSafeString_rtsp() {
-        checkToSafeString("rtsp://rtsp.android.com/...", "rtsp://rtsp.android.com/");
-        checkToSafeString("rtsp://rtsp.android.com/...", "rtsp://rtsp.android.com/video.mov");
-        checkToSafeString("rtsp://rtsp.android.com/...", "rtsp://rtsp.android.com/video.mov?param");
-        checkToSafeString("RtsP://rtsp.android.com/...", "RtsP://anonymous@rtsp.android.com/");
-        checkToSafeString("rtsp://rtsp.android.com:2121/...",
-                "rtsp://username:password@rtsp.android.com:2121/");
-    }
-
-    public void testToSafeString_notSupport() {
-        checkToSafeString("unsupported://ajkakjah/askdha/secret?secret",
-                "unsupported://ajkakjah/askdha/secret?secret");
-        checkToSafeString("unsupported:ajkakjah/askdha/secret?secret",
-                "unsupported:ajkakjah/askdha/secret?secret");
-    }
-
-    private void checkToSafeString(String expectedSafeString, String original) {
-        assertEquals(expectedSafeString, Uri.parse(original).toSafeString());
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java b/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java
deleted file mode 100644
index 4088d82..0000000
--- a/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-import junit.framework.TestCase;
-import android.net.Uri.Builder;
-import android.net.Uri;
-
-public class Uri_BuilderTest extends TestCase {
-    public void testBuilderOperations() {
-        Uri uri = Uri.parse("http://google.com/p1?query#fragment");
-        Builder builder = uri.buildUpon();
-        uri = builder.appendPath("p2").build();
-        assertEquals("http", uri.getScheme());
-        assertEquals("google.com", uri.getAuthority());
-        assertEquals("/p1/p2", uri.getPath());
-        assertEquals("query", uri.getQuery());
-        assertEquals("fragment", uri.getFragment());
-        assertEquals(uri.toString(), builder.toString());
-
-        uri = Uri.parse("mailto:nobody");
-        builder = uri.buildUpon();
-        uri = builder.build();
-        assertEquals("mailto", uri.getScheme());
-        assertEquals("nobody", uri.getSchemeSpecificPart());
-        assertEquals(uri.toString(), builder.toString());
-
-        uri = new Uri.Builder()
-                .scheme("http")
-                .encodedAuthority("google.com")
-                .encodedPath("/p1")
-                .appendEncodedPath("p2")
-                .encodedQuery("query")
-                .appendQueryParameter("query2", null)
-                .encodedFragment("fragment")
-                .build();
-        assertEquals("http", uri.getScheme());
-        assertEquals("google.com", uri.getEncodedAuthority());
-        assertEquals("/p1/p2", uri.getEncodedPath());
-        assertEquals("query&query2=null", uri.getEncodedQuery());
-        assertEquals("fragment", uri.getEncodedFragment());
-
-        uri = new Uri.Builder()
-                .scheme("mailto")
-                .encodedOpaquePart("nobody")
-                .build();
-        assertEquals("mailto", uri.getScheme());
-        assertEquals("nobody", uri.getEncodedSchemeSpecificPart());
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java b/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java
deleted file mode 100644
index 5a70928..0000000
--- a/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import android.net.UrlQuerySanitizer;
-import android.net.UrlQuerySanitizer.IllegalCharacterValueSanitizer;
-import android.net.UrlQuerySanitizer.ParameterValuePair;
-import android.net.UrlQuerySanitizer.ValueSanitizer;
-import android.os.Build;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-import java.util.Set;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class UrlQuerySanitizerTest {
-    @Rule
-    public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule();
-
-    private static final int ALL_OK = IllegalCharacterValueSanitizer.ALL_OK;
-
-    // URL for test.
-    private static final String TEST_URL = "http://example.com/?name=Joe+User&age=20&height=175";
-
-    // Default sanitizer's change when "+".
-    private static final String EXPECTED_UNDERLINE_NAME = "Joe_User";
-
-    // IllegalCharacterValueSanitizer sanitizer's change when "+".
-    private static final String EXPECTED_SPACE_NAME = "Joe User";
-    private static final String EXPECTED_AGE = "20";
-    private static final String EXPECTED_HEIGHT = "175";
-    private static final String NAME = "name";
-    private static final String AGE = "age";
-    private static final String HEIGHT = "height";
-
-    @Test
-    public void testUrlQuerySanitizer() {
-        MockUrlQuerySanitizer uqs = new MockUrlQuerySanitizer();
-        assertFalse(uqs.getAllowUnregisteredParamaters());
-
-        final String query = "book=thinking in java&price=108";
-        final String book = "book";
-        final String bookName = "thinking in java";
-        final String price = "price";
-        final String bookPrice = "108";
-        final String notExistPar = "notExistParameter";
-        uqs.registerParameters(new String[]{book, price}, UrlQuerySanitizer.getSpaceLegal());
-        uqs.parseQuery(query);
-        assertTrue(uqs.hasParameter(book));
-        assertTrue(uqs.hasParameter(price));
-        assertFalse(uqs.hasParameter(notExistPar));
-        assertEquals(bookName, uqs.getValue(book));
-        assertEquals(bookPrice, uqs.getValue(price));
-        assertNull(uqs.getValue(notExistPar));
-        uqs.clear();
-        assertFalse(uqs.hasParameter(book));
-        assertFalse(uqs.hasParameter(price));
-
-        uqs.parseEntry(book, bookName);
-        assertTrue(uqs.hasParameter(book));
-        assertEquals(bookName, uqs.getValue(book));
-        uqs.parseEntry(price, bookPrice);
-        assertTrue(uqs.hasParameter(price));
-        assertEquals(bookPrice, uqs.getValue(price));
-        assertFalse(uqs.hasParameter(notExistPar));
-        assertNull(uqs.getValue(notExistPar));
-
-        uqs = new MockUrlQuerySanitizer(TEST_URL);
-        assertTrue(uqs.getAllowUnregisteredParamaters());
-
-        assertTrue(uqs.hasParameter(NAME));
-        assertTrue(uqs.hasParameter(AGE));
-        assertTrue(uqs.hasParameter(HEIGHT));
-        assertFalse(uqs.hasParameter(notExistPar));
-
-        assertEquals(EXPECTED_UNDERLINE_NAME, uqs.getValue(NAME));
-        assertEquals(EXPECTED_AGE, uqs.getValue(AGE));
-        assertEquals(EXPECTED_HEIGHT, uqs.getValue(HEIGHT));
-        assertNull(uqs.getValue(notExistPar));
-
-        final int ContainerLen = 3;
-        Set<String> urlSet = uqs.getParameterSet();
-        assertEquals(ContainerLen, urlSet.size());
-        assertTrue(urlSet.contains(NAME));
-        assertTrue(urlSet.contains(AGE));
-        assertTrue(urlSet.contains(HEIGHT));
-        assertFalse(urlSet.contains(notExistPar));
-
-        List<ParameterValuePair> urlList = uqs.getParameterList();
-        assertEquals(ContainerLen, urlList.size());
-        ParameterValuePair pvp = urlList.get(0);
-        assertEquals(NAME, pvp.mParameter);
-        assertEquals(EXPECTED_UNDERLINE_NAME, pvp.mValue);
-        pvp = urlList.get(1);
-        assertEquals(AGE, pvp.mParameter);
-        assertEquals(EXPECTED_AGE, pvp.mValue);
-        pvp = urlList.get(2);
-        assertEquals(HEIGHT, pvp.mParameter);
-        assertEquals(EXPECTED_HEIGHT, pvp.mValue);
-
-        assertFalse(uqs.getPreferFirstRepeatedParameter());
-        uqs.addSanitizedEntry(HEIGHT, EXPECTED_HEIGHT + 1);
-        assertEquals(ContainerLen, urlSet.size());
-        assertEquals(ContainerLen + 1, urlList.size());
-        assertEquals(EXPECTED_HEIGHT + 1, uqs.getValue(HEIGHT));
-
-        uqs.setPreferFirstRepeatedParameter(true);
-        assertTrue(uqs.getPreferFirstRepeatedParameter());
-        uqs.addSanitizedEntry(HEIGHT, EXPECTED_HEIGHT);
-        assertEquals(ContainerLen, urlSet.size());
-        assertEquals(ContainerLen + 2, urlList.size());
-        assertEquals(EXPECTED_HEIGHT + 1, uqs.getValue(HEIGHT));
-
-        uqs.registerParameter(NAME, null);
-        assertNull(uqs.getValueSanitizer(NAME));
-        assertNotNull(uqs.getEffectiveValueSanitizer(NAME));
-
-        uqs.setAllowUnregisteredParamaters(false);
-        assertFalse(uqs.getAllowUnregisteredParamaters());
-        uqs.registerParameter(NAME, null);
-        assertNull(uqs.getEffectiveValueSanitizer(NAME));
-
-        ValueSanitizer vs = new IllegalCharacterValueSanitizer(ALL_OK);
-        uqs.registerParameter(NAME, vs);
-        uqs.parseUrl(TEST_URL);
-        assertEquals(EXPECTED_SPACE_NAME, uqs.getValue(NAME));
-        assertNotSame(EXPECTED_AGE, uqs.getValue(AGE));
-
-        String[] register = {NAME, AGE};
-        uqs.registerParameters(register, vs);
-        uqs.parseUrl(TEST_URL);
-        assertEquals(EXPECTED_SPACE_NAME, uqs.getValue(NAME));
-        assertEquals(EXPECTED_AGE, uqs.getValue(AGE));
-        assertNotSame(EXPECTED_HEIGHT, uqs.getValue(HEIGHT));
-
-        uqs.setUnregisteredParameterValueSanitizer(vs);
-        assertEquals(vs, uqs.getUnregisteredParameterValueSanitizer());
-
-        vs = UrlQuerySanitizer.getAllIllegal();
-        assertEquals("Joe_User", vs.sanitize("Joe<User"));
-        vs = UrlQuerySanitizer.getAllButNulAndAngleBracketsLegal();
-        assertEquals("Joe   User", vs.sanitize("Joe<>\0User"));
-        vs = UrlQuerySanitizer.getAllButNulLegal();
-        assertEquals("Joe User", vs.sanitize("Joe\0User"));
-        vs = UrlQuerySanitizer.getAllButWhitespaceLegal();
-        assertEquals("Joe_User", vs.sanitize("Joe User"));
-        vs = UrlQuerySanitizer.getAmpAndSpaceLegal();
-        assertEquals("Joe User&", vs.sanitize("Joe User&"));
-        vs = UrlQuerySanitizer.getAmpLegal();
-        assertEquals("Joe_User&", vs.sanitize("Joe User&"));
-        vs = UrlQuerySanitizer.getSpaceLegal();
-        assertEquals("Joe User ", vs.sanitize("Joe User&"));
-        vs = UrlQuerySanitizer.getUrlAndSpaceLegal();
-        assertEquals("Joe User&Smith%B5'\'", vs.sanitize("Joe User&Smith%B5'\'"));
-        vs = UrlQuerySanitizer.getUrlLegal();
-        assertEquals("Joe_User&Smith%B5'\'", vs.sanitize("Joe User&Smith%B5'\'"));
-
-        String escape = "Joe";
-        assertEquals(escape, uqs.unescape(escape));
-        String expectedPlus = "Joe User";
-        String expectedPercentSignHex = "title=" + Character.toString((char)181);
-        String initialPlus = "Joe+User";
-        String initialPercentSign = "title=%B5";
-        assertEquals(expectedPlus, uqs.unescape(initialPlus));
-        assertEquals(expectedPercentSignHex, uqs.unescape(initialPercentSign));
-        String expectedPlusThenPercentSign = "Joe Random, User";
-        String plusThenPercentSign = "Joe+Random%2C%20User";
-        assertEquals(expectedPlusThenPercentSign, uqs.unescape(plusThenPercentSign));
-        String expectedPercentSignThenPlus = "Joe, Random User";
-        String percentSignThenPlus = "Joe%2C+Random+User";
-        assertEquals(expectedPercentSignThenPlus, uqs.unescape(percentSignThenPlus));
-
-        assertTrue(uqs.decodeHexDigit('0') >= 0);
-        assertTrue(uqs.decodeHexDigit('b') >= 0);
-        assertTrue(uqs.decodeHexDigit('F') >= 0);
-        assertTrue(uqs.decodeHexDigit('$') < 0);
-
-        assertTrue(uqs.isHexDigit('0'));
-        assertTrue(uqs.isHexDigit('b'));
-        assertTrue(uqs.isHexDigit('F'));
-        assertFalse(uqs.isHexDigit('$'));
-
-        uqs.clear();
-        assertEquals(0, urlSet.size());
-        assertEquals(0, urlList.size());
-
-        uqs.setPreferFirstRepeatedParameter(true);
-        assertTrue(uqs.getPreferFirstRepeatedParameter());
-        uqs.setPreferFirstRepeatedParameter(false);
-        assertFalse(uqs.getPreferFirstRepeatedParameter());
-
-        UrlQuerySanitizer uq = new UrlQuerySanitizer();
-        uq.setPreferFirstRepeatedParameter(true);
-        final String PARA_ANSWER = "answer";
-        uq.registerParameter(PARA_ANSWER, new MockValueSanitizer());
-        uq.parseUrl("http://www.google.com/question?answer=13&answer=42");
-        assertEquals("13", uq.getValue(PARA_ANSWER));
-
-        uq.setPreferFirstRepeatedParameter(false);
-        uq.parseQuery("http://www.google.com/question?answer=13&answer=42");
-        assertEquals("42", uq.getValue(PARA_ANSWER));
-
-    }
-
-    @Test @IgnoreUpTo(Build.VERSION_CODES.Q) // Only fixed in R
-    public void testScriptUrlOk_73822755() {
-        ValueSanitizer sanitizer = new UrlQuerySanitizer.IllegalCharacterValueSanitizer(
-                UrlQuerySanitizer.IllegalCharacterValueSanitizer.SCRIPT_URL_OK);
-        assertEquals("javascript:alert()", sanitizer.sanitize("javascript:alert()"));
-    }
-
-    @Test @IgnoreUpTo(Build.VERSION_CODES.Q) // Only fixed in R
-    public void testScriptUrlBlocked_73822755() {
-        ValueSanitizer sanitizer = UrlQuerySanitizer.getUrlAndSpaceLegal();
-        assertEquals("", sanitizer.sanitize("javascript:alert()"));
-    }
-
-    private static class MockValueSanitizer implements ValueSanitizer{
-
-        public String sanitize(String value) {
-            return value;
-        }
-    }
-
-    class MockUrlQuerySanitizer extends UrlQuerySanitizer {
-        public MockUrlQuerySanitizer() {
-            super();
-        }
-
-        public MockUrlQuerySanitizer(String url) {
-            super(url);
-        }
-
-        @Override
-        protected void addSanitizedEntry(String parameter, String value) {
-            super.addSanitizedEntry(parameter, value);
-        }
-
-        @Override
-        protected void clear() {
-            super.clear();
-        }
-
-        @Override
-        protected int decodeHexDigit(char c) {
-            return super.decodeHexDigit(c);
-        }
-
-        @Override
-        protected boolean isHexDigit(char c) {
-            return super.isHexDigit(c);
-        }
-
-        @Override
-        protected void parseEntry(String parameter, String value) {
-            super.parseEntry(parameter, value);
-        }
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java b/tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java
deleted file mode 100644
index f86af31..0000000
--- a/tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-import android.net.UrlQuerySanitizer;
-import android.net.UrlQuerySanitizer.IllegalCharacterValueSanitizer;
-import android.test.AndroidTestCase;
-
-public class UrlQuerySanitizer_IllegalCharacterValueSanitizerTest extends AndroidTestCase {
-    static final int SPACE_OK = IllegalCharacterValueSanitizer.SPACE_OK;
-    public void testSanitize() {
-        IllegalCharacterValueSanitizer sanitizer =  new IllegalCharacterValueSanitizer(SPACE_OK);
-        assertEquals("Joe User", sanitizer.sanitize("Joe<User"));
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/UrlQuerySanitizer_ParameterValuePairTest.java b/tests/cts/net/src/android/net/cts/UrlQuerySanitizer_ParameterValuePairTest.java
deleted file mode 100644
index 077cdaf..0000000
--- a/tests/cts/net/src/android/net/cts/UrlQuerySanitizer_ParameterValuePairTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts;
-
-import android.net.UrlQuerySanitizer;
-import android.net.UrlQuerySanitizer.ParameterValuePair;
-import android.test.AndroidTestCase;
-
-public class UrlQuerySanitizer_ParameterValuePairTest extends AndroidTestCase {
-    public void testConstructor() {
-        final String parameter = "name";
-        final String vaule = "Joe_user";
-
-        UrlQuerySanitizer uqs = new UrlQuerySanitizer();
-        ParameterValuePair parameterValuePair = uqs.new ParameterValuePair(parameter, vaule);
-        assertEquals(parameter, parameterValuePair.mParameter);
-        assertEquals(vaule, parameterValuePair.mValue);
-    }
-}
diff --git a/tests/cts/net/src/android/net/cts/VpnServiceTest.java b/tests/cts/net/src/android/net/cts/VpnServiceTest.java
deleted file mode 100644
index 15af23c..0000000
--- a/tests/cts/net/src/android/net/cts/VpnServiceTest.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net.cts;
-
-import android.content.Intent;
-import android.net.VpnService;
-import android.os.ParcelFileDescriptor;
-import android.platform.test.annotations.AppModeFull;
-import android.test.AndroidTestCase;
-
-import java.io.File;
-import java.net.DatagramSocket;
-import java.net.Socket;
-
-/**
- * VpnService API is built with security in mind. However, its security also
- * blocks us from writing tests for positive cases. For now we only test for
- * negative cases, and we will try to cover the rest in the future.
- */
-public class VpnServiceTest extends AndroidTestCase {
-
-    private static final String TAG = VpnServiceTest.class.getSimpleName();
-
-    private VpnService mVpnService = new VpnService();
-
-    @AppModeFull(reason = "PackageManager#queryIntentActivities cannot access in instant app mode")
-    public void testPrepare() throws Exception {
-        // Should never return null since we are not prepared.
-        Intent intent = VpnService.prepare(mContext);
-        assertNotNull(intent);
-
-        // Should be always resolved by only one activity.
-        int count = mContext.getPackageManager().queryIntentActivities(intent, 0).size();
-        assertEquals(1, count);
-    }
-
-    public void testEstablish() throws Exception {
-        ParcelFileDescriptor descriptor = null;
-        try {
-            // Should always return null since we are not prepared.
-            descriptor = mVpnService.new Builder().addAddress("8.8.8.8", 30).establish();
-            assertNull(descriptor);
-        } finally {
-            try {
-                descriptor.close();
-            } catch (Exception e) {
-                // ignore
-            }
-        }
-    }
-
-    @AppModeFull(reason = "Socket cannot bind in instant app mode")
-    public void testProtect_DatagramSocket() throws Exception {
-        DatagramSocket socket = new DatagramSocket();
-        try {
-            // Should always return false since we are not prepared.
-            assertFalse(mVpnService.protect(socket));
-        } finally {
-            try {
-                socket.close();
-            } catch (Exception e) {
-                // ignore
-            }
-        }
-    }
-
-    public void testProtect_Socket() throws Exception {
-        Socket socket = new Socket();
-        try {
-            // Should always return false since we are not prepared.
-            assertFalse(mVpnService.protect(socket));
-        } finally {
-            try {
-                socket.close();
-            } catch (Exception e) {
-                // ignore
-            }
-        }
-    }
-
-    @AppModeFull(reason = "Socket cannot bind in instant app mode")
-    public void testProtect_int() throws Exception {
-        DatagramSocket socket = new DatagramSocket();
-        ParcelFileDescriptor descriptor = ParcelFileDescriptor.fromDatagramSocket(socket);
-        try {
-            // Should always return false since we are not prepared.
-            assertFalse(mVpnService.protect(descriptor.getFd()));
-        } finally {
-            try {
-                descriptor.close();
-            } catch (Exception e) {
-                // ignore
-            }
-            try {
-                socket.close();
-            } catch (Exception e) {
-                // ignore
-            }
-        }
-    }
-
-    public void testTunDevice() throws Exception {
-        File file = new File("/dev/tun");
-        assertTrue(file.exists());
-        assertFalse(file.isFile());
-        assertFalse(file.isDirectory());
-        assertFalse(file.canExecute());
-        assertFalse(file.canRead());
-        assertFalse(file.canWrite());
-    }
-}
diff --git a/tests/cts/net/src/android/net/ipv6/cts/PingTest.java b/tests/cts/net/src/android/net/ipv6/cts/PingTest.java
deleted file mode 100644
index 146fd83..0000000
--- a/tests/cts/net/src/android/net/ipv6/cts/PingTest.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2013 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.ipv6.cts;
-
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.StructTimeval;
-import static android.system.OsConstants.*;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Inet6Address;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.Random;
-
-/**
- * Checks that the device has kernel support for the IPv6 ping socket. This allows ping6 to work
- * without root privileges. The necessary kernel code is in Linux 3.11 or above, or the
- * <code>common/android-3.x</code> kernel trees. If you are not running one of these kernels, the
- * functionality can be obtained by cherry-picking the following patches from David Miller's
- * <code>net-next</code> tree:
- * <ul>
- * <li>6d0bfe2 net: ipv6: Add IPv6 support to the ping socket.
- * <li>c26d6b4 ping: always initialize ->sin6_scope_id and ->sin6_flowinfo
- * <li>fbfe80c net: ipv6: fix wrong ping_v6_sendmsg return value
- * <li>a1bdc45 net: ipv6: add missing lock in ping_v6_sendmsg
- * <li>cf970c0 ping: prevent NULL pointer dereference on write to msg_name
- * </ul>
- * or the equivalent backports to the <code>common/android-3.x</code> trees.
- */
-public class PingTest extends AndroidTestCase {
-    /** Maximum size of the packets we're using to test. */
-    private static final int MAX_SIZE = 4096;
-
-    /** Size of the ICMPv6 header. */
-    private static final int ICMP_HEADER_SIZE = 8;
-
-    /** Number of packets to test. */
-    private static final int NUM_PACKETS = 10;
-
-    /** The beginning of an ICMPv6 echo request: type, code, and uninitialized checksum. */
-    private static final byte[] PING_HEADER = new byte[] {
-        (byte) ICMP6_ECHO_REQUEST, (byte) 0x00, (byte) 0x00, (byte) 0x00
-    };
-
-    /**
-     * Returns a byte array containing an ICMPv6 echo request with the specified payload length.
-     */
-    private byte[] pingPacket(int payloadLength) {
-        byte[] packet = new byte[payloadLength + ICMP_HEADER_SIZE];
-        new Random().nextBytes(packet);
-        System.arraycopy(PING_HEADER, 0, packet, 0, PING_HEADER.length);
-        return packet;
-    }
-
-    /**
-     * Checks that the first length bytes of two byte arrays are equal.
-     */
-    private void assertArrayBytesEqual(byte[] expected, byte[] actual, int length) {
-        for (int i = 0; i < length; i++) {
-            assertEquals("Arrays differ at index " + i + ":", expected[i], actual[i]);
-        }
-    }
-
-    /**
-     * Creates an IPv6 ping socket and sets a receive timeout of 100ms.
-     */
-    private FileDescriptor createPingSocket() throws ErrnoException {
-        FileDescriptor s = Os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6);
-        Os.setsockoptTimeval(s, SOL_SOCKET, SO_RCVTIMEO, StructTimeval.fromMillis(100));
-        return s;
-    }
-
-    /**
-     * Sends a ping packet to a random port on the specified address on the specified socket.
-     */
-    private void sendPing(FileDescriptor s,
-            InetAddress address, byte[] packet) throws ErrnoException, IOException {
-        // Pick a random port. Choose a range that gives a reasonable chance of picking a low port.
-        int port = (int) (Math.random() * 2048);
-
-        // Send the packet.
-        int ret = Os.sendto(s, ByteBuffer.wrap(packet), 0, address, port);
-        assertEquals(packet.length, ret);
-    }
-
-    /**
-     * Checks that a socket has received a response appropriate to the specified packet.
-     */
-    private void checkResponse(FileDescriptor s, InetAddress dest,
-            byte[] sent, boolean useRecvfrom) throws ErrnoException, IOException {
-        ByteBuffer responseBuffer = ByteBuffer.allocate(MAX_SIZE);
-        int bytesRead;
-
-        // Receive the response.
-        if (useRecvfrom) {
-            InetSocketAddress from = new InetSocketAddress();
-            bytesRead = Os.recvfrom(s, responseBuffer, 0, from);
-
-            // Check the source address and scope ID.
-            assertTrue(from.getAddress() instanceof Inet6Address);
-            Inet6Address fromAddress = (Inet6Address) from.getAddress();
-            assertEquals(0, fromAddress.getScopeId());
-            assertNull(fromAddress.getScopedInterface());
-            assertEquals(dest.getHostAddress(), fromAddress.getHostAddress());
-        } else {
-            bytesRead = Os.read(s, responseBuffer);
-        }
-
-        // Check the packet length.
-        assertEquals(sent.length, bytesRead);
-
-        // Check the response is an echo reply.
-        byte[] response = new byte[bytesRead];
-        responseBuffer.flip();
-        responseBuffer.get(response, 0, bytesRead);
-        assertEquals((byte) ICMP6_ECHO_REPLY, response[0]);
-
-        // Find out what ICMP ID was used in the packet that was sent.
-        int id = ((InetSocketAddress) Os.getsockname(s)).getPort();
-        sent[4] = (byte) (id / 256);
-        sent[5] = (byte) (id % 256);
-
-        // Ensure the response is the same as the packet, except for the type (which is 0x81)
-        // and the ID and checksum,  which are set by the kernel.
-        response[0] = (byte) 0x80;                 // Type.
-        response[2] = response[3] = (byte) 0x00;   // Checksum.
-        assertArrayBytesEqual(response, sent, bytesRead);
-    }
-
-    /**
-     * Sends NUM_PACKETS random ping packets to ::1 and checks the replies.
-     */
-    public void testLoopbackPing() throws ErrnoException, IOException {
-        // Generate a random ping packet and send it to localhost.
-        InetAddress ipv6Loopback = InetAddress.getByName(null);
-        assertEquals("::1", ipv6Loopback.getHostAddress());
-
-        for (int i = 0; i < NUM_PACKETS; i++) {
-            byte[] packet = pingPacket((int) (Math.random() * (MAX_SIZE - ICMP_HEADER_SIZE)));
-            FileDescriptor s = createPingSocket();
-            // Use both recvfrom and read().
-            sendPing(s, ipv6Loopback, packet);
-            checkResponse(s, ipv6Loopback, packet, true);
-            sendPing(s, ipv6Loopback, packet);
-            checkResponse(s, ipv6Loopback, packet, false);
-            // Check closing the socket doesn't raise an exception.
-            Os.close(s);
-        }
-    }
-}
diff --git a/tests/cts/net/src/android/net/rtp/cts/AudioCodecTest.java b/tests/cts/net/src/android/net/rtp/cts/AudioCodecTest.java
deleted file mode 100644
index 412498c..0000000
--- a/tests/cts/net/src/android/net/rtp/cts/AudioCodecTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net.rtp.cts;
-
-import android.net.rtp.AudioCodec;
-import android.test.AndroidTestCase;
-
-public class AudioCodecTest extends AndroidTestCase {
-
-    private void assertEquals(AudioCodec codec, int type, String rtpmap, String fmtp) {
-        if (type >= 0) {
-            assertEquals(codec.type, type);
-        } else {
-            assertTrue(codec.type >= 96 && codec.type <= 127);
-        }
-        assertEquals(codec.rtpmap.compareToIgnoreCase(rtpmap), 0);
-        assertEquals(codec.fmtp, fmtp);
-    }
-
-    public void testConstants() throws Exception {
-        assertEquals(AudioCodec.PCMU, 0, "PCMU/8000", null);
-        assertEquals(AudioCodec.PCMA, 8, "PCMA/8000", null);
-        assertEquals(AudioCodec.GSM, 3, "GSM/8000", null);
-        assertEquals(AudioCodec.GSM_EFR, -1, "GSM-EFR/8000", null);
-        assertEquals(AudioCodec.AMR, -1, "AMR/8000", null);
-
-        assertFalse(AudioCodec.AMR.type == AudioCodec.GSM_EFR.type);
-    }
-
-    public void testGetCodec() throws Exception {
-        // Bad types.
-        assertNull(AudioCodec.getCodec(128, "PCMU/8000", null));
-        assertNull(AudioCodec.getCodec(-1, "PCMU/8000", null));
-        assertNull(AudioCodec.getCodec(96, null, null));
-
-        // Fixed types.
-        assertEquals(AudioCodec.getCodec(0, null, null), 0, "PCMU/8000", null);
-        assertEquals(AudioCodec.getCodec(8, null, null), 8, "PCMA/8000", null);
-        assertEquals(AudioCodec.getCodec(3, null, null), 3, "GSM/8000", null);
-
-        // Dynamic types.
-        assertEquals(AudioCodec.getCodec(96, "pcmu/8000", null), 96, "PCMU/8000", null);
-        assertEquals(AudioCodec.getCodec(97, "pcma/8000", null), 97, "PCMA/8000", null);
-        assertEquals(AudioCodec.getCodec(98, "gsm/8000", null), 98, "GSM/8000", null);
-        assertEquals(AudioCodec.getCodec(99, "gsm-efr/8000", null), 99, "GSM-EFR/8000", null);
-        assertEquals(AudioCodec.getCodec(100, "amr/8000", null), 100, "AMR/8000", null);
-    }
-
-    public void testGetCodecs() throws Exception {
-        AudioCodec[] codecs = AudioCodec.getCodecs();
-        assertTrue(codecs.length >= 5);
-
-        // The types of the codecs should be different.
-        boolean[] types = new boolean[128];
-        for (AudioCodec codec : codecs) {
-            assertFalse(types[codec.type]);
-            types[codec.type] = true;
-        }
-    }
-}
diff --git a/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java b/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java
deleted file mode 100644
index fc78e96..0000000
--- a/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net.rtp.cts;
-
-import android.content.Context;
-import android.media.AudioManager;
-import android.net.rtp.AudioCodec;
-import android.net.rtp.AudioGroup;
-import android.net.rtp.AudioStream;
-import android.net.rtp.RtpStream;
-import android.os.Build;
-import android.platform.test.annotations.AppModeFull;
-import android.test.AndroidTestCase;
-
-import androidx.core.os.BuildCompat;
-
-import java.net.DatagramPacket;
-import java.net.DatagramSocket;
-import java.net.InetAddress;
-
-@AppModeFull(reason = "RtpStream cannot create in instant app mode")
-public class AudioGroupTest extends AndroidTestCase {
-
-    private static final String TAG = AudioGroupTest.class.getSimpleName();
-
-    private AudioManager mAudioManager;
-
-    private AudioStream mStreamA;
-    private DatagramSocket mSocketA;
-    private AudioStream mStreamB;
-    private DatagramSocket mSocketB;
-    private AudioGroup mGroup;
-
-    @Override
-    public void setUp() throws Exception {
-        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
-        mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
-
-        InetAddress local = InetAddress.getByName("::1");
-
-        mStreamA = new AudioStream(local);
-        mStreamA.setMode(RtpStream.MODE_NORMAL);
-        mStreamA.setCodec(AudioCodec.PCMU);
-        mSocketA = new DatagramSocket();
-        mSocketA.connect(mStreamA.getLocalAddress(), mStreamA.getLocalPort());
-        mStreamA.associate(mSocketA.getLocalAddress(), mSocketA.getLocalPort());
-
-        mStreamB = new AudioStream(local);
-        mStreamB.setMode(RtpStream.MODE_NORMAL);
-        mStreamB.setCodec(AudioCodec.PCMU);
-        mSocketB = new DatagramSocket();
-        mSocketB.connect(mStreamB.getLocalAddress(), mStreamB.getLocalPort());
-        mStreamB.associate(mSocketB.getLocalAddress(), mSocketB.getLocalPort());
-
-        // BuildCompat.isAtLeastR is documented to return false on release SDKs (including R)
-        mGroup = Build.VERSION.SDK_INT > Build.VERSION_CODES.Q || BuildCompat.isAtLeastR()
-                ? new AudioGroup(mContext)
-                : new AudioGroup(); // Constructor with context argument was introduced in R
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        mGroup.clear();
-        mStreamA.release();
-        mSocketA.close();
-        mStreamB.release();
-        mSocketB.close();
-        mAudioManager.setMode(AudioManager.MODE_NORMAL);
-    }
-
-    private void assertPacket(DatagramSocket socket, int length) throws Exception {
-        DatagramPacket packet = new DatagramPacket(new byte[length + 1], length + 1);
-        socket.setSoTimeout(3000);
-        socket.receive(packet);
-        assertEquals(packet.getLength(), length);
-    }
-
-    private void drain(DatagramSocket socket) throws Exception {
-        DatagramPacket packet = new DatagramPacket(new byte[1], 1);
-        socket.setSoTimeout(1);
-        try {
-            // Drain the socket by retrieving all the packets queued on it.
-            // A SocketTimeoutException will be thrown when it becomes empty.
-            while (true) {
-                socket.receive(packet);
-            }
-        } catch (Exception e) {
-            // ignore.
-        }
-    }
-
-    public void testTraffic() throws Exception {
-        mStreamA.join(mGroup);
-        assertPacket(mSocketA, 12 + 160);
-
-        mStreamB.join(mGroup);
-        assertPacket(mSocketB, 12 + 160);
-
-        mStreamA.join(null);
-        drain(mSocketA);
-
-        drain(mSocketB);
-        assertPacket(mSocketB, 12 + 160);
-
-        mStreamA.join(mGroup);
-        assertPacket(mSocketA, 12 + 160);
-    }
-
-    public void testSetMode() throws Exception {
-        mGroup.setMode(AudioGroup.MODE_NORMAL);
-        assertEquals(mGroup.getMode(), AudioGroup.MODE_NORMAL);
-
-        mGroup.setMode(AudioGroup.MODE_MUTED);
-        assertEquals(mGroup.getMode(), AudioGroup.MODE_MUTED);
-
-        mStreamA.join(mGroup);
-        mStreamB.join(mGroup);
-
-        mGroup.setMode(AudioGroup.MODE_NORMAL);
-        assertEquals(mGroup.getMode(), AudioGroup.MODE_NORMAL);
-
-        mGroup.setMode(AudioGroup.MODE_MUTED);
-        assertEquals(mGroup.getMode(), AudioGroup.MODE_MUTED);
-    }
-
-    public void testAdd() throws Exception {
-        mStreamA.join(mGroup);
-        assertEquals(mGroup.getStreams().length, 1);
-
-        mStreamB.join(mGroup);
-        assertEquals(mGroup.getStreams().length, 2);
-
-        mStreamA.join(mGroup);
-        assertEquals(mGroup.getStreams().length, 2);
-    }
-
-    public void testRemove() throws Exception {
-        mStreamA.join(mGroup);
-        assertEquals(mGroup.getStreams().length, 1);
-
-        mStreamA.join(null);
-        assertEquals(mGroup.getStreams().length, 0);
-
-        mStreamA.join(mGroup);
-        assertEquals(mGroup.getStreams().length, 1);
-    }
-
-    public void testClear() throws Exception {
-        mStreamA.join(mGroup);
-        mStreamB.join(mGroup);
-        mGroup.clear();
-
-        assertEquals(mGroup.getStreams().length, 0);
-        assertFalse(mStreamA.isBusy());
-        assertFalse(mStreamB.isBusy());
-    }
-
-    public void testDoubleClear() throws Exception {
-        mStreamA.join(mGroup);
-        mStreamB.join(mGroup);
-        mGroup.clear();
-        mGroup.clear();
-    }
-}
diff --git a/tests/cts/net/src/android/net/rtp/cts/AudioStreamTest.java b/tests/cts/net/src/android/net/rtp/cts/AudioStreamTest.java
deleted file mode 100644
index f2db6ee..0000000
--- a/tests/cts/net/src/android/net/rtp/cts/AudioStreamTest.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net.rtp.cts;
-
-import android.net.rtp.AudioCodec;
-import android.net.rtp.AudioStream;
-import android.platform.test.annotations.AppModeFull;
-import android.test.AndroidTestCase;
-
-import java.net.InetAddress;
-
-@AppModeFull(reason = "RtpStream cannot create in instant app mode")
-public class AudioStreamTest extends AndroidTestCase {
-
-    private void testRtpStream(InetAddress address) throws Exception {
-        AudioStream stream = new AudioStream(address);
-        assertEquals(stream.getLocalAddress(), address);
-        assertEquals(stream.getLocalPort() % 2, 0);
-
-        assertNull(stream.getRemoteAddress());
-        assertEquals(stream.getRemotePort(), -1);
-        stream.associate(address, 1000);
-        assertEquals(stream.getRemoteAddress(), address);
-        assertEquals(stream.getRemotePort(), 1000);
-
-        assertFalse(stream.isBusy());
-        stream.release();
-    }
-
-    public void testV4Stream() throws Exception {
-        testRtpStream(InetAddress.getByName("127.0.0.1"));
-    }
-
-    public void testV6Stream() throws Exception {
-        testRtpStream(InetAddress.getByName("::1"));
-    }
-
-    public void testSetDtmfType() throws Exception {
-        AudioStream stream = new AudioStream(InetAddress.getByName("::1"));
-
-        assertEquals(stream.getDtmfType(), -1);
-        try {
-            stream.setDtmfType(0);
-            fail("Expecting IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // ignore
-        }
-        stream.setDtmfType(96);
-        assertEquals(stream.getDtmfType(), 96);
-
-        stream.setCodec(AudioCodec.getCodec(97, "PCMU/8000", null));
-        try {
-            stream.setDtmfType(97);
-            fail("Expecting IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // ignore
-        }
-        stream.release();
-    }
-
-    public void testSetCodec() throws Exception {
-        AudioStream stream = new AudioStream(InetAddress.getByName("::1"));
-
-        assertNull(stream.getCodec());
-        stream.setCodec(AudioCodec.getCodec(97, "PCMU/8000", null));
-        assertNotNull(stream.getCodec());
-
-        stream.setDtmfType(96);
-        try {
-            stream.setCodec(AudioCodec.getCodec(96, "PCMU/8000", null));
-            fail("Expecting IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // ignore
-        }
-        stream.release();
-    }
-
-    public void testDoubleRelease() throws Exception {
-        AudioStream stream = new AudioStream(InetAddress.getByName("::1"));
-        stream.release();
-        stream.release();
-    }
-}
diff --git a/tests/cts/net/util/Android.bp b/tests/cts/net/util/Android.bp
deleted file mode 100644
index c36d976..0000000
--- a/tests/cts/net/util/Android.bp
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-// Common utilities for cts net tests.
-java_library {
-    name: "cts-net-utils",
-    srcs: ["java/**/*.java", "java/**/*.kt"],
-    static_libs: [
-        "compatibility-device-util-axt",
-        "junit",
-        "net-tests-utils",
-    ],
-}
\ No newline at end of file
diff --git a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
deleted file mode 100644
index 34c6541..0000000
--- a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
+++ /dev/null
@@ -1,693 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts.util;
-
-import static android.Manifest.permission.NETWORK_SETTINGS;
-import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.net.NetworkCapabilities.TRANSPORT_TEST;
-import static android.net.wifi.WifiManager.SCAN_RESULTS_AVAILABLE_ACTION;
-
-import static com.android.testutils.TestPermissionUtil.runAsShell;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.annotation.NonNull;
-import android.app.AppOpsManager;
-import android.content.BroadcastReceiver;
-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.NetworkInfo;
-import android.net.NetworkInfo.State;
-import android.net.NetworkRequest;
-import android.net.TestNetworkManager;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.os.Binder;
-import android.os.Build;
-import android.os.IBinder;
-import android.os.SystemProperties;
-import android.provider.Settings;
-import android.system.Os;
-import android.system.OsConstants;
-import android.util.Log;
-
-import com.android.compatibility.common.util.SystemUtil;
-
-import junit.framework.AssertionFailedError;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-public final class CtsNetUtils {
-    private static final String TAG = CtsNetUtils.class.getSimpleName();
-    private static final int DURATION = 10000;
-    private static final int SOCKET_TIMEOUT_MS = 2000;
-    private static final int PRIVATE_DNS_PROBE_MS = 1_000;
-
-    private static final int PRIVATE_DNS_SETTING_TIMEOUT_MS = 10_000;
-    private static final int CONNECTIVITY_CHANGE_TIMEOUT_SECS = 30;
-    public static final int HTTP_PORT = 80;
-    public static final String TEST_HOST = "connectivitycheck.gstatic.com";
-    public static final String HTTP_REQUEST =
-            "GET /generate_204 HTTP/1.0\r\n" +
-                    "Host: " + TEST_HOST + "\r\n" +
-                    "Connection: keep-alive\r\n\r\n";
-    // Action sent to ConnectivityActionReceiver when a network callback is sent via PendingIntent.
-    public static final String NETWORK_CALLBACK_ACTION =
-            "ConnectivityManagerTest.NetworkCallbackAction";
-
-    private final IBinder mBinder = new Binder();
-    private final Context mContext;
-    private final ConnectivityManager mCm;
-    private final ContentResolver mCR;
-    private final WifiManager mWifiManager;
-    private TestNetworkCallback mCellNetworkCallback;
-    private String mOldPrivateDnsMode;
-    private String mOldPrivateDnsSpecifier;
-
-    public CtsNetUtils(Context context) {
-        mContext = context;
-        mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
-        mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
-        mCR = context.getContentResolver();
-    }
-
-    /** Checks if FEATURE_IPSEC_TUNNELS is enabled on the device */
-    public boolean hasIpsecTunnelsFeature() {
-        return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
-                || SystemProperties.getInt("ro.product.first_api_level", 0)
-                        >= Build.VERSION_CODES.Q;
-    }
-
-    /**
-     * Sets the given appop using shell commands
-     *
-     * <p>Expects caller to hold the shell permission identity.
-     */
-    public void setAppopPrivileged(int appop, boolean allow) {
-        final String opName = AppOpsManager.opToName(appop);
-        for (final String pkg : new String[] {"com.android.shell", mContext.getPackageName()}) {
-            final String cmd =
-                    String.format(
-                            "appops set %s %s %s",
-                            pkg, // Package name
-                            opName, // Appop
-                            (allow ? "allow" : "deny")); // Action
-            SystemUtil.runShellCommand(cmd);
-        }
-    }
-
-    /** Sets up a test network using the provided interface name */
-    public TestNetworkCallback setupAndGetTestNetwork(String ifname) throws Exception {
-        // Build a network request
-        final NetworkRequest nr =
-                new NetworkRequest.Builder()
-                        .clearCapabilities()
-                        .addTransportType(TRANSPORT_TEST)
-                        .setNetworkSpecifier(ifname)
-                        .build();
-
-        final TestNetworkCallback cb = new TestNetworkCallback();
-        mCm.requestNetwork(nr, cb);
-
-        // Setup the test network after network request is filed to prevent Network from being
-        // reaped due to no requests matching it.
-        mContext.getSystemService(TestNetworkManager.class).setupTestNetwork(ifname, mBinder);
-
-        return cb;
-    }
-
-    // Toggle WiFi twice, leaving it in the state it started in
-    public void toggleWifi() {
-        if (mWifiManager.isWifiEnabled()) {
-            Network wifiNetwork = getWifiNetwork();
-            disconnectFromWifi(wifiNetwork);
-            connectToWifi();
-        } else {
-            connectToWifi();
-            Network wifiNetwork = getWifiNetwork();
-            disconnectFromWifi(wifiNetwork);
-        }
-    }
-
-    /**
-     * Enable WiFi and wait for it to become connected to a network.
-     *
-     * This method expects to receive a legacy broadcast on connect, which may not be sent if the
-     * network does not become default or if it is not the first network.
-     */
-    public Network connectToWifi() {
-        return connectToWifi(true /* expectLegacyBroadcast */);
-    }
-
-    /**
-     * Enable WiFi and wait for it to become connected to a network.
-     *
-     * A network is considered connected when a {@link NetworkRequest} with TRANSPORT_WIFI
-     * receives a {@link NetworkCallback#onAvailable(Network)} callback.
-     */
-    public Network ensureWifiConnected() {
-        return connectToWifi(false /* expectLegacyBroadcast */);
-    }
-
-    /**
-     * Enable WiFi and wait for it to become connected to a network.
-     *
-     * @param expectLegacyBroadcast Whether to check for a legacy CONNECTIVITY_ACTION connected
-     *                              broadcast. The broadcast is typically not sent if the network
-     *                              does not become the default network, and is not the first
-     *                              network to appear.
-     * @return The network that was newly connected.
-     */
-    private Network connectToWifi(boolean expectLegacyBroadcast) {
-        final TestNetworkCallback callback = new TestNetworkCallback();
-        mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback);
-        Network wifiNetwork = null;
-
-        ConnectivityActionReceiver receiver = new ConnectivityActionReceiver(
-                mCm, ConnectivityManager.TYPE_WIFI, NetworkInfo.State.CONNECTED);
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
-        mContext.registerReceiver(receiver, filter);
-
-        boolean connected = false;
-        final String err = "Wifi must be configured to connect to an access point for this test.";
-        try {
-            clearWifiBlacklist();
-            SystemUtil.runShellCommand("svc wifi enable");
-            final WifiConfiguration config = maybeAddVirtualWifiConfiguration();
-            if (config == null) {
-                // TODO: this may not clear the BSSID blacklist, as opposed to
-                // mWifiManager.connect(config)
-                assertTrue("Error reconnecting wifi", runAsShell(NETWORK_SETTINGS,
-                        mWifiManager::reconnect));
-            } else {
-                // When running CTS, devices are expected to have wifi networks pre-configured.
-                // This condition is only hit on virtual devices.
-                final Integer error = runAsShell(NETWORK_SETTINGS, () -> {
-                    final ConnectWifiListener listener = new ConnectWifiListener();
-                    mWifiManager.connect(config, listener);
-                    return listener.connectFuture.get(
-                            CONNECTIVITY_CHANGE_TIMEOUT_SECS, TimeUnit.SECONDS);
-                });
-                assertNull("Error connecting to wifi: " + error, error);
-            }
-            // Ensure we get an onAvailable callback and possibly a CONNECTIVITY_ACTION.
-            wifiNetwork = callback.waitForAvailable();
-            assertNotNull(err, wifiNetwork);
-            connected = !expectLegacyBroadcast || receiver.waitForState();
-        } catch (InterruptedException ex) {
-            fail("connectToWifi was interrupted");
-        } finally {
-            mCm.unregisterNetworkCallback(callback);
-            mContext.unregisterReceiver(receiver);
-        }
-
-        assertTrue(err, connected);
-        return wifiNetwork;
-    }
-
-    private static class ConnectWifiListener implements WifiManager.ActionListener {
-        /**
-         * Future completed when the connect process ends. Provides the error code or null if none.
-         */
-        final CompletableFuture<Integer> connectFuture = new CompletableFuture<>();
-        @Override
-        public void onSuccess() {
-            connectFuture.complete(null);
-        }
-
-        @Override
-        public void onFailure(int reason) {
-            connectFuture.complete(reason);
-        }
-    }
-
-    private WifiConfiguration maybeAddVirtualWifiConfiguration() {
-        final List<WifiConfiguration> configs = runAsShell(NETWORK_SETTINGS,
-                mWifiManager::getConfiguredNetworks);
-        // If no network is configured, add a config for virtual access points if applicable
-        if (configs.size() == 0) {
-            final List<ScanResult> scanResults = getWifiScanResults();
-            final WifiConfiguration virtualConfig = maybeConfigureVirtualNetwork(scanResults);
-            assertNotNull("The device has no configured wifi network", virtualConfig);
-
-            return virtualConfig;
-        }
-        // No need to add a configuration: there is already one
-        return null;
-    }
-
-    private List<ScanResult> getWifiScanResults() {
-        final CompletableFuture<List<ScanResult>> scanResultsFuture = new CompletableFuture<>();
-        runAsShell(NETWORK_SETTINGS, () -> {
-            final BroadcastReceiver receiver = new BroadcastReceiver() {
-                @Override
-                public void onReceive(Context context, Intent intent) {
-                    scanResultsFuture.complete(mWifiManager.getScanResults());
-                }
-            };
-            mContext.registerReceiver(receiver, new IntentFilter(SCAN_RESULTS_AVAILABLE_ACTION));
-            mWifiManager.startScan();
-        });
-
-        try {
-            return scanResultsFuture.get(CONNECTIVITY_CHANGE_TIMEOUT_SECS, TimeUnit.SECONDS);
-        } catch (ExecutionException | InterruptedException | TimeoutException e) {
-            throw new AssertionFailedError("Wifi scan results not received within timeout");
-        }
-    }
-
-    /**
-     * If a virtual wifi network is detected, add a configuration for that network.
-     * TODO(b/158150376): have the test infrastructure add virtual wifi networks when appropriate.
-     */
-    private WifiConfiguration maybeConfigureVirtualNetwork(List<ScanResult> scanResults) {
-        // Virtual wifi networks used on the emulator and cloud testing infrastructure
-        final List<String> virtualSsids = Arrays.asList("VirtWifi", "AndroidWifi");
-        Log.d(TAG, "Wifi scan results: " + scanResults);
-        final ScanResult virtualScanResult = scanResults.stream().filter(
-                s -> virtualSsids.contains(s.SSID)).findFirst().orElse(null);
-
-        // Only add the virtual configuration if the virtual AP is detected in scans
-        if (virtualScanResult == null) return null;
-
-        final WifiConfiguration virtualConfig = new WifiConfiguration();
-        // ASCII SSIDs need to be surrounded by double quotes
-        virtualConfig.SSID = "\"" + virtualScanResult.SSID + "\"";
-        virtualConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
-
-        runAsShell(NETWORK_SETTINGS, () -> {
-            final int networkId = mWifiManager.addNetwork(virtualConfig);
-            assertTrue(networkId >= 0);
-            assertTrue(mWifiManager.enableNetwork(networkId, false /* attemptConnect */));
-        });
-        return virtualConfig;
-    }
-
-    /**
-     * Re-enable wifi networks that were blacklisted, typically because no internet connection was
-     * detected the last time they were connected. This is necessary to make sure wifi can reconnect
-     * to them.
-     */
-    private void clearWifiBlacklist() {
-        runAsShell(NETWORK_SETTINGS, () -> {
-            for (WifiConfiguration cfg : mWifiManager.getConfiguredNetworks()) {
-                assertTrue(mWifiManager.enableNetwork(cfg.networkId, false /* attemptConnect */));
-            }
-        });
-    }
-
-    /**
-     * Disable WiFi and wait for it to become disconnected from the network.
-     *
-     * This method expects to receive a legacy broadcast on disconnect, which may not be sent if the
-     * network was not default, or was not the first network.
-     *
-     * @param wifiNetworkToCheck If non-null, a network that should be disconnected. This network
-     *                           is expected to be able to establish a TCP connection to a remote
-     *                           server before disconnecting, and to have that connection closed in
-     *                           the process.
-     */
-    public void disconnectFromWifi(Network wifiNetworkToCheck) {
-        disconnectFromWifi(wifiNetworkToCheck, true /* expectLegacyBroadcast */);
-    }
-
-    /**
-     * Disable WiFi and wait for it to become disconnected from the network.
-     *
-     * @param wifiNetworkToCheck If non-null, a network that should be disconnected. This network
-     *                           is expected to be able to establish a TCP connection to a remote
-     *                           server before disconnecting, and to have that connection closed in
-     *                           the process.
-     */
-    public void ensureWifiDisconnected(Network wifiNetworkToCheck) {
-        disconnectFromWifi(wifiNetworkToCheck, false /* expectLegacyBroadcast */);
-    }
-
-    /**
-     * Disable WiFi and wait for it to become disconnected from the network.
-     *
-     * @param wifiNetworkToCheck If non-null, a network that should be disconnected. This network
-     *                           is expected to be able to establish a TCP connection to a remote
-     *                           server before disconnecting, and to have that connection closed in
-     *                           the process.
-     * @param expectLegacyBroadcast Whether to check for a legacy CONNECTIVITY_ACTION disconnected
-     *                              broadcast. The broadcast is typically not sent if the network
-     *                              was not the default network and not the first network to appear.
-     *                              The check will always be skipped if the device was not connected
-     *                              to wifi in the first place.
-     */
-    private void disconnectFromWifi(Network wifiNetworkToCheck, boolean expectLegacyBroadcast) {
-        final TestNetworkCallback callback = new TestNetworkCallback();
-        mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback);
-
-        ConnectivityActionReceiver receiver = new ConnectivityActionReceiver(
-                mCm, ConnectivityManager.TYPE_WIFI, NetworkInfo.State.DISCONNECTED);
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
-        mContext.registerReceiver(receiver, filter);
-
-        final WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
-        final boolean wasWifiConnected = wifiInfo != null && wifiInfo.getNetworkId() != -1;
-        // Assert that we can establish a TCP connection on wifi.
-        Socket wifiBoundSocket = null;
-        if (wifiNetworkToCheck != null) {
-            assertTrue("Cannot check network " + wifiNetworkToCheck + ": wifi is not connected",
-                    wasWifiConnected);
-            final NetworkCapabilities nc = mCm.getNetworkCapabilities(wifiNetworkToCheck);
-            assertNotNull("Network " + wifiNetworkToCheck + " is not connected", nc);
-            try {
-                wifiBoundSocket = getBoundSocket(wifiNetworkToCheck, TEST_HOST, HTTP_PORT);
-                testHttpRequest(wifiBoundSocket);
-            } catch (IOException e) {
-                fail("HTTP request before wifi disconnected failed with: " + e);
-            }
-        }
-
-        try {
-            SystemUtil.runShellCommand("svc wifi disable");
-            if (wasWifiConnected) {
-                // Ensure we get both an onLost callback and a CONNECTIVITY_ACTION.
-                assertNotNull("Did not receive onLost callback after disabling wifi",
-                        callback.waitForLost());
-            }
-            if (wasWifiConnected && expectLegacyBroadcast) {
-                assertTrue("Wifi failed to reach DISCONNECTED state.", receiver.waitForState());
-            }
-        } catch (InterruptedException ex) {
-            fail("disconnectFromWifi was interrupted");
-        } finally {
-            mCm.unregisterNetworkCallback(callback);
-            mContext.unregisterReceiver(receiver);
-        }
-
-        // Check that the socket is closed when wifi disconnects.
-        if (wifiBoundSocket != null) {
-            try {
-                testHttpRequest(wifiBoundSocket);
-                fail("HTTP request should not succeed after wifi disconnects");
-            } catch (IOException expected) {
-                assertEquals(Os.strerror(OsConstants.ECONNABORTED), expected.getMessage());
-            }
-        }
-    }
-
-    public Network getWifiNetwork() {
-        TestNetworkCallback callback = new TestNetworkCallback();
-        mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback);
-        Network network = null;
-        try {
-            network = callback.waitForAvailable();
-        } catch (InterruptedException e) {
-            fail("NetworkCallback wait was interrupted.");
-        } finally {
-            mCm.unregisterNetworkCallback(callback);
-        }
-        assertNotNull("Cannot find Network for wifi. Is wifi connected?", network);
-        return network;
-    }
-
-    public 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. " +
-                "Please ensure the device has working mobile data.", cellNetwork);
-        return cellNetwork;
-    }
-
-    public void disconnectFromCell() {
-        if (!cellConnectAttempted()) {
-            throw new IllegalStateException("Cell connection not attempted");
-        }
-        mCm.unregisterNetworkCallback(mCellNetworkCallback);
-        mCellNetworkCallback = null;
-    }
-
-    public boolean cellConnectAttempted() {
-        return mCellNetworkCallback != null;
-    }
-
-    private NetworkRequest makeWifiNetworkRequest() {
-        return new NetworkRequest.Builder()
-                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
-                .build();
-    }
-
-    private void testHttpRequest(Socket s) throws IOException {
-        OutputStream out = s.getOutputStream();
-        InputStream in = s.getInputStream();
-
-        final byte[] requestBytes = HTTP_REQUEST.getBytes("UTF-8");
-        byte[] responseBytes = new byte[4096];
-        out.write(requestBytes);
-        in.read(responseBytes);
-        assertTrue(new String(responseBytes, "UTF-8").startsWith("HTTP/1.0 204 No Content\r\n"));
-    }
-
-    private Socket getBoundSocket(Network network, String host, int port) throws IOException {
-        InetSocketAddress addr = new InetSocketAddress(host, port);
-        Socket s = network.getSocketFactory().createSocket();
-        try {
-            s.setSoTimeout(SOCKET_TIMEOUT_MS);
-            s.connect(addr, SOCKET_TIMEOUT_MS);
-        } catch (IOException e) {
-            s.close();
-            throw e;
-        }
-        return s;
-    }
-
-    public void storePrivateDnsSetting() {
-        // Store private DNS setting
-        mOldPrivateDnsMode = Settings.Global.getString(mCR, Settings.Global.PRIVATE_DNS_MODE);
-        mOldPrivateDnsSpecifier = Settings.Global.getString(mCR,
-                Settings.Global.PRIVATE_DNS_SPECIFIER);
-        // It's possible that there is no private DNS default value in Settings.
-        // Give it a proper default mode which is opportunistic mode.
-        if (mOldPrivateDnsMode == null) {
-            mOldPrivateDnsSpecifier = "";
-            mOldPrivateDnsMode = PRIVATE_DNS_MODE_OPPORTUNISTIC;
-            Settings.Global.putString(mCR,
-                    Settings.Global.PRIVATE_DNS_SPECIFIER, mOldPrivateDnsSpecifier);
-            Settings.Global.putString(mCR, Settings.Global.PRIVATE_DNS_MODE, mOldPrivateDnsMode);
-        }
-    }
-
-    public void restorePrivateDnsSetting() throws InterruptedException {
-        if (mOldPrivateDnsMode == null || mOldPrivateDnsSpecifier == null) {
-            return;
-        }
-        // restore private DNS setting
-        if ("hostname".equals(mOldPrivateDnsMode)) {
-            setPrivateDnsStrictMode(mOldPrivateDnsSpecifier);
-            awaitPrivateDnsSetting("restorePrivateDnsSetting timeout",
-                    mCm.getActiveNetwork(),
-                    mOldPrivateDnsSpecifier, true);
-        } else {
-            Settings.Global.putString(mCR, Settings.Global.PRIVATE_DNS_MODE, mOldPrivateDnsMode);
-        }
-    }
-
-    public void setPrivateDnsStrictMode(String server) {
-        // To reduce flake rate, set PRIVATE_DNS_SPECIFIER before PRIVATE_DNS_MODE. This ensures
-        // that if the previous private DNS mode was not "hostname", the system only sees one
-        // EVENT_PRIVATE_DNS_SETTINGS_CHANGED event instead of two.
-        Settings.Global.putString(mCR, Settings.Global.PRIVATE_DNS_SPECIFIER, server);
-        final String mode = Settings.Global.getString(mCR, Settings.Global.PRIVATE_DNS_MODE);
-        // If current private DNS mode is "hostname", we only need to set PRIVATE_DNS_SPECIFIER.
-        if (!"hostname".equals(mode)) {
-            Settings.Global.putString(mCR, Settings.Global.PRIVATE_DNS_MODE, "hostname");
-        }
-    }
-
-    public void awaitPrivateDnsSetting(@NonNull String msg, @NonNull Network network,
-            @NonNull String server, boolean requiresValidatedServers) throws InterruptedException {
-        CountDownLatch latch = new CountDownLatch(1);
-        NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build();
-        NetworkCallback callback = new NetworkCallback() {
-            @Override
-            public void onLinkPropertiesChanged(Network n, LinkProperties lp) {
-                if (requiresValidatedServers && lp.getValidatedPrivateDnsServers().isEmpty()) {
-                    return;
-                }
-                if (network.equals(n) && server.equals(lp.getPrivateDnsServerName())) {
-                    latch.countDown();
-                }
-            }
-        };
-        mCm.registerNetworkCallback(request, callback);
-        assertTrue(msg, latch.await(PRIVATE_DNS_SETTING_TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        mCm.unregisterNetworkCallback(callback);
-        // Wait some time for NetworkMonitor's private DNS probe to complete. If we do not do
-        // this, then the test could complete before the NetworkMonitor private DNS probe
-        // completes. This would result in tearDown disabling private DNS, and the NetworkMonitor
-        // private DNS probe getting stuck because there are no longer any private DNS servers to
-        // query. This then results in the next test not being able to change the private DNS
-        // setting within the timeout, because the NetworkMonitor thread is blocked in the
-        // private DNS probe. There is no way to know when the probe has completed: because the
-        // network is likely already validated, there is no callback that we can listen to, so
-        // just sleep.
-        if (requiresValidatedServers) {
-            Thread.sleep(PRIVATE_DNS_PROBE_MS);
-        }
-    }
-
-    /**
-     * Receiver that captures the last connectivity change's network type and state. Recognizes
-     * both {@code CONNECTIVITY_ACTION} and {@code NETWORK_CALLBACK_ACTION} intents.
-     */
-    public static class ConnectivityActionReceiver extends BroadcastReceiver {
-
-        private final CountDownLatch mReceiveLatch = new CountDownLatch(1);
-
-        private final int mNetworkType;
-        private final NetworkInfo.State mNetState;
-        private final ConnectivityManager mCm;
-
-        public ConnectivityActionReceiver(ConnectivityManager cm, int networkType,
-                NetworkInfo.State netState) {
-            this.mCm = cm;
-            mNetworkType = networkType;
-            mNetState = netState;
-        }
-
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            NetworkInfo networkInfo = null;
-
-            // When receiving ConnectivityManager.CONNECTIVITY_ACTION, the NetworkInfo parcelable
-            // is stored in EXTRA_NETWORK_INFO. With a NETWORK_CALLBACK_ACTION, the Network is
-            // sent in EXTRA_NETWORK and we need to ask the ConnectivityManager for the NetworkInfo.
-            if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
-                networkInfo = intent.getExtras()
-                        .getParcelable(ConnectivityManager.EXTRA_NETWORK_INFO);
-                assertNotNull("ConnectivityActionReceiver expected EXTRA_NETWORK_INFO",
-                        networkInfo);
-            } else if (NETWORK_CALLBACK_ACTION.equals(action)) {
-                Network network = intent.getExtras()
-                        .getParcelable(ConnectivityManager.EXTRA_NETWORK);
-                assertNotNull("ConnectivityActionReceiver expected EXTRA_NETWORK", network);
-                networkInfo = this.mCm.getNetworkInfo(network);
-                if (networkInfo == null) {
-                    // When disconnecting, it seems like we get an intent sent with an invalid
-                    // Network; that is, by the time we call ConnectivityManager.getNetworkInfo(),
-                    // it is invalid. Ignore these.
-                    Log.i(TAG, "ConnectivityActionReceiver NETWORK_CALLBACK_ACTION ignoring "
-                            + "invalid network");
-                    return;
-                }
-            } else {
-                fail("ConnectivityActionReceiver received unxpected intent action: " + action);
-            }
-
-            assertNotNull("ConnectivityActionReceiver didn't find NetworkInfo", networkInfo);
-            int networkType = networkInfo.getType();
-            State networkState = networkInfo.getState();
-            Log.i(TAG, "Network type: " + networkType + " state: " + networkState);
-            if (networkType == mNetworkType && networkInfo.getState() == mNetState) {
-                mReceiveLatch.countDown();
-            }
-        }
-
-        public boolean waitForState() throws InterruptedException {
-            return mReceiveLatch.await(CONNECTIVITY_CHANGE_TIMEOUT_SECS, TimeUnit.SECONDS);
-        }
-    }
-
-    /**
-     * Callback used in testRegisterNetworkCallback that allows caller to block on
-     * {@code onAvailable}.
-     */
-    public static class TestNetworkCallback extends ConnectivityManager.NetworkCallback {
-        private final CountDownLatch mAvailableLatch = new CountDownLatch(1);
-        private final CountDownLatch mLostLatch = new CountDownLatch(1);
-        private final CountDownLatch mUnavailableLatch = new CountDownLatch(1);
-
-        public Network currentNetwork;
-        public Network lastLostNetwork;
-
-        public Network waitForAvailable() throws InterruptedException {
-            return mAvailableLatch.await(CONNECTIVITY_CHANGE_TIMEOUT_SECS, TimeUnit.SECONDS)
-                    ? currentNetwork : null;
-        }
-
-        public Network waitForLost() throws InterruptedException {
-            return mLostLatch.await(CONNECTIVITY_CHANGE_TIMEOUT_SECS, TimeUnit.SECONDS)
-                    ? lastLostNetwork : null;
-        }
-
-        public boolean waitForUnavailable() throws InterruptedException {
-            return mUnavailableLatch.await(2, TimeUnit.SECONDS);
-        }
-
-
-        @Override
-        public void onAvailable(Network network) {
-            currentNetwork = network;
-            mAvailableLatch.countDown();
-        }
-
-        @Override
-        public void onLost(Network network) {
-            lastLostNetwork = network;
-            if (network.equals(currentNetwork)) {
-                currentNetwork = null;
-            }
-            mLostLatch.countDown();
-        }
-
-        @Override
-        public void onUnavailable() {
-            mUnavailableLatch.countDown();
-        }
-    }
-}
diff --git a/tests/cts/net/util/java/android/net/cts/util/CtsTetheringUtils.java b/tests/cts/net/util/java/android/net/cts/util/CtsTetheringUtils.java
deleted file mode 100644
index b18c1e7..0000000
--- a/tests/cts/net/util/java/android/net/cts/util/CtsTetheringUtils.java
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.cts.util;
-
-import static android.net.TetheringManager.TETHERING_WIFI;
-import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
-import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED;
-import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
-import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
-
-import android.content.Context;
-import android.net.Network;
-import android.net.TetheredClient;
-import android.net.TetheringManager;
-import android.net.TetheringManager.TetheringEventCallback;
-import android.net.TetheringManager.TetheringInterfaceRegexps;
-import android.net.TetheringManager.TetheringRequest;
-import android.net.wifi.WifiClient;
-import android.net.wifi.WifiManager;
-import android.net.wifi.WifiManager.SoftApCallback;
-import android.os.ConditionVariable;
-
-import androidx.annotation.NonNull;
-
-import com.android.net.module.util.ArrayTrackRecord;
-
-import java.util.Collection;
-import java.util.List;
-
-public final class CtsTetheringUtils {
-    private TetheringManager mTm;
-    private WifiManager mWm;
-    private Context mContext;
-
-    private static final int DEFAULT_TIMEOUT_MS = 60_000;
-
-    public CtsTetheringUtils(Context ctx) {
-        mContext = ctx;
-        mTm = mContext.getSystemService(TetheringManager.class);
-        mWm = mContext.getSystemService(WifiManager.class);
-    }
-
-    public static class StartTetheringCallback implements TetheringManager.StartTetheringCallback {
-        private static int TIMEOUT_MS = 30_000;
-        public static class CallbackValue {
-            public final int error;
-
-            private CallbackValue(final int e) {
-                error = e;
-            }
-
-            public static class OnTetheringStarted extends CallbackValue {
-                OnTetheringStarted() { super(TETHER_ERROR_NO_ERROR); }
-            }
-
-            public static class OnTetheringFailed extends CallbackValue {
-                OnTetheringFailed(final int error) { super(error); }
-            }
-
-            @Override
-            public String toString() {
-                return String.format("%s(%d)", getClass().getSimpleName(), error);
-            }
-        }
-
-        private final ArrayTrackRecord<CallbackValue>.ReadHead mHistory =
-                new ArrayTrackRecord<CallbackValue>().newReadHead();
-
-        @Override
-        public void onTetheringStarted() {
-            mHistory.add(new CallbackValue.OnTetheringStarted());
-        }
-
-        @Override
-        public void onTetheringFailed(final int error) {
-            mHistory.add(new CallbackValue.OnTetheringFailed(error));
-        }
-
-        public void verifyTetheringStarted() {
-            final CallbackValue cv = mHistory.poll(TIMEOUT_MS, c -> true);
-            assertNotNull("No onTetheringStarted after " + TIMEOUT_MS + " ms", cv);
-            assertTrue("Fail start tethering:" + cv,
-                    cv instanceof CallbackValue.OnTetheringStarted);
-        }
-
-        public void expectTetheringFailed(final int expected) throws InterruptedException {
-            final CallbackValue cv = mHistory.poll(TIMEOUT_MS, c -> true);
-            assertNotNull("No onTetheringFailed after " + TIMEOUT_MS + " ms", cv);
-            assertTrue("Expect fail with error code " + expected + ", but received: " + cv,
-                    (cv instanceof CallbackValue.OnTetheringFailed) && (cv.error == expected));
-        }
-    }
-
-    public static boolean isIfaceMatch(final List<String> ifaceRegexs, final List<String> ifaces) {
-        return isIfaceMatch(ifaceRegexs.toArray(new String[0]), ifaces);
-    }
-
-    public static boolean isIfaceMatch(final String[] ifaceRegexs, final List<String> ifaces) {
-        if (ifaceRegexs == null) fail("ifaceRegexs should not be null");
-
-        if (ifaces == null) return false;
-
-        for (String s : ifaces) {
-            for (String regex : ifaceRegexs) {
-                if (s.matches(regex)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    // Must poll the callback before looking at the member.
-    public static class TestTetheringEventCallback implements TetheringEventCallback {
-        private static final int TIMEOUT_MS = 30_000;
-
-        public enum CallbackType {
-            ON_SUPPORTED,
-            ON_UPSTREAM,
-            ON_TETHERABLE_REGEX,
-            ON_TETHERABLE_IFACES,
-            ON_TETHERED_IFACES,
-            ON_ERROR,
-            ON_CLIENTS,
-            ON_OFFLOAD_STATUS,
-        };
-
-        public static class CallbackValue {
-            public final CallbackType callbackType;
-            public final Object callbackParam;
-            public final int callbackParam2;
-
-            private CallbackValue(final CallbackType type, final Object param, final int param2) {
-                this.callbackType = type;
-                this.callbackParam = param;
-                this.callbackParam2 = param2;
-            }
-        }
-
-        private final ArrayTrackRecord<CallbackValue> mHistory =
-                new ArrayTrackRecord<CallbackValue>();
-
-        private final ArrayTrackRecord<CallbackValue>.ReadHead mCurrent =
-                mHistory.newReadHead();
-
-        private TetheringInterfaceRegexps mTetherableRegex;
-        private List<String> mTetherableIfaces;
-        private List<String> mTetheredIfaces;
-
-        @Override
-        public void onTetheringSupported(boolean supported) {
-            mHistory.add(new CallbackValue(CallbackType.ON_SUPPORTED, null, (supported ? 1 : 0)));
-        }
-
-        @Override
-        public void onUpstreamChanged(Network network) {
-            mHistory.add(new CallbackValue(CallbackType.ON_UPSTREAM, network, 0));
-        }
-
-        @Override
-        public void onTetherableInterfaceRegexpsChanged(TetheringInterfaceRegexps reg) {
-            mTetherableRegex = reg;
-            mHistory.add(new CallbackValue(CallbackType.ON_TETHERABLE_REGEX, reg, 0));
-        }
-
-        @Override
-        public void onTetherableInterfacesChanged(List<String> interfaces) {
-            mTetherableIfaces = interfaces;
-            mHistory.add(new CallbackValue(CallbackType.ON_TETHERABLE_IFACES, interfaces, 0));
-        }
-
-        @Override
-        public void onTetheredInterfacesChanged(List<String> interfaces) {
-            mTetheredIfaces = interfaces;
-            mHistory.add(new CallbackValue(CallbackType.ON_TETHERED_IFACES, interfaces, 0));
-        }
-
-        @Override
-        public void onError(String ifName, int error) {
-            mHistory.add(new CallbackValue(CallbackType.ON_ERROR, ifName, error));
-        }
-
-        @Override
-        public void onClientsChanged(Collection<TetheredClient> clients) {
-            mHistory.add(new CallbackValue(CallbackType.ON_CLIENTS, clients, 0));
-        }
-
-        @Override
-        public void onOffloadStatusChanged(int status) {
-            mHistory.add(new CallbackValue(CallbackType.ON_OFFLOAD_STATUS, status, 0));
-        }
-
-        public void expectTetherableInterfacesChanged(@NonNull List<String> regexs) {
-            assertNotNull("No expected tetherable ifaces callback", mCurrent.poll(TIMEOUT_MS,
-                (cv) -> {
-                    if (cv.callbackType != CallbackType.ON_TETHERABLE_IFACES) return false;
-                    final List<String> interfaces = (List<String>) cv.callbackParam;
-                    return isIfaceMatch(regexs, interfaces);
-                }));
-        }
-
-        public void expectTetheredInterfacesChanged(@NonNull List<String> regexs) {
-            assertNotNull("No expected tethered ifaces callback", mCurrent.poll(TIMEOUT_MS,
-                (cv) -> {
-                    if (cv.callbackType != CallbackType.ON_TETHERED_IFACES) return false;
-
-                    final List<String> interfaces = (List<String>) cv.callbackParam;
-
-                    // Null regexs means no active tethering.
-                    if (regexs == null) return interfaces.isEmpty();
-
-                    return isIfaceMatch(regexs, interfaces);
-                }));
-        }
-
-        public void expectCallbackStarted() {
-            int receivedBitMap = 0;
-            // The each bit represent a type from CallbackType.ON_*.
-            // Expect all of callbacks except for ON_ERROR.
-            final int expectedBitMap = 0xff ^ (1 << CallbackType.ON_ERROR.ordinal());
-            // Receive ON_ERROR on started callback is not matter. It just means tethering is
-            // failed last time, should able to continue the test this time.
-            while ((receivedBitMap & expectedBitMap) != expectedBitMap) {
-                final CallbackValue cv = mCurrent.poll(TIMEOUT_MS, c -> true);
-                if (cv == null) {
-                    fail("No expected callbacks, " + "expected bitmap: "
-                            + expectedBitMap + ", actual: " + receivedBitMap);
-                }
-
-                receivedBitMap |= (1 << cv.callbackType.ordinal());
-            }
-        }
-
-        public void expectOneOfOffloadStatusChanged(int... offloadStatuses) {
-            assertNotNull("No offload status changed", mCurrent.poll(TIMEOUT_MS, (cv) -> {
-                if (cv.callbackType != CallbackType.ON_OFFLOAD_STATUS) return false;
-
-                final int status = (int) cv.callbackParam;
-                for (int offloadStatus : offloadStatuses) {
-                    if (offloadStatus == status) return true;
-                }
-
-                return false;
-            }));
-        }
-
-        public void expectErrorOrTethered(final String iface) {
-            assertNotNull("No expected callback", mCurrent.poll(TIMEOUT_MS, (cv) -> {
-                if (cv.callbackType == CallbackType.ON_ERROR
-                        && iface.equals((String) cv.callbackParam)) {
-                    return true;
-                }
-                if (cv.callbackType == CallbackType.ON_TETHERED_IFACES
-                        && ((List<String>) cv.callbackParam).contains(iface)) {
-                    return true;
-                }
-
-                return false;
-            }));
-        }
-
-        public Network getCurrentValidUpstream() {
-            final CallbackValue result = mCurrent.poll(TIMEOUT_MS, (cv) -> {
-                return (cv.callbackType == CallbackType.ON_UPSTREAM)
-                        && cv.callbackParam != null;
-            });
-
-            assertNotNull("No valid upstream", result);
-            return (Network) result.callbackParam;
-        }
-
-        public void assumeTetheringSupported() {
-            final ArrayTrackRecord<CallbackValue>.ReadHead history =
-                    mHistory.newReadHead();
-            assertNotNull("No onSupported callback", history.poll(TIMEOUT_MS, (cv) -> {
-                if (cv.callbackType != CallbackType.ON_SUPPORTED) return false;
-
-                assumeTrue(cv.callbackParam2 == 1 /* supported */);
-                return true;
-            }));
-        }
-
-        public TetheringInterfaceRegexps getTetheringInterfaceRegexps() {
-            return mTetherableRegex;
-        }
-
-        public List<String> getTetherableInterfaces() {
-            return mTetherableIfaces;
-        }
-
-        public List<String> getTetheredInterfaces() {
-            return mTetheredIfaces;
-        }
-    }
-
-    public TestTetheringEventCallback registerTetheringEventCallback() {
-        final TestTetheringEventCallback tetherEventCallback =
-                new TestTetheringEventCallback();
-
-        mTm.registerTetheringEventCallback(c -> c.run() /* executor */, tetherEventCallback);
-        tetherEventCallback.expectCallbackStarted();
-
-        return tetherEventCallback;
-    }
-
-    public void unregisterTetheringEventCallback(final TestTetheringEventCallback callback) {
-        mTm.unregisterTetheringEventCallback(callback);
-    }
-
-    private static List<String> getWifiTetherableInterfaceRegexps(
-            final TestTetheringEventCallback callback) {
-        return callback.getTetheringInterfaceRegexps().getTetherableWifiRegexs();
-    }
-
-    public static boolean isWifiTetheringSupported(final TestTetheringEventCallback callback) {
-        return !getWifiTetherableInterfaceRegexps(callback).isEmpty();
-    }
-
-    public void startWifiTethering(final TestTetheringEventCallback callback)
-            throws InterruptedException {
-        final List<String> wifiRegexs = getWifiTetherableInterfaceRegexps(callback);
-        assertFalse(isIfaceMatch(wifiRegexs, callback.getTetheredInterfaces()));
-
-        final StartTetheringCallback startTetheringCallback = new StartTetheringCallback();
-        final TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI)
-                .setShouldShowEntitlementUi(false).build();
-        mTm.startTethering(request, c -> c.run() /* executor */, startTetheringCallback);
-        startTetheringCallback.verifyTetheringStarted();
-
-        callback.expectTetheredInterfacesChanged(wifiRegexs);
-
-        callback.expectOneOfOffloadStatusChanged(
-                TETHER_HARDWARE_OFFLOAD_STARTED,
-                TETHER_HARDWARE_OFFLOAD_FAILED);
-    }
-
-    private static class StopSoftApCallback implements SoftApCallback {
-        private final ConditionVariable mWaiting = new ConditionVariable();
-        @Override
-        public void onStateChanged(int state, int failureReason) {
-            if (state == WifiManager.WIFI_AP_STATE_DISABLED) mWaiting.open();
-        }
-
-        @Override
-        public void onConnectedClientsChanged(List<WifiClient> clients) { }
-
-        public void waitForSoftApStopped() {
-            if (!mWaiting.block(DEFAULT_TIMEOUT_MS)) {
-                fail("stopSoftAp Timeout");
-            }
-        }
-    }
-
-    // Wait for softAp to be disabled. This is necessary on devices where stopping softAp
-    // deletes the interface. On these devices, tethering immediately stops when the softAp
-    // interface is removed, but softAp is not yet fully disabled. Wait for softAp to be
-    // fully disabled, because otherwise the next test might fail because it attempts to
-    // start softAp before it's fully stopped.
-    public void expectSoftApDisabled() {
-        final StopSoftApCallback callback = new StopSoftApCallback();
-        try {
-            mWm.registerSoftApCallback(c -> c.run(), callback);
-            // registerSoftApCallback will immediately call the callback with the current state, so
-            // this callback will fire even if softAp is already disabled.
-            callback.waitForSoftApStopped();
-        } finally {
-            mWm.unregisterSoftApCallback(callback);
-        }
-    }
-
-    public void stopWifiTethering(final TestTetheringEventCallback callback) {
-        mTm.stopTethering(TETHERING_WIFI);
-        expectSoftApDisabled();
-        callback.expectTetheredInterfacesChanged(null);
-        callback.expectOneOfOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
-    }
-}
diff --git a/tests/cts/tethering/Android.bp b/tests/cts/tethering/Android.bp
deleted file mode 100644
index 85bb0e0..0000000
--- a/tests/cts/tethering/Android.bp
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-android_test {
-    name: "CtsTetheringTest",
-    defaults: ["cts_defaults"],
-
-    libs: [
-        "android.test.base.stubs",
-    ],
-
-    srcs: [
-        "src/**/*.java",
-    ],
-
-    static_libs: [
-        "TetheringCommonTests",
-        "TetheringIntegrationTestsLib",
-        "compatibility-device-util-axt",
-        "cts-net-utils",
-        "net-tests-utils",
-        "ctstestrunner-axt",
-        "junit",
-        "junit-params",
-    ],
-
-    jni_libs: [
-        // For mockito extended
-        "libdexmakerjvmtiagent",
-        "libstaticjvmtiagent",
-    ],
-
-    // Change to system current when TetheringManager move to bootclass path.
-    platform_apis: true,
-
-    // Tag this module as a cts test artifact
-    test_suites: [
-        "cts",
-        "general-tests",
-        "mts",
-    ],
-
-    // Include both the 32 and 64 bit versions
-    compile_multilib: "both",
-}
diff --git a/tests/cts/tethering/AndroidManifest.xml b/tests/cts/tethering/AndroidManifest.xml
deleted file mode 100644
index 665002e..0000000
--- a/tests/cts/tethering/AndroidManifest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.tethering.cts">
-
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-
-    <application android:debuggable="true">
-        <uses-library android:name="android.test.runner" />
-    </application>
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="android.tethering.cts"
-                     android:label="CTS tests of android.tethering">
-        <meta-data android:name="listener"
-            android:value="com.android.cts.runner.CtsTestRunListener" />
-    </instrumentation>
-
-</manifest>
diff --git a/tests/cts/tethering/AndroidTest.xml b/tests/cts/tethering/AndroidTest.xml
deleted file mode 100644
index e752e3a..0000000
--- a/tests/cts/tethering/AndroidTest.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="Config for CTS Tethering test cases">
-    <option name="test-suite-tag" value="cts" />
-    <option name="config-descriptor:metadata" key="component" value="networking" />
-    <option name="config-descriptor:metadata" key="token" value="SIM_CARD" />
-    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
-    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
-    <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
-    <option name="not-shardable" value="true" />
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsTetheringTest.apk" />
-    </target_preparer>
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.tethering.cts" />
-    </test>
-
-    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
-        <option name="mainline-module-package-name" value="com.google.android.tethering" />
-    </object>
-</configuration>
diff --git a/tests/cts/tethering/OWNERS b/tests/cts/tethering/OWNERS
deleted file mode 100644
index cd6abeb..0000000
--- a/tests/cts/tethering/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Bug component: 31808
-lorenzo@google.com
-satk@google.com
-
diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
deleted file mode 100644
index 87787b9..0000000
--- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.tethering.test;
-
-import static android.content.pm.PackageManager.FEATURE_TELEPHONY;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
-import static android.net.TetheringManager.TETHERING_USB;
-import static android.net.TetheringManager.TETHERING_WIFI;
-import static android.net.TetheringManager.TETHERING_WIFI_P2P;
-import static android.net.TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN;
-import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION;
-import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
-import static android.net.cts.util.CtsTetheringUtils.isIfaceMatch;
-import static android.net.cts.util.CtsTetheringUtils.isWifiTetheringSupported;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeFalse;
-import static org.junit.Assume.assumeTrue;
-
-import android.app.UiAutomation;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.net.ConnectivityManager;
-import android.net.LinkAddress;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.TetheringManager;
-import android.net.TetheringManager.OnTetheringEntitlementResultListener;
-import android.net.TetheringManager.TetheringInterfaceRegexps;
-import android.net.TetheringManager.TetheringRequest;
-import android.net.cts.util.CtsNetUtils;
-import android.net.cts.util.CtsNetUtils.TestNetworkCallback;
-import android.net.cts.util.CtsTetheringUtils;
-import android.net.cts.util.CtsTetheringUtils.StartTetheringCallback;
-import android.net.cts.util.CtsTetheringUtils.TestTetheringEventCallback;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
-import android.os.PersistableBundle;
-import android.os.ResultReceiver;
-import android.telephony.CarrierConfigManager;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Consumer;
-
-@RunWith(AndroidJUnit4.class)
-public class TetheringManagerTest {
-
-    private Context mContext;
-
-    private ConnectivityManager mCm;
-    private TetheringManager mTM;
-    private WifiManager mWm;
-    private PackageManager mPm;
-
-    private TetherChangeReceiver mTetherChangeReceiver;
-    private CtsNetUtils mCtsNetUtils;
-    private CtsTetheringUtils mCtsTetheringUtils;
-
-    private static final int DEFAULT_TIMEOUT_MS = 60_000;
-
-    private void adoptShellPermissionIdentity() {
-        final UiAutomation uiAutomation =
-                InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        uiAutomation.adoptShellPermissionIdentity();
-    }
-
-    private void dropShellPermissionIdentity() {
-        final UiAutomation uiAutomation =
-                InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        uiAutomation.dropShellPermissionIdentity();
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        adoptShellPermissionIdentity();
-        mContext = InstrumentationRegistry.getContext();
-        mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
-        mTM = (TetheringManager) mContext.getSystemService(Context.TETHERING_SERVICE);
-        mWm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
-        mPm = mContext.getPackageManager();
-        mCtsNetUtils = new CtsNetUtils(mContext);
-        mCtsTetheringUtils = new CtsTetheringUtils(mContext);
-        mTetherChangeReceiver = new TetherChangeReceiver();
-        final IntentFilter filter = new IntentFilter(
-                TetheringManager.ACTION_TETHER_STATE_CHANGED);
-        final Intent intent = mContext.registerReceiver(mTetherChangeReceiver, filter);
-        if (intent != null) mTetherChangeReceiver.onReceive(null, intent);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mTM.stopAllTethering();
-        mContext.unregisterReceiver(mTetherChangeReceiver);
-        dropShellPermissionIdentity();
-    }
-
-    private class TetherChangeReceiver extends BroadcastReceiver {
-        private class TetherState {
-            final ArrayList<String> mAvailable;
-            final ArrayList<String> mActive;
-            final ArrayList<String> mErrored;
-
-            TetherState(Intent intent) {
-                mAvailable = intent.getStringArrayListExtra(
-                        TetheringManager.EXTRA_AVAILABLE_TETHER);
-                mActive = intent.getStringArrayListExtra(
-                        TetheringManager.EXTRA_ACTIVE_TETHER);
-                mErrored = intent.getStringArrayListExtra(
-                        TetheringManager.EXTRA_ERRORED_TETHER);
-            }
-        }
-
-        @Override
-        public void onReceive(Context content, Intent intent) {
-            String action = intent.getAction();
-            if (action.equals(TetheringManager.ACTION_TETHER_STATE_CHANGED)) {
-                mResult.add(new TetherState(intent));
-            }
-        }
-
-        public final LinkedBlockingQueue<TetherState> mResult = new LinkedBlockingQueue<>();
-
-        // Expects that tethering reaches the desired state.
-        // - If active is true, expects that tethering is enabled on at least one interface
-        //   matching ifaceRegexs.
-        // - If active is false, expects that tethering is disabled on all the interfaces matching
-        //   ifaceRegexs.
-        // Fails if any interface matching ifaceRegexs becomes errored.
-        public void expectTethering(final boolean active, final String[] ifaceRegexs) {
-            while (true) {
-                final TetherState state = pollAndAssertNoError(DEFAULT_TIMEOUT_MS, ifaceRegexs);
-                assertNotNull("Did not receive expected state change, active: " + active, state);
-
-                if (isIfaceActive(ifaceRegexs, state) == active) return;
-            }
-        }
-
-        private TetherState pollAndAssertNoError(final int timeout, final String[] ifaceRegexs) {
-            final TetherState state = pollTetherState(timeout);
-            assertNoErroredIfaces(state, ifaceRegexs);
-            return state;
-        }
-
-        private TetherState pollTetherState(final int timeout) {
-            try {
-                return mResult.poll(timeout, TimeUnit.MILLISECONDS);
-            } catch (InterruptedException e) {
-                fail("No result after " + timeout + " ms");
-                return null;
-            }
-        }
-
-        private boolean isIfaceActive(final String[] ifaceRegexs, final TetherState state) {
-            return isIfaceMatch(ifaceRegexs, state.mActive);
-        }
-
-        private void assertNoErroredIfaces(final TetherState state, final String[] ifaceRegexs) {
-            if (state == null || state.mErrored == null) return;
-
-            if (isIfaceMatch(ifaceRegexs, state.mErrored)) {
-                fail("Found failed tethering interfaces: " + Arrays.toString(state.mErrored.toArray()));
-            }
-        }
-    }
-
-    @Test
-    public void testStartTetheringWithStateChangeBroadcast() throws Exception {
-        if (!mTM.isTetheringSupported()) return;
-
-        final String[] wifiRegexs = mTM.getTetherableWifiRegexs();
-        if (wifiRegexs.length == 0) return;
-
-        final String[] tetheredIfaces = mTM.getTetheredIfaces();
-        assertTrue(tetheredIfaces.length == 0);
-
-        final StartTetheringCallback startTetheringCallback = new StartTetheringCallback();
-        final TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI)
-                .setShouldShowEntitlementUi(false).build();
-        mTM.startTethering(request, c -> c.run() /* executor */, startTetheringCallback);
-        startTetheringCallback.verifyTetheringStarted();
-
-        mTetherChangeReceiver.expectTethering(true /* active */, wifiRegexs);
-
-        mTM.stopTethering(TETHERING_WIFI);
-        mCtsTetheringUtils.expectSoftApDisabled();
-        mTetherChangeReceiver.expectTethering(false /* active */, wifiRegexs);
-    }
-
-    @Test
-    public void testTetheringRequest() {
-        final TetheringRequest tr = new TetheringRequest.Builder(TETHERING_WIFI).build();
-        assertEquals(TETHERING_WIFI, tr.getTetheringType());
-        assertNull(tr.getLocalIpv4Address());
-        assertNull(tr.getClientStaticIpv4Address());
-        assertFalse(tr.isExemptFromEntitlementCheck());
-        assertTrue(tr.getShouldShowEntitlementUi());
-
-        final LinkAddress localAddr = new LinkAddress("192.168.24.5/24");
-        final LinkAddress clientAddr = new LinkAddress("192.168.24.100/24");
-        final TetheringRequest tr2 = new TetheringRequest.Builder(TETHERING_USB)
-                .setStaticIpv4Addresses(localAddr, clientAddr)
-                .setExemptFromEntitlementCheck(true)
-                .setShouldShowEntitlementUi(false).build();
-
-        assertEquals(localAddr, tr2.getLocalIpv4Address());
-        assertEquals(clientAddr, tr2.getClientStaticIpv4Address());
-        assertEquals(TETHERING_USB, tr2.getTetheringType());
-        assertTrue(tr2.isExemptFromEntitlementCheck());
-        assertFalse(tr2.getShouldShowEntitlementUi());
-    }
-
-    @Test
-    public void testRegisterTetheringEventCallback() throws Exception {
-        final TestTetheringEventCallback tetherEventCallback =
-                mCtsTetheringUtils.registerTetheringEventCallback();
-        tetherEventCallback.assumeTetheringSupported();
-
-        if (!isWifiTetheringSupported(tetherEventCallback)) {
-            mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
-            return;
-        }
-
-        mCtsTetheringUtils.startWifiTethering(tetherEventCallback);
-
-        final List<String> tetheredIfaces = tetherEventCallback.getTetheredInterfaces();
-        assertEquals(1, tetheredIfaces.size());
-        final String wifiTetheringIface = tetheredIfaces.get(0);
-
-        mCtsTetheringUtils.stopWifiTethering(tetherEventCallback);
-
-        try {
-            final int ret = mTM.tether(wifiTetheringIface);
-
-            // There is no guarantee that the wifi interface will be available after disabling
-            // the hotspot, so don't fail the test if the call to tether() fails.
-            assumeTrue(ret == TETHER_ERROR_NO_ERROR);
-
-            // If calling #tether successful, there is a callback to tell the result of tethering
-            // setup.
-            tetherEventCallback.expectErrorOrTethered(wifiTetheringIface);
-        } finally {
-            mTM.untether(wifiTetheringIface);
-            mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
-        }
-    }
-
-    @Test
-    public void testGetTetherableInterfaceRegexps() {
-        final TestTetheringEventCallback tetherEventCallback =
-                mCtsTetheringUtils.registerTetheringEventCallback();
-        tetherEventCallback.assumeTetheringSupported();
-
-        final TetheringInterfaceRegexps tetherableRegexs =
-                tetherEventCallback.getTetheringInterfaceRegexps();
-        final List<String> wifiRegexs = tetherableRegexs.getTetherableWifiRegexs();
-        final List<String> usbRegexs = tetherableRegexs.getTetherableUsbRegexs();
-        final List<String> btRegexs = tetherableRegexs.getTetherableBluetoothRegexs();
-
-        assertEquals(wifiRegexs, Arrays.asList(mTM.getTetherableWifiRegexs()));
-        assertEquals(usbRegexs, Arrays.asList(mTM.getTetherableUsbRegexs()));
-        assertEquals(btRegexs, Arrays.asList(mTM.getTetherableBluetoothRegexs()));
-
-        //Verify that any regex name should only contain in one array.
-        wifiRegexs.forEach(s -> assertFalse(usbRegexs.contains(s)));
-        wifiRegexs.forEach(s -> assertFalse(btRegexs.contains(s)));
-        usbRegexs.forEach(s -> assertFalse(btRegexs.contains(s)));
-
-        mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
-    }
-
-    @Test
-    public void testStopAllTethering() throws Exception {
-        final TestTetheringEventCallback tetherEventCallback =
-                mCtsTetheringUtils.registerTetheringEventCallback();
-        tetherEventCallback.assumeTetheringSupported();
-
-        try {
-            if (!isWifiTetheringSupported(tetherEventCallback)) return;
-
-            // TODO: start ethernet tethering here when TetheringManagerTest is moved to
-            // TetheringIntegrationTest.
-
-            mCtsTetheringUtils.startWifiTethering(tetherEventCallback);
-
-            mTM.stopAllTethering();
-            tetherEventCallback.expectTetheredInterfacesChanged(null);
-        } finally {
-            mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
-        }
-    }
-
-    @Test
-    public void testEnableTetheringPermission() throws Exception {
-        dropShellPermissionIdentity();
-        final StartTetheringCallback startTetheringCallback = new StartTetheringCallback();
-        mTM.startTethering(new TetheringRequest.Builder(TETHERING_WIFI).build(),
-                c -> c.run() /* executor */, startTetheringCallback);
-        startTetheringCallback.expectTetheringFailed(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
-    }
-
-    private class EntitlementResultListener implements OnTetheringEntitlementResultListener {
-        private final CompletableFuture<Integer> future = new CompletableFuture<>();
-
-        @Override
-        public void onTetheringEntitlementResult(int result) {
-            future.complete(result);
-        }
-
-        public int get(long timeout, TimeUnit unit) throws Exception {
-            return future.get(timeout, unit);
-        }
-
-    }
-
-    private void assertEntitlementResult(final Consumer<EntitlementResultListener> functor,
-            final int expect) throws Exception {
-        final EntitlementResultListener listener = new EntitlementResultListener();
-        functor.accept(listener);
-
-        assertEquals(expect, listener.get(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testRequestLatestEntitlementResult() throws Exception {
-        assumeTrue(mTM.isTetheringSupported());
-        // Verify that requestLatestTetheringEntitlementResult() can get entitlement
-        // result(TETHER_ERROR_ENTITLEMENT_UNKNOWN due to invalid downstream type) via listener.
-        assertEntitlementResult(listener -> mTM.requestLatestTetheringEntitlementResult(
-                TETHERING_WIFI_P2P, false, c -> c.run(), listener),
-                TETHER_ERROR_ENTITLEMENT_UNKNOWN);
-
-        // Verify that requestLatestTetheringEntitlementResult() can get entitlement
-        // result(TETHER_ERROR_ENTITLEMENT_UNKNOWN due to invalid downstream type) via receiver.
-        assertEntitlementResult(listener -> mTM.requestLatestTetheringEntitlementResult(
-                TETHERING_WIFI_P2P,
-                new ResultReceiver(null /* handler */) {
-                    @Override
-                    public void onReceiveResult(int resultCode, Bundle resultData) {
-                        listener.onTetheringEntitlementResult(resultCode);
-                    }
-                }, false),
-                TETHER_ERROR_ENTITLEMENT_UNKNOWN);
-
-        // Do not request TETHERING_WIFI entitlement result if TETHERING_WIFI is not available.
-        assumeTrue(mTM.getTetherableWifiRegexs().length > 0);
-
-        // Verify that null listener will cause IllegalArgumentException.
-        try {
-            mTM.requestLatestTetheringEntitlementResult(
-                    TETHERING_WIFI, false, c -> c.run(), null);
-        } catch (IllegalArgumentException expect) { }
-
-        // Override carrier config to ignore entitlement check.
-        final PersistableBundle bundle = new PersistableBundle();
-        bundle.putBoolean(CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, false);
-        overrideCarrierConfig(bundle);
-
-        // Verify that requestLatestTetheringEntitlementResult() can get entitlement
-        // result TETHER_ERROR_NO_ERROR due to provisioning bypassed.
-        assertEntitlementResult(listener -> mTM.requestLatestTetheringEntitlementResult(
-                TETHERING_WIFI, false, c -> c.run(), listener), TETHER_ERROR_NO_ERROR);
-
-        // Reset carrier config.
-        overrideCarrierConfig(null);
-    }
-
-    private void overrideCarrierConfig(PersistableBundle bundle) {
-        final CarrierConfigManager configManager = (CarrierConfigManager) mContext
-                .getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        final int subId = SubscriptionManager.getDefaultSubscriptionId();
-        configManager.overrideConfig(subId, bundle);
-    }
-
-    @Test
-    public void testTetheringUpstream() throws Exception {
-        assumeTrue(mPm.hasSystemFeature(FEATURE_TELEPHONY));
-        final TestTetheringEventCallback tetherEventCallback =
-                mCtsTetheringUtils.registerTetheringEventCallback();
-        tetherEventCallback.assumeTetheringSupported();
-        final boolean previousWifiEnabledState = mWm.isWifiEnabled();
-
-        try {
-            if (!isWifiTetheringSupported(tetherEventCallback)) return;
-
-            if (previousWifiEnabledState) {
-                mCtsNetUtils.disconnectFromWifi(null);
-            }
-
-            final TestNetworkCallback networkCallback = new TestNetworkCallback();
-            Network activeNetwork = null;
-            try {
-                mCm.registerDefaultNetworkCallback(networkCallback);
-                activeNetwork = networkCallback.waitForAvailable();
-            } finally {
-                mCm.unregisterNetworkCallback(networkCallback);
-            }
-
-            assertNotNull("No active network. Please ensure the device has working mobile data.",
-                    activeNetwork);
-            final NetworkCapabilities activeNetCap = mCm.getNetworkCapabilities(activeNetwork);
-
-            // If active nework is ETHERNET, tethering may not use cell network as upstream.
-            assumeFalse(activeNetCap.hasTransport(TRANSPORT_ETHERNET));
-
-            assertTrue(activeNetCap.hasTransport(TRANSPORT_CELLULAR));
-
-            mCtsTetheringUtils.startWifiTethering(tetherEventCallback);
-
-            final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
-                    Context.TELEPHONY_SERVICE);
-            final boolean dunRequired = telephonyManager.isTetheringApnRequired();
-            final int expectedCap = dunRequired ? NET_CAPABILITY_DUN : NET_CAPABILITY_INTERNET;
-            final Network network = tetherEventCallback.getCurrentValidUpstream();
-            final NetworkCapabilities netCap = mCm.getNetworkCapabilities(network);
-            assertTrue(netCap.hasTransport(TRANSPORT_CELLULAR));
-            assertTrue(netCap.hasCapability(expectedCap));
-
-            mCtsTetheringUtils.stopWifiTethering(tetherEventCallback);
-        } finally {
-            mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
-            if (previousWifiEnabledState) {
-                mCtsNetUtils.connectToWifi();
-            }
-        }
-    }
-}
