Merge "Merge "Merge "Fix expected reverse lookup of Google DNS IP addresses" into nougat-cts-dev am: 3b416dd354" into nougat-mr1-cts-dev am: 50491fb1cc" into oreo-cts-dev
am: b6d3940f89

Change-Id: Iacbf91536898e4b0d8942581593ab87eae0af323
diff --git a/tests/cts/hostside/Android.mk b/tests/cts/hostside/Android.mk
index 1c3f053..7270580 100644
--- a/tests/cts/hostside/Android.mk
+++ b/tests/cts/hostside/Android.mk
@@ -26,7 +26,7 @@
 LOCAL_CTS_TEST_PACKAGE := android.net.hostsidenetwork
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
 
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
diff --git a/tests/cts/hostside/AndroidTest.xml b/tests/cts/hostside/AndroidTest.xml
index ad7f81b..4a2e2e3 100644
--- a/tests/cts/hostside/AndroidTest.xml
+++ b/tests/cts/hostside/AndroidTest.xml
@@ -15,6 +15,7 @@
 -->
 <configuration description="Config for CTS net host test cases">
     <option name="config-descriptor:metadata" key="component" value="networking" />
+    <target_preparer class="com.android.cts.net.NetPolicyTestsPreparer" />
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
         <option name="jar" value="CtsHostsideNetworkTests.jar" />
         <option name="runtime-hint" value="3m56s" />
diff --git a/tests/cts/hostside/app/Android.mk b/tests/cts/hostside/app/Android.mk
old mode 100644
new mode 100755
index 1c1a798..127ef32
--- a/tests/cts/hostside/app/Android.mk
+++ b/tests/cts/hostside/app/Android.mk
@@ -19,7 +19,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE_TAGS := tests
-LOCAL_SDK_VERSION := current
+#LOCAL_SDK_VERSION := current
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util ctstestrunner ub-uiautomator \
         CtsHostsideNetworkTestsAidl
 
@@ -31,6 +32,6 @@
 LOCAL_DEX_PREOPT := false
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/cts/hostside/app/AndroidManifest.xml b/tests/cts/hostside/app/AndroidManifest.xml
index 0598a3b..7466cb8 100644
--- a/tests/cts/hostside/app/AndroidManifest.xml
+++ b/tests/cts/hostside/app/AndroidManifest.xml
@@ -21,6 +21,8 @@
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
     <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
 
     <application>
         <uses-library android:name="android.test.runner" />
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
index c2dce38..f20f1d1 100644
--- 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
@@ -129,7 +129,7 @@
 
     public void testBackgroundNetworkAccess_enabledButWhitelistedOnNotificationAction()
             throws Exception {
-        if (!isSupported()) return;
+        if (!isSupported() || isLowRamDevice()) return;
 
         setPendingIntentWhitelistDuration(NETWORK_TIMEOUT_MS);
         try {
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
index f3d5d2c..ce56d25 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
@@ -26,13 +26,14 @@
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 
+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.content.pm.PackageManager;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
@@ -42,6 +43,7 @@
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.SystemClock;
+import android.provider.Settings;
 import android.service.notification.NotificationListenerService;
 import android.test.InstrumentationTestCase;
 import android.text.TextUtils;
@@ -116,6 +118,7 @@
     private MyServiceClient mServiceClient;
     private String mDeviceIdleConstantsSetting;
     private boolean mSupported;
+    private boolean mIsLocationOn;
 
     @Override
     protected void setUp() throws Exception {
@@ -130,20 +133,49 @@
         mServiceClient = new MyServiceClient(mContext);
         mServiceClient.bind();
         mDeviceIdleConstantsSetting = "device_idle_constants";
+        mIsLocationOn = isLocationOn();
+        if (!mIsLocationOn) {
+            enableLocation();
+        }
         mSupported = setUpActiveNetworkMeteringState();
 
         Log.i(TAG, "Apps status on " + getName() + ":\n"
                 + "\ttest app: uid=" + mMyUid + ", state=" + getProcessStateByUid(mMyUid) + "\n"
                 + "\tapp2: uid=" + mUid + ", state=" + getProcessStateByUid(mUid));
+        executeShellCommand("settings get global app_idle_constants");
    }
 
     @Override
     protected void tearDown() throws Exception {
+        if (!mIsLocationOn) {
+            disableLocation();
+        }
         mServiceClient.unbind();
 
         super.tearDown();
     }
 
+    private void enableLocation() throws Exception {
+        Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.LOCATION_MODE,
+                Settings.Secure.LOCATION_MODE_SENSORS_ONLY);
+        assertEquals(Settings.Secure.LOCATION_MODE_SENSORS_ONLY,
+                Settings.Secure.getInt(mContext.getContentResolver(),
+                        Settings.Secure.LOCATION_MODE));
+    }
+
+    private void disableLocation() throws Exception {
+        Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.LOCATION_MODE,
+                Settings.Secure.LOCATION_MODE_OFF);
+        assertEquals(Settings.Secure.LOCATION_MODE_OFF,
+                Settings.Secure.getInt(mContext.getContentResolver(),
+                        Settings.Secure.LOCATION_MODE));
+    }
+
+    private boolean isLocationOn() throws Exception {
+        return Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.LOCATION_MODE) != Settings.Secure.LOCATION_MODE_OFF;
+    }
+
     protected int getUid(String packageName) throws Exception {
         return mContext.getPackageManager().getPackageUid(packageName, 0);
     }
@@ -353,14 +385,47 @@
             Log.w(TAG, "Network status didn't match for expectAvailable=" + expectAvailable
                     + " on attempt #" + i + ": " + error + "\n"
                     + "Sleeping " + timeoutMs + "ms before trying again");
-            SystemClock.sleep(timeoutMs);
+            // No sleep after the last turn
+            if (i < maxTries) {
+                SystemClock.sleep(timeoutMs);
+            }
             // Exponential back-off.
             timeoutMs = Math.min(timeoutMs*2, NETWORK_TIMEOUT_MS);
         }
+        dumpOnFailure();
         fail("Invalid state for expectAvailable=" + expectAvailable + " after " + maxTries
                 + " attempts.\nLast error: " + error);
     }
 
+    private void dumpOnFailure() throws Exception {
+        dumpAllNetworkRules();
+        Log.d(TAG, "Usagestats dump: " + getUsageStatsDump());
+        executeShellCommand("settings get global app_idle_constants");
+    }
+
+    private void dumpAllNetworkRules() throws Exception {
+        final String networkManagementDump = runShellCommand(mInstrumentation,
+                "dumpsys network_management").trim();
+        final String networkPolicyDump = runShellCommand(mInstrumentation,
+                "dumpsys netpolicy").trim();
+        TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter('\n');
+        splitter.setString(networkManagementDump);
+        String next;
+        Log.d(TAG, ">>> Begin network_management dump");
+        while (splitter.hasNext()) {
+            next = splitter.next();
+            Log.d(TAG, next);
+        }
+        Log.d(TAG, "<<< End network_management dump");
+        splitter.setString(networkPolicyDump);
+        Log.d(TAG, ">>> Begin netpolicy dump");
+        while (splitter.hasNext()) {
+            next = splitter.next();
+            Log.d(TAG, next);
+        }
+        Log.d(TAG, "<<< End netpolicy dump");
+    }
+
     /**
      * Checks whether the network is available as expected.
      *
@@ -412,6 +477,12 @@
         return errors.toString();
     }
 
+    protected boolean isLowRamDevice() {
+        final ActivityManager am = (ActivityManager) mContext.getSystemService(
+            Context.ACTIVITY_SERVICE);
+        return am.isLowRamDevice();
+    }
+
     protected String executeShellCommand(String command) throws Exception {
         final String result = runShellCommand(mInstrumentation, command).trim();
         if (DEBUG) Log.d(TAG, "Command '" + command + "' returned '" + result + "'");
@@ -558,11 +629,15 @@
         NetworkInfo info = null;
         for (int i = 1; i <= maxTries; i++) {
             info = mCm.getActiveNetworkInfo();
-            if (info != null) {
+            if (info == null) {
+                Log.v(TAG, "No active network info on attempt #" + i
+                        + "; sleeping 1s before polling again");
+            } else if (mCm.isActiveNetworkMetered() != expected) {
+                Log.v(TAG, "Wrong metered status for active network " + info + "; expected="
+                        + expected + "; sleeping 1s before polling again");
+            } else {
                 break;
             }
-            Log.v(TAG, "No active network info on attempt #" + i
-                    + "; sleeping 1s before polling again");
             Thread.sleep(SECOND_IN_MS);
         }
         assertNotNull("No active network after " + maxTries + " attempts", info);
@@ -801,16 +876,8 @@
 
     protected void setAppIdle(boolean enabled) throws Exception {
         Log.i(TAG, "Setting app idle to " + enabled);
-        final String beforeStats = getUsageStatsDump();
         executeSilentShellCommand("am set-inactive " + TEST_APP2_PKG + " " + enabled );
-        try {
-            assertAppIdle(enabled); // Sanity check
-        } catch (Throwable e) {
-            final String afterStats = getUsageStatsDump();
-            Log.d(TAG, "UsageStats before:\n" + beforeStats);
-            Log.d(TAG, "UsageStats after:\n" + afterStats);
-            throw e;
-        }
+        assertAppIdle(enabled); // Sanity check
     }
 
     private String getUsageStatsDump() throws Exception {
@@ -825,7 +892,7 @@
                     && !str.contains(TEST_PKG) && !str.contains(TEST_APP2_PKG)) {
                 continue;
             }
-            if (str.contains("config=")) {
+            if (str.trim().startsWith("config=") || str.trim().startsWith("time=")) {
                 continue;
             }
             sb.append(str).append('\n');
@@ -834,7 +901,13 @@
     }
 
     protected void assertAppIdle(boolean enabled) throws Exception {
-        assertDelayedShellCommand("am get-inactive " + TEST_APP2_PKG, 15, 2, "Idle=" + enabled);
+        try {
+            assertDelayedShellCommand("am get-inactive " + TEST_APP2_PKG, 15, 2, "Idle=" + enabled);
+        } catch (Throwable e) {
+            Log.d(TAG, "UsageStats dump:\n" + getUsageStatsDump());
+            executeShellCommand("settings get global app_idle_constants");
+            throw e;
+        }
     }
 
     /**
@@ -868,19 +941,12 @@
      * notification actions right after the notification is sent.
      */
     protected void registerNotificationListenerService() throws Exception {
-        final StringBuilder listeners = new StringBuilder(getNotificationListenerServices());
-        if (listeners.length() > 0) {
-            listeners.append(":");
-        }
-        listeners.append(MyNotificationListenerService.getId());
-        executeShellCommand("settings put secure enabled_notification_listeners " + listeners);
-        final String newListeners = getNotificationListenerServices();
-        assertEquals("Failed to set 'enabled_notification_listeners'",
-                listeners.toString(), newListeners);
-    }
-
-    private String getNotificationListenerServices() throws Exception {
-        return executeShellCommand("settings get secure enabled_notification_listeners");
+        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 {
@@ -916,10 +982,12 @@
                         // App didn't come to foreground when the activity is started, so try again.
                         assertForegroundNetworkAccess();
                     } else {
+                        dumpOnFailure();
                         fail("Network is not available for app2 (" + mUid + "): " + errors[0]);
                     }
                 }
             } else {
+                dumpOnFailure();
                 fail("Timed out waiting for network availability status from app2 (" + mUid + ")");
             }
         } else {
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
index 599a31c..c3962fb 100644
--- 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
@@ -22,6 +22,9 @@
 
 import android.util.Log;
 
+import com.android.compatibility.common.util.CddTest;
+
+@CddTest(requirement="7.4.7/C-1-1,H-1-1,C-2-1")
 public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase {
 
     private static final String[] REQUIRED_WHITELISTED_PACKAGES = {
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
index 0893511..0132536 100644
--- 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
@@ -19,6 +19,7 @@
 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;
@@ -74,6 +75,11 @@
                 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;
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
index bc982ce..b3f61c4 100755
--- 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
@@ -29,6 +29,7 @@
 import android.net.VpnService;
 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.UiObjectNotFoundException;
@@ -537,6 +538,14 @@
 
     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;
+        }
 
         FileDescriptor fd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS);
 
@@ -554,6 +563,7 @@
 
         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"},
@@ -571,6 +581,12 @@
         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);
diff --git a/tests/cts/hostside/app2/Android.mk b/tests/cts/hostside/app2/Android.mk
index 706455d..5c0bae1 100644
--- a/tests/cts/hostside/app2/Android.mk
+++ b/tests/cts/hostside/app2/Android.mk
@@ -30,6 +30,8 @@
 LOCAL_DEX_PREOPT := false
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+
+LOCAL_CERTIFICATE := cts/hostsidetests/net/certs/cts-net-app
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/cts/hostside/certs/README b/tests/cts/hostside/certs/README
new file mode 100644
index 0000000..b660a82
--- /dev/null
+++ b/tests/cts/hostside/certs/README
@@ -0,0 +1,2 @@
+# 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
new file mode 100644
index 0000000..1703e4e
--- /dev/null
+++ b/tests/cts/hostside/certs/cts-net-app.pk8
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
new file mode 100644
index 0000000..a15ff48
--- /dev/null
+++ b/tests/cts/hostside/certs/cts-net-app.x509.pem
@@ -0,0 +1,19 @@
+-----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/NetPolicyTestsPreparer.java b/tests/cts/hostside/src/com/android/cts/net/NetPolicyTestsPreparer.java
new file mode 100644
index 0000000..9b19554
--- /dev/null
+++ b/tests/cts/hostside/src/com/android/cts/net/NetPolicyTestsPreparer.java
@@ -0,0 +1,75 @@
+/*
+ * 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 com.android.cts.net;
+
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil;
+import com.android.tradefed.targetprep.ITargetCleaner;
+import com.android.tradefed.targetprep.ITargetPreparer;
+
+public class NetPolicyTestsPreparer implements ITargetPreparer, ITargetCleaner {
+    private final static String KEY_PAROLE_DURATION = "parole_duration";
+    private final static String DESIRED_PAROLE_DURATION = "0";
+
+    private boolean mAppIdleConstsUpdated;
+    private String mOriginalAppIdleConsts;
+
+    @Override
+    public void setUp(ITestDevice device, IBuildInfo buildInfo) throws DeviceNotAvailableException {
+        updateParoleDuration(device);
+        LogUtil.CLog.d("Original app_idle_constants: " + mOriginalAppIdleConsts);
+    }
+
+    @Override
+    public void tearDown(ITestDevice device, IBuildInfo buildInfo, Throwable throwable)
+            throws DeviceNotAvailableException {
+        if (mAppIdleConstsUpdated) {
+            executeCmd(device, "settings put global app_idle_constants " + mOriginalAppIdleConsts);
+        }
+    }
+
+    /**
+     * Updates parole_duration with the desired value.
+     */
+    private void updateParoleDuration(ITestDevice device) throws DeviceNotAvailableException {
+        mOriginalAppIdleConsts = executeCmd(device, "settings get global app_idle_constants");
+        String newAppIdleConstants;
+        final String newConstant = KEY_PAROLE_DURATION + "=" + DESIRED_PAROLE_DURATION;
+        if (mOriginalAppIdleConsts == null || "null".equals(mOriginalAppIdleConsts)) {
+            // app_idle_constants is initially empty, so just assign the desired value.
+            newAppIdleConstants = newConstant;
+        } else if (mOriginalAppIdleConsts.contains(KEY_PAROLE_DURATION)) {
+            // app_idle_constants contains parole_duration, so replace it with the desired value.
+            newAppIdleConstants = mOriginalAppIdleConsts.replaceAll(
+                    KEY_PAROLE_DURATION + "=\\d+", newConstant);
+        } else {
+            // app_idle_constants didn't have parole_duration, so append the desired value.
+            newAppIdleConstants = mOriginalAppIdleConsts + "," + newConstant;
+        }
+        executeCmd(device, "settings put global app_idle_constants " + newAppIdleConstants);
+        mAppIdleConstsUpdated = true;
+    }
+
+    private String executeCmd(ITestDevice device, String cmd)
+            throws DeviceNotAvailableException {
+        final String output = device.executeShellCommand(cmd).trim();
+        LogUtil.CLog.d("Output for '%s': %s", cmd, output);
+        return output;
+    }
+}
diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk
index 98cde9b..4aeab38 100644
--- a/tests/cts/net/Android.mk
+++ b/tests/cts/net/Android.mk
@@ -47,7 +47,7 @@
 #LOCAL_SDK_VERSION := current
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
 
 include $(BUILD_CTS_PACKAGE)
 
diff --git a/tests/cts/net/appForApi23/Android.mk b/tests/cts/net/appForApi23/Android.mk
index f0d3535..54b60a0 100644
--- a/tests/cts/net/appForApi23/Android.mk
+++ b/tests/cts/net/appForApi23/Android.mk
@@ -31,7 +31,7 @@
 LOCAL_SDK_VERSION := 23
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
 
 include $(BUILD_CTS_PACKAGE)
 
diff --git a/tests/cts/net/jni/Android.mk b/tests/cts/net/jni/Android.mk
index 0ec8d28..887e95e 100644
--- a/tests/cts/net/jni/Android.mk
+++ b/tests/cts/net/jni/Android.mk
@@ -27,6 +27,9 @@
 
 LOCAL_SHARED_LIBRARIES := libnativehelper_compat_libc++ liblog
 LOCAL_CXX_STL := libc++_static
+
+LOCAL_CFLAGS := -Wno-unused-parameter
+
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
diff --git a/tests/cts/net/native/Android.mk b/tests/cts/net/native/Android.mk
index 8338432..b798d87 100644
--- a/tests/cts/net/native/Android.mk
+++ b/tests/cts/net/native/Android.mk
@@ -1,2 +1,15 @@
-include $(call all-subdir-makefiles)
+# 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 $(call all-subdir-makefiles)
diff --git a/tests/cts/net/native/qtaguid/Android.mk b/tests/cts/net/native/qtaguid/Android.mk
index 4f5bf9f..6c92b5c 100644
--- a/tests/cts/net/native/qtaguid/Android.mk
+++ b/tests/cts/net/native/qtaguid/Android.mk
@@ -16,15 +16,8 @@
 
 LOCAL_PATH:= $(call my-dir)
 
-test_executable := CtsNativeNetTestCases
-list_executable := $(test_executable)_list
-
 include $(CLEAR_VARS)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-
-
-LOCAL_MODULE := $(test_executable)
-LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := CtsNativeNetTestCases
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativetest
 LOCAL_MULTILIB := both
 LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
@@ -33,9 +26,6 @@
 LOCAL_SRC_FILES := \
     src/NativeQtaguidTest.cpp
 
-LOCAL_C_INCLUDES := \
-    external/gtest/include \
-
 LOCAL_SHARED_LIBRARIES := \
     libutils \
     liblog \
@@ -45,27 +35,9 @@
     libgtest
 
 LOCAL_CTS_TEST_PACKAGE := android.net.native
-
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts
+LOCAL_COMPATIBILITY_SUITE := cts vts
 
 LOCAL_CFLAGS := -Werror -Wall
 
 include $(BUILD_CTS_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-
-LOCAL_MODULE := $(list_executable)
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := \
-    src/NativeQtaguidTest.cpp
-
-LOCAL_CFLAGS := \
-    -DBUILD_ONLY \
-
-LOCAL_SHARED_LIBRARIES := \
-    liblog \
-
-include $(BUILD_HOST_NATIVE_TEST)
diff --git a/tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp b/tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp
index 0301c81..9009c24 100644
--- a/tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp
+++ b/tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp
@@ -17,16 +17,12 @@
 #include <arpa/inet.h>
 #include <errno.h>
 #include <inttypes.h>
-#include <stdlib.h>
 #include <string.h>
 #include <sys/socket.h>
+
 #include <gtest/gtest.h>
-
-#if !defined(BUILD_ONLY)
 #include <cutils/qtaguid.h>
-#endif
 
-#if !defined(BUILD_ONLY)
 int getCtrlSkInfo(int tag, uid_t uid, uint64_t* sk_addr, int* ref_cnt) {
     FILE *fp;
     fp = fopen("/proc/net/xt_qtaguid/ctrl", "r");
@@ -69,12 +65,35 @@
     EXPECT_EQ(0, qtaguid_tagSocket(sockfd, tag, uid));
     EXPECT_EQ(0, getCtrlSkInfo(tag, uid, &sk_addr, &ref_cnt));
     EXPECT_EQ(expect_addr, sk_addr);
-    EXPECT_EQ(0, qtaguid_untagSocket(sockfd));
+    close(sockfd);
     EXPECT_EQ(-ENOENT, getCtrlSkInfo(tag, uid, &sk_addr, &ref_cnt));
 }
-#else
-void checkNoSocketPointerLeaks(int family) {}
-#endif
+
+TEST (NativeQtaguidTest, close_socket_without_untag) {
+    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, qtaguid_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) {
+    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, qtaguid_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) {
   checkNoSocketPointerLeaks(AF_INET);
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index 9f54c8e..c885942 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -37,6 +37,7 @@
 import android.net.NetworkInfo.State;
 import android.net.NetworkRequest;
 import android.net.wifi.WifiManager;
+import android.os.Looper;
 import android.os.SystemProperties;
 import android.system.Os;
 import android.system.OsConstants;
@@ -110,6 +111,7 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+        Looper.prepare();
         mContext = getContext();
         mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
         mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
@@ -279,11 +281,10 @@
     }
 
     private boolean isSupported(int networkType) {
-        // Change-Id I02eb5f22737720095f646f8db5c87fd66da129d6 added VPN support
-        // to all devices directly in software, independent of any external
-        // configuration.
         return mNetworks.containsKey(networkType) ||
-               (networkType == ConnectivityManager.TYPE_VPN);
+               (networkType == ConnectivityManager.TYPE_VPN) ||
+               (networkType == ConnectivityManager.TYPE_ETHERNET &&
+                       mContext.getSystemService(Context.ETHERNET_SERVICE) != null);
     }
 
     public void testIsNetworkSupported() {
diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java
index 87e22d8..5dce5ab 100644
--- a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java
+++ b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java
@@ -41,6 +41,8 @@
 import android.test.AndroidTestCase;
 import android.util.Log;
 
+import com.android.compatibility.common.util.CddTest;
+
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -54,6 +56,7 @@
  * Wi-Fi Aware CTS test suite: single device testing. Performs tests on a single
  * device to validate Wi-Fi Aware.
  */
+@CddTest(requirement="7.4.2.3/C-1-1")
 public class SingleDeviceTest extends AndroidTestCase {
     private static final String TAG = "WifiAwareCtsTests";
 
@@ -485,6 +488,7 @@
      * then the attach/destroy will not correspond to enable/disable and will not result in a new
      * MAC address being generated.
      */
+    @CddTest(requirement="7.4.2.3/C-1-4")
     public void testAttachDiscoveryAddressChanges() {
         if (!TestUtils.shouldTestWifiAware(getContext())) {
             return;
diff --git a/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java b/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java
index a066ba8..4187883 100644
--- a/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java
@@ -31,9 +31,12 @@
 import static android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_STATE_ENABLED;
 import android.test.AndroidTestCase;
 
+import com.android.compatibility.common.util.CddTest;
+
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
+@CddTest(requirement="7.4.2.1/C-1-1,C-1-3")
 public class ConcurrencyTest extends AndroidTestCase {
     private class MySync {
         int expectedWifiState;
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java
index 4480a24..8b17a57 100644
--- a/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java
@@ -23,6 +23,9 @@
 import android.net.wifi.WifiManager;
 import android.test.AndroidTestCase;
 
+import com.android.compatibility.common.util.CddTest;
+
+@CddTest(requirement="7.4.2/C-1-1")
 public class WifiConfigurationTest extends AndroidTestCase {
     private  WifiManager mWifiManager;
     @Override
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java
index 5983cb7..c97f010 100644
--- a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java
@@ -29,9 +29,11 @@
 import android.test.AndroidTestCase;
 
 import com.android.compatibility.common.util.PollingCheck;
+import com.android.compatibility.common.util.CddTest;
 
 import java.util.concurrent.Callable;
 
+@CddTest(requirement="7.4.2/C-1-1")
 public class WifiInfoTest extends AndroidTestCase {
     private static class MySync {
         int expectedState = STATE_NULL;
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java
index 44b49c0..90540f4 100644
--- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -37,6 +37,7 @@
 import android.test.AndroidTestCase;
 import android.util.Log;
 
+import com.android.compatibility.common.util.CddTest;
 import com.android.compatibility.common.util.WifiConfigCreator;
 
 import java.net.HttpURLConnection;
@@ -49,6 +50,7 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 
+@CddTest(requirement="7.4.2/C-1-1")
 public class WifiManagerTest extends AndroidTestCase {
     private static class MySync {
         int expectedState = STATE_NULL;
@@ -77,6 +79,10 @@
     private static final String SSID2 = "\"WifiManagerTestModified\"";
     private static final String PROXY_TEST_SSID = "SomeProxyAp";
     private static final String ADD_NETWORK_EXCEPTION_SUBSTR = "addNetwork";
+    // A full single scan duration is about 6-7 seconds if country code is set
+    // to US. If country code is set to world mode (00), we would expect a scan
+    // duration of roughly 8 seconds. So we set scan timeout as 9 seconds here.
+    private static final int SCAN_TIMEOUT_MSEC = 9000;
     private static final int TIMEOUT_MSEC = 6000;
     private static final int WAIT_MSEC = 60;
     private static final int DURATION = 10000;
@@ -202,7 +208,7 @@
             mMySync.expectedState = STATE_SCANNING;
             mScanResults = null;
             assertTrue(mWifiManager.startScan());
-            long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
+            long timeout = System.currentTimeMillis() + SCAN_TIMEOUT_MSEC;
             while (System.currentTimeMillis() < timeout && mMySync.expectedState == STATE_SCANNING)
                 mMySync.wait(WAIT_MSEC);
         }
@@ -582,6 +588,7 @@
      *
      * @throws Exception
      */
+    @CddTest(requirement="7.4.2.4/C-1-1,C-1-2,C-2-1")
     public void testAddPasspointConfigWithUserCredential() throws Exception {
         if (!WifiFeature.isWifiSupported(getContext())) {
             // skip the test if WiFi is not supported
@@ -596,6 +603,7 @@
      *
      * @throws Exception
      */
+    @CddTest(requirement="7.4.2.4/C-1-1,C-1-2,C-2-1")
     public void testAddPasspointConfigWithCertCredential() throws Exception {
         if (!WifiFeature.isWifiSupported(getContext())) {
             // skip the test if WiFi is not supported
@@ -610,6 +618,7 @@
      *
      * @throws Exception
      */
+    @CddTest(requirement="7.4.2.4/C-1-1,C-1-2,C-2-1")
     public void testAddPasspointConfigWithSimCredential() throws Exception {
         if (!WifiFeature.isWifiSupported(getContext())) {
             // skip the test if WiFi is not supported
@@ -816,7 +825,11 @@
      * Note: Location mode must be enabled for this test.
      */
     public void testStartLocalOnlyHotspotSuccess() {
-        // first check that softap mode is supported by the device
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        // check that softap mode is supported by the device
         if (!mWifiManager.isPortableHotspotSupported()) {
             return;
         }
@@ -839,7 +852,6 @@
      * tethering is started.
      * Note: Location mode must be enabled for this test.
      */
-
     public void testSetWifiEnabledByAppDoesNotStopHotspot() throws Exception {
         if (!WifiFeature.isWifiSupported(getContext())) {
             // skip the test if WiFi is not supported
@@ -872,7 +884,11 @@
      * Note: Location mode must be enabled for this test.
      */
     public void testStartLocalOnlyHotspotSingleRequestByApps() {
-        // first check that softap mode is supported by the device
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        // check that softap mode is supported by the device
         if (!mWifiManager.isPortableHotspotSupported()) {
             return;
         }
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java
index 3cdd56a..aeb1234 100644
--- a/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java
@@ -21,6 +21,9 @@
 import android.net.wifi.WifiManager.WifiLock;
 import android.test.AndroidTestCase;
 
+import com.android.compatibility.common.util.CddTest;
+
+@CddTest(requirement="7.4.2/C-1-1")
 public class WifiManager_WifiLockTest extends AndroidTestCase {
 
     private static final String WIFI_TAG = "WifiManager_WifiLockTest";