resolve merge conflicts of 1381b1d9a77260d78a3a67359e16c06ee388d37b to oc-mr1-dev-plus-aosp
am: 0c02379ec1  -s ours

Change-Id: I8bc040bea87ffb581568eae69cafb2c65fca9412
diff --git a/tests/cts/hostside/AndroidTest.xml b/tests/cts/hostside/AndroidTest.xml
index 4a2e2e3..c96fea4 100644
--- a/tests/cts/hostside/AndroidTest.xml
+++ b/tests/cts/hostside/AndroidTest.xml
@@ -14,6 +14,7 @@
      limitations under the License.
 -->
 <configuration description="Config for CTS net host test cases">
+    <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="networking" />
     <target_preparer class="com.android.cts.net.NetPolicyTestsPreparer" />
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
diff --git a/tests/cts/hostside/app/Android.mk b/tests/cts/hostside/app/Android.mk
index f094f3f..c03e70b 100644
--- a/tests/cts/hostside/app/Android.mk
+++ b/tests/cts/hostside/app/Android.mk
@@ -23,6 +23,8 @@
 LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util ctstestrunner ub-uiautomator \
         CtsHostsideNetworkTestsAidl
 
+LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := CtsHostsideNetworkTestsApp
diff --git a/tests/cts/hostside/app/AndroidManifest.xml b/tests/cts/hostside/app/AndroidManifest.xml
index 7466cb8..2553f47 100644
--- a/tests/cts/hostside/app/AndroidManifest.xml
+++ b/tests/cts/hostside/app/AndroidManifest.xml
@@ -20,6 +20,7 @@
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
+    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
     <uses-permission android:name="android.permission.INTERNET"/>
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java
index d2c0873..0e141c0 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java
@@ -34,7 +34,7 @@
         removePowerSaveModeWhitelist(TEST_APP2_PKG);
         removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG);
         setAppIdle(false);
-        turnBatteryOff();
+        turnBatteryOn();
 
         registerBroadcastReceiver();
     }
@@ -48,7 +48,7 @@
         try {
             tearDownMeteredNetwork();
         } finally {
-            turnBatteryOn();
+            turnBatteryOff();
             setAppIdle(false);
         }
     }
@@ -127,6 +127,19 @@
         assertBackgroundNetworkAccess(false);
     }
 
+    public void testBackgroundNetworkAccess_tempWhitelisted() throws Exception {
+        if (!isSupported()) return;
+
+        setAppIdle(true);
+        assertBackgroundNetworkAccess(false);
+
+        addTempPowerSaveModeWhitelist(TEST_APP2_PKG, TEMP_POWERSAVE_WHITELIST_DURATION_MS);
+        assertBackgroundNetworkAccess(true);
+        // Wait until the whitelist duration is expired.
+        SystemClock.sleep(TEMP_POWERSAVE_WHITELIST_DURATION_MS);
+        assertBackgroundNetworkAccess(false);
+    }
+
     public void testBackgroundNetworkAccess_disabled() throws Exception {
         if (!isSupported()) return;
 
@@ -142,9 +155,9 @@
         // Check that app is paroled when charging
         setAppIdle(true);
         assertBackgroundNetworkAccess(false);
-        turnBatteryOn();
-        assertBackgroundNetworkAccess(true);
         turnBatteryOff();
+        assertBackgroundNetworkAccess(true);
+        turnBatteryOn();
         assertBackgroundNetworkAccess(false);
 
         // Check that app is restricted when not idle but power-save is on
@@ -154,11 +167,11 @@
         assertBackgroundNetworkAccess(false);
         // Use setBatterySaverMode API to leave power-save mode instead of plugging in charger
         setBatterySaverMode(false);
-        turnBatteryOn();
+        turnBatteryOff();
         assertBackgroundNetworkAccess(true);
 
         // And when no longer charging, it still has network access, since it's not idle
-        turnBatteryOff();
+        turnBatteryOn();
         assertBackgroundNetworkAccess(true);
     }
 
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
index ce56d25..2f36b93 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
@@ -49,8 +49,6 @@
 import android.text.TextUtils;
 import android.util.Log;
 
-import com.android.cts.net.hostside.INetworkStateObserver;
-
 /**
  * Superclass for tests related to background network restrictions.
  */
@@ -87,7 +85,7 @@
     private static final String NETWORK_STATUS_SEPARATOR = "\\|";
     private static final int SECOND_IN_MS = 1000;
     static final int NETWORK_TIMEOUT_MS = 15 * SECOND_IN_MS;
-    private static final int PROCESS_STATE_FOREGROUND_SERVICE = 4;
+    private static final int PROCESS_STATE_FOREGROUND_SERVICE = 3;
     private static final int PROCESS_STATE_TOP = 2;
 
     private static final String KEY_NETWORK_STATE_OBSERVER = TEST_PKG + ".observer";
@@ -108,6 +106,8 @@
 
     private static final String APP_NOT_FOREGROUND_ERROR = "app_not_fg";
 
+    protected static final long TEMP_POWERSAVE_WHITELIST_DURATION_MS = 5_000; // 5 sec
+
     protected Context mContext;
     protected Instrumentation mInstrumentation;
     protected ConnectivityManager mCm;
@@ -138,6 +138,7 @@
             enableLocation();
         }
         mSupported = setUpActiveNetworkMeteringState();
+        setAppIdle(false);
 
         Log.i(TAG, "Apps status on " + getName() + ":\n"
                 + "\ttest app: uid=" + mMyUid + ", state=" + getProcessStateByUid(mMyUid) + "\n"
@@ -147,6 +148,7 @@
 
     @Override
     protected void tearDown() throws Exception {
+        batteryReset();
         if (!mIsLocationOn) {
             disableLocation();
         }
@@ -751,6 +753,12 @@
                 + ". Full list: " + uids);
     }
 
+    protected void addTempPowerSaveModeWhitelist(String packageName, long duration)
+            throws Exception {
+        Log.i(TAG, "Adding pkg " + packageName + " to temp-power-save-mode whitelist");
+        executeShellCommand("dumpsys deviceidle tempwhitelist -d " + duration + " " + packageName);
+    }
+
     protected void assertPowerSaveModeWhitelist(String packageName, boolean expected)
             throws Exception {
         // TODO: currently the power-save mode is behaving like idle, but once it changes, we'll
@@ -800,15 +808,22 @@
         assertPowerSaveModeExceptIdleWhitelist(packageName, false); // Sanity check
     }
 
-    protected void turnBatteryOff() throws Exception {
+    protected void turnBatteryOn() throws Exception {
         executeSilentShellCommand("cmd battery unplug");
+        executeSilentShellCommand("cmd battery set status "
+                + BatteryManager.BATTERY_STATUS_NOT_CHARGING);
         assertBatteryState(false);
     }
 
-    protected void turnBatteryOn() throws Exception {
-        executeSilentShellCommand("cmd battery reset");
+    protected void turnBatteryOff() throws Exception {
+        executeSilentShellCommand("cmd battery set ac " + BatteryManager.BATTERY_PLUGGED_AC);
+        executeSilentShellCommand("cmd battery set status "
+                + BatteryManager.BATTERY_STATUS_CHARGING);
         assertBatteryState(true);
+    }
 
+    private void batteryReset() throws Exception {
+        executeSilentShellCommand("cmd battery reset");
     }
 
     private void assertBatteryState(boolean pluggedIn) throws Exception {
@@ -839,11 +854,11 @@
     protected void setBatterySaverMode(boolean enabled) throws Exception {
         Log.i(TAG, "Setting Battery Saver Mode to " + enabled);
         if (enabled) {
-            turnBatteryOff();
+            turnBatteryOn();
             executeSilentShellCommand("cmd power set-mode 1");
         } else {
             executeSilentShellCommand("cmd power set-mode 0");
-            turnBatteryOn();
+            turnBatteryOff();
         }
     }
 
@@ -853,12 +868,12 @@
 
         Log.i(TAG, "Setting Doze Mode to " + enabled);
         if (enabled) {
-            turnBatteryOff();
+            turnBatteryOn();
             turnScreenOff();
             executeShellCommand("dumpsys deviceidle force-idle deep");
         } else {
             turnScreenOn();
-            turnBatteryOn();
+            turnBatteryOff();
             executeShellCommand("dumpsys deviceidle unforce");
         }
         // Sanity check.
@@ -1004,7 +1019,8 @@
     private Intent getIntentForComponent(int type) {
         final Intent intent = new Intent();
         if (type == TYPE_COMPONENT_ACTIVTIY) {
-            intent.setComponent(new ComponentName(TEST_APP2_PKG, TEST_APP2_ACTIVITY_CLASS));
+            intent.setComponent(new ComponentName(TEST_APP2_PKG, TEST_APP2_ACTIVITY_CLASS))
+                    .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         } else if (type == TYPE_COMPONENT_FOREGROUND_SERVICE) {
             intent.setComponent(new ComponentName(TEST_APP2_PKG, TEST_APP2_SERVICE_CLASS))
                     .setFlags(1);
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java
index 5248255..76332be 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java
@@ -15,6 +15,7 @@
  */
 package com.android.cts.net.hostside;
 
+import android.os.SystemClock;
 import android.util.Log;
 
 /**
@@ -271,4 +272,55 @@
             setDozeMode(false);
         }
     }
+
+    public void testAppIdleAndDoze_tempPowerSaveWhitelists() throws Exception {
+        if (!isSupported()) {
+            return;
+        }
+        if (!isDozeModeEnabled()) {
+            Log.i(TAG, "Skipping " + getClass() + "." + getName()
+                    + "() because device does not support Doze Mode");
+            return;
+        }
+
+        setDozeMode(true);
+        setAppIdle(true);
+
+        try {
+            assertBackgroundNetworkAccess(false);
+
+            addTempPowerSaveModeWhitelist(TEST_APP2_PKG, TEMP_POWERSAVE_WHITELIST_DURATION_MS);
+            assertBackgroundNetworkAccess(true);
+
+            // Wait until the whitelist duration is expired.
+            SystemClock.sleep(TEMP_POWERSAVE_WHITELIST_DURATION_MS);
+            assertBackgroundNetworkAccess(false);
+        } finally {
+            setAppIdle(false);
+            setDozeMode(false);
+        }
+    }
+
+    public void testAppIdleAndBatterySaver_tempPowerSaveWhitelists() throws Exception {
+        if (!isSupported()) {
+            return;
+        }
+
+        setBatterySaverMode(true);
+        setAppIdle(true);
+
+        try {
+            assertBackgroundNetworkAccess(false);
+
+            addTempPowerSaveModeWhitelist(TEST_APP2_PKG, TEMP_POWERSAVE_WHITELIST_DURATION_MS);
+            assertBackgroundNetworkAccess(true);
+
+            // Wait until the whitelist duration is expired.
+            SystemClock.sleep(TEMP_POWERSAVE_WHITELIST_DURATION_MS);
+            assertBackgroundNetworkAccess(false);
+        } finally {
+            setAppIdle(false);
+            setBatterySaverMode(false);
+        }
+    }
 }
diff --git a/tests/cts/hostside/app2/AndroidManifest.xml b/tests/cts/hostside/app2/AndroidManifest.xml
index adf0045..acd393d 100644
--- a/tests/cts/hostside/app2/AndroidManifest.xml
+++ b/tests/cts/hostside/app2/AndroidManifest.xml
@@ -19,6 +19,7 @@
     package="com.android.cts.net.hostside.app2" >
 
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
     <uses-permission android:name="android.permission.INTERNET" />
 
     <!--
diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java
index c6df893..7c9ce8f 100644
--- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java
+++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java
@@ -19,13 +19,13 @@
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.TestIdentifier;
-import com.android.ddmlib.testrunner.TestResult;
 import com.android.ddmlib.testrunner.TestResult.TestStatus;
-import com.android.ddmlib.testrunner.TestRunResult;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.result.TestDescription;
+import com.android.tradefed.result.TestResult;
+import com.android.tradefed.result.TestRunResult;
 import com.android.tradefed.testtype.DeviceTestCase;
 import com.android.tradefed.testtype.IAbi;
 import com.android.tradefed.testtype.IAbiReceiver;
@@ -150,7 +150,7 @@
         if (result.hasFailedTests()) {
             // build a meaningful error message
             StringBuilder errorBuilder = new StringBuilder("on-device tests failed:\n");
-            for (Map.Entry<TestIdentifier, TestResult> resultEntry :
+            for (Map.Entry<TestDescription, TestResult> resultEntry :
                 result.getTestResults().entrySet()) {
                 if (!resultEntry.getValue().getStatus().equals(TestStatus.PASSED)) {
                     errorBuilder.append(resultEntry.getKey().toString());
diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
index bf3fc08..fe9d36c 100644
--- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
+++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
@@ -146,6 +146,11 @@
                 "testBackgroundNetworkAccess_whitelisted");
     }
 
+    public void testAppIdleMetered_tempWhitelisted() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleMeteredTest",
+                "testBackgroundNetworkAccess_tempWhitelisted");
+    }
+
     public void testAppIdleMetered_enabled() throws Exception {
         runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleMeteredTest",
                 "testBackgroundNetworkAccess_enabled");
@@ -166,6 +171,11 @@
                 "testBackgroundNetworkAccess_whitelisted");
     }
 
+    public void testAppIdleNonMetered_tempWhitelisted() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleNonMeteredTest",
+                "testBackgroundNetworkAccess_tempWhitelisted");
+    }
+
     public void testAppIdleNonMetered_enabled() throws Exception {
         runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleNonMeteredTest",
                 "testBackgroundNetworkAccess_enabled");
@@ -261,6 +271,16 @@
                 "testDozeAndAppIdle_powerSaveWhitelists");
     }
 
+    public void testAppIdleAndDoze_tempPowerSaveWhitelists() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".MixedModesTest",
+                "testAppIdleAndDoze_tempPowerSaveWhitelists");
+    }
+
+    public void testAppIdleAndBatterySaver_tempPowerSaveWhitelists() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".MixedModesTest",
+                "testAppIdleAndBatterySaver_tempPowerSaveWhitelists");
+    }
+
     /*******************
      * Helper methods. *
      *******************/
diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk
index 9559779..e67bb8f 100644
--- a/tests/cts/net/Android.mk
+++ b/tests/cts/net/Android.mk
@@ -24,7 +24,12 @@
 # Include both the 32 and 64 bit versions
 LOCAL_MULTILIB := both
 
-LOCAL_JAVA_LIBRARIES := voip-common conscrypt org.apache.http.legacy
+LOCAL_JAVA_LIBRARIES := \
+    voip-common \
+    conscrypt \
+    org.apache.http.legacy \
+    android.test.base.stubs \
+
 
 LOCAL_JNI_SHARED_LIBRARIES := libcts_jni libnativedns_jni \
                               libnativemultinetwork_jni libnativehelper_compat_libc++
@@ -40,8 +45,7 @@
     ctstestrunner \
     ctstestserver \
     mockwebserver \
-    junit \
-    legacy-android-test
+    junit
 
 # uncomment when b/13249961 is fixed
 #LOCAL_SDK_VERSION := current
diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml
index dd310a1..37bf323 100644
--- a/tests/cts/net/AndroidManifest.xml
+++ b/tests/cts/net/AndroidManifest.xml
@@ -30,7 +30,7 @@
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
 
-    <application>
+    <application android:usesCleartextTraffic="true">
         <uses-library android:name="android.test.runner" />
         <uses-library android:name="org.apache.http.legacy" android:required="false" />
 
diff --git a/tests/cts/net/AndroidTest.xml b/tests/cts/net/AndroidTest.xml
index 4a578ea..4190a77 100644
--- a/tests/cts/net/AndroidTest.xml
+++ b/tests/cts/net/AndroidTest.xml
@@ -13,6 +13,7 @@
      limitations under the License.
 -->
 <configuration description="Config for CTS Net test cases">
+    <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="networking" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/tests/cts/net/assets/network_watchlist_config_for_test.xml b/tests/cts/net/assets/network_watchlist_config_for_test.xml
new file mode 100644
index 0000000..835ae0f
--- /dev/null
+++ b/tests/cts/net/assets/network_watchlist_config_for_test.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright (C) 2018 The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<!-- This test config file just contains some random hashes for testing
+ConnectivityManager.getWatchlistConfigHash() -->
+<watchlist-config>
+    <sha256-domain>
+        <hash>F0905DA7549614957B449034C281EF7BDEFDBC2B6E050AD1E78D6DE18FBD0D5F</hash>
+    </sha256-domain>
+    <sha256-ip>
+        <hash>18DD41C9F2E8E4879A1575FB780514EF33CF6E1F66578C4AE7CCA31F49B9F2EC</hash>
+    </sha256-ip>
+    <crc32-domain>
+        <hash>AAAAAAAA</hash>
+    </crc32-domain>
+    <crc32-ip>
+        <hash>BBBBBBBB</hash>
+    </crc32-ip>
+</watchlist-config>
diff --git a/tests/cts/net/native/qtaguid/AndroidTest.xml b/tests/cts/net/native/qtaguid/AndroidTest.xml
index 2eea82e..7591c87 100644
--- a/tests/cts/net/native/qtaguid/AndroidTest.xml
+++ b/tests/cts/net/native/qtaguid/AndroidTest.xml
@@ -14,6 +14,7 @@
      limitations under the License.
 -->
 <configuration description="Config for CTS Native Network xt_qtaguid test cases">
+    <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="networking" />
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
         <option name="cleanup" value="true" />
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index c885942..754e4f6 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -16,8 +16,11 @@
 
 package android.net.cts;
 
+import static android.content.pm.PackageManager.FEATURE_TELEPHONY;
+import static android.content.pm.PackageManager.FEATURE_WIFI;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 
 import android.app.PendingIntent;
@@ -29,6 +32,7 @@
 import android.content.pm.PackageManager;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
+import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkConfig;
@@ -50,14 +54,23 @@
 import java.io.FileNotFoundException;
 import java.io.InputStream;
 import java.io.IOException;
+import java.io.InputStreamReader;
 import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.Inet6Address;
+import java.net.InetAddress;
 import java.net.Socket;
 import java.net.InetSocketAddress;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Scanner;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
+import libcore.io.Streams;
 
 public class ConnectivityManagerTest extends AndroidTestCase {
 
@@ -107,6 +120,8 @@
     private final HashMap<Integer, NetworkConfig> mNetworks =
             new HashMap<Integer, NetworkConfig>();
     boolean mWifiConnectAttempted;
+    private TestNetworkCallback mCellNetworkCallback;
+
 
     @Override
     protected void setUp() throws Exception {
@@ -140,6 +155,10 @@
         if (mWifiConnectAttempted) {
             disconnectFromWifi(null);
         }
+        if (cellConnectAttempted()) {
+            disconnectFromCell();
+        }
+        super.tearDown();
     }
 
     /**
@@ -246,6 +265,95 @@
         }
     }
 
+    /**
+     * Tests that connections can be opened on WiFi and cellphone networks,
+     * and that they are made from different IP addresses.
+     */
+    public void testOpenConnection() throws Exception {
+        boolean canRunTest = mPackageManager.hasSystemFeature(FEATURE_WIFI)
+                && mPackageManager.hasSystemFeature(FEATURE_TELEPHONY);
+        if (!canRunTest) {
+            Log.i(TAG,"testOpenConnection cannot execute unless device supports both WiFi "
+                    + "and a cellular connection");
+            return;
+        }
+
+        Network wifiNetwork = connectToWifi();
+        Network cellNetwork = connectToCell();
+        // This server returns the requestor's IP address as the response body.
+        URL url = new URL("http://google-ipv6test.appspot.com/ip.js?fmt=text");
+        String wifiAddressString = httpGet(wifiNetwork, url);
+        String cellAddressString = httpGet(cellNetwork, url);
+
+        assertFalse(String.format("Same address '%s' on two different networks (%s, %s)",
+                wifiAddressString, wifiNetwork, cellNetwork),
+                wifiAddressString.equals(cellAddressString));
+
+        // Sanity check that the IP addresses that the requests appeared to come from
+        // are actually on the respective networks.
+        assertOnNetwork(wifiAddressString, wifiNetwork);
+        assertOnNetwork(cellAddressString, cellNetwork);
+
+        assertFalse("Unexpectedly equal: " + wifiNetwork, wifiNetwork.equals(cellNetwork));
+    }
+
+    private Network connectToCell() throws InterruptedException {
+        if (cellConnectAttempted()) {
+            throw new IllegalStateException("Already connected");
+        }
+        NetworkRequest cellRequest = new NetworkRequest.Builder()
+                .addTransportType(TRANSPORT_CELLULAR)
+                .addCapability(NET_CAPABILITY_INTERNET)
+                .build();
+        mCellNetworkCallback = new TestNetworkCallback();
+        mCm.requestNetwork(cellRequest, mCellNetworkCallback);
+        final Network cellNetwork = mCellNetworkCallback.waitForAvailable();
+        assertNotNull("Cell network not available within timeout", cellNetwork);
+        return cellNetwork;
+    }
+
+    private boolean cellConnectAttempted() {
+        return mCellNetworkCallback != null;
+    }
+
+    private void disconnectFromCell() {
+        if (!cellConnectAttempted()) {
+            throw new IllegalStateException("Cell connection not attempted");
+        }
+        mCm.unregisterNetworkCallback(mCellNetworkCallback);
+        mCellNetworkCallback = null;
+    }
+
+    /**
+     * Performs a HTTP GET to the specified URL on the specified Network, and returns
+     * the response body decoded as UTF-8.
+     */
+    private static String httpGet(Network network, URL httpUrl) throws IOException {
+        HttpURLConnection connection = (HttpURLConnection) network.openConnection(httpUrl);
+        try {
+            InputStream inputStream = connection.getInputStream();
+            return Streams.readFully(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
+        } finally {
+            connection.disconnect();
+        }
+    }
+
+    private void assertOnNetwork(String adressString, Network network) throws UnknownHostException {
+        InetAddress address = InetAddress.getByName(adressString);
+        LinkProperties linkProperties = mCm.getLinkProperties(network);
+        // To make sure that the request went out on the right network, check that
+        // the IP address seen by the server is assigned to the expected network.
+        // We can only do this for IPv6 addresses, because in IPv4 we will likely
+        // have a private IPv4 address, and that won't match what the server sees.
+        if (address instanceof Inet6Address) {
+            assertContains(linkProperties.getAddresses(), address);
+        }
+    }
+
+    private static<T> void assertContains(Collection<T> collection, T element) {
+        assertTrue(element + " not found in " + collection, collection.contains(element));
+    }
+
     private void assertStartUsingNetworkFeatureUnsupported(int networkType, String feature) {
         try {
             mCm.startUsingNetworkFeature(networkType, feature);
@@ -324,7 +432,7 @@
      * that it would increase test coverage by much (how many devices have 3G radio but not Wifi?).
      */
     public void testRegisterNetworkCallback() {
-        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+        if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
             Log.i(TAG, "testRegisterNetworkCallback cannot execute unless device supports WiFi");
             return;
         }
@@ -364,7 +472,7 @@
      * of a {@code NetworkCallback}.
      */
     public void testRegisterNetworkCallback_withPendingIntent() {
-        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+        if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
             Log.i(TAG, "testRegisterNetworkCallback cannot execute unless device supports WiFi");
             return;
         }
@@ -458,7 +566,7 @@
      * Tests reporting of connectivity changed.
      */
     public void testConnectivityChanged_manifestRequestOnly_shouldNotReceiveIntent() {
-        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+        if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
             Log.i(TAG, "testConnectivityChanged_manifestRequestOnly_shouldNotReceiveIntent cannot execute unless device supports WiFi");
             return;
         }
@@ -475,7 +583,7 @@
     }
 
     public void testConnectivityChanged_whenRegistered_shouldReceiveIntent() {
-        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+        if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
             Log.i(TAG, "testConnectivityChanged_whenRegistered_shouldReceiveIntent cannot execute unless device supports WiFi");
             return;
         }
@@ -495,7 +603,7 @@
 
     public void testConnectivityChanged_manifestRequestOnlyPreN_shouldReceiveIntent()
             throws InterruptedException {
-        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+        if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
             Log.i(TAG, "testConnectivityChanged_manifestRequestOnlyPreN_shouldReceiveIntent cannot execute unless device supports WiFi");
             return;
         }
diff --git a/tests/cts/net/src/android/net/cts/NetworkWatchlistTest.java b/tests/cts/net/src/android/net/cts/NetworkWatchlistTest.java
new file mode 100644
index 0000000..939079f
--- /dev/null
+++ b/tests/cts/net/src/android/net/cts/NetworkWatchlistTest.java
@@ -0,0 +1,113 @@
+/*
+ * 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.content.Context;
+import android.net.ConnectivityManager;
+import android.os.FileUtils;
+import android.support.test.InstrumentationRegistry;
+import android.test.AndroidTestCase;
+
+import com.android.compatibility.common.util.ApiLevelUtil;
+import com.android.compatibility.common.util.SystemUtil;
+
+import org.junit.Assert;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Formatter;
+
+public class NetworkWatchlistTest extends AndroidTestCase {
+
+    private static final String TEST_WATCHLIST_XML = "assets/network_watchlist_config_for_test.xml";
+    private static final String SDCARD_CONFIG_PATH =
+            "/sdcard/network_watchlist_config_for_test.xml";
+    private static final String TMP_CONFIG_PATH =
+            "/data/local/tmp/network_watchlist_config_for_test.xml";
+    // Generated from sha256sum network_watchlist_config_for_test.xml
+    private static final String TEST_WATCHLIST_CONFIG_HASH =
+            "B5FC4636994180D54E1E912F78178AB1D8BD2BE71D90CA9F5BBC3284E4D04ED4";
+
+    private Context mContext;
+    private boolean mHasFeature;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getContext();
+        mHasFeature = isAtLeastP();
+        runCommand("rm " + SDCARD_CONFIG_PATH);
+        runCommand("rm " + TMP_CONFIG_PATH);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        runCommand("rm " + SDCARD_CONFIG_PATH);
+        runCommand("rm " + TMP_CONFIG_PATH);
+    }
+
+    private boolean isAtLeastP() throws Exception {
+        // TODO: replace with ApiLevelUtil.isAtLeast(Build.VERSION_CODES.P) when the P API level
+        // constant is defined.
+        return ApiLevelUtil.getCodename().compareToIgnoreCase("P") >= 0;
+    }
+
+    /**
+     * Test if ConnectivityManager.getNetworkWatchlistConfigHash() correctly
+     * returns the hash of config we set.
+     */
+    public void testGetWatchlistConfigHash() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        // TODO: Test watchlist config does not exist case
+        // Save test watchlist config to sdcard as app can't access /data/local/tmp
+        saveResourceToFile(TEST_WATCHLIST_XML, SDCARD_CONFIG_PATH);
+        // Copy test watchlist config from sdcard to /data/local/tmp as systerm service
+        // can't access /sdcard
+        runCommand("cp " + SDCARD_CONFIG_PATH + " " + TMP_CONFIG_PATH);
+        // Set test watchlist config to system
+        final String cmdResult = runCommand(
+                "cmd network_watchlist set-test-config " + TMP_CONFIG_PATH).trim();
+        assertTrue(cmdResult.contains("Success"));
+        // Test if watchlist config hash value is correct
+        ConnectivityManager connectivityManager =
+                (ConnectivityManager) getContext().getSystemService(
+                        Context.CONNECTIVITY_SERVICE);
+        byte[] result = connectivityManager.getNetworkWatchlistConfigHash();
+        Assert.assertEquals(TEST_WATCHLIST_CONFIG_HASH, byteArrayToHexString(result));
+    }
+
+    private static String byteArrayToHexString(byte[] bytes) {
+        Formatter formatter = new Formatter();
+        for (byte b : bytes) {
+            formatter.format("%02X", b);
+        }
+        return formatter.toString();
+    }
+
+    private void saveResourceToFile(String res, String filePath) throws IOException {
+        InputStream in = getClass().getClassLoader().getResourceAsStream(res);
+        FileUtils.copyToFileOrThrow(in, new File(filePath));
+    }
+
+    private static String runCommand(String command) throws IOException {
+        return SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(), command);
+    }
+}
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..1d212ca 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
@@ -21,6 +21,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.ConnectivityManager;
+import android.net.MacAddress;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
 import android.net.wifi.WifiManager;
@@ -44,7 +45,6 @@
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.CountDownLatch;
@@ -717,82 +717,14 @@
     }
 
     /**
-     * Request an Aware data-path (open) on a Publish discovery session (which can be done with a
-     * null peer - to accept all requests). Validate that times-out.
-     */
-    public void testDataPathOpenInContextOfDiscoveryFail() {
-        if (!TestUtils.shouldTestWifiAware(getContext())) {
-            return;
-        }
-
-        WifiAwareSession session = attachAndGetSession();
-
-        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
-                "ValidName").build();
-        DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
-        NetworkCallbackTest networkCb = new NetworkCallbackTest();
-
-        // 1. publish
-        session.publish(publishConfig, discoveryCb, mHandler);
-        assertTrue("Publish started",
-                discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
-        PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession();
-        assertNotNull("Publish session", discoverySession);
-
-        // 2. request an AWARE network
-        NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
-                NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier(
-                discoverySession.createNetworkSpecifierOpen(null)).build();
-        mConnectivityManager.requestNetwork(nr, networkCb, 2000);
-        assertTrue("OnUnavailable received", networkCb.waitForOnUnavailable());
-
-        discoverySession.close();
-        session.close();
-    }
-
-    /**
-     * Request an Aware data-path (encrypted) on a Publish discovery session (which can be done
-     * with a null peer - to accept all requests). Validate that times-out.
-     */
-    public void testDataPathPassphraseInContextOfDiscoveryFail() {
-        if (!TestUtils.shouldTestWifiAware(getContext())) {
-            return;
-        }
-
-        WifiAwareSession session = attachAndGetSession();
-
-        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
-                "ValidName").build();
-        DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
-        NetworkCallbackTest networkCb = new NetworkCallbackTest();
-
-        // 1. publish
-        session.publish(publishConfig, discoveryCb, mHandler);
-        assertTrue("Publish started",
-                discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
-        PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession();
-        assertNotNull("Publish session", discoverySession);
-
-        // 2. request an AWARE network
-        NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
-                NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier(
-                discoverySession.createNetworkSpecifierPassphrase(null,
-                        "Some very long but not very good passphrase")).build();
-        mConnectivityManager.requestNetwork(nr, networkCb, 2000);
-        assertTrue("OnUnavailable received", networkCb.waitForOnUnavailable());
-
-        discoverySession.close();
-        session.close();
-    }
-
-    /**
-     * Request an Aware data-path (open) as a Responder with no peer MAC address (i.e. accept any
-     * peer request). Validate that times-out.
+     * Request an Aware data-path (open) as a Responder with an arbitrary peer MAC address. Validate
+     * that times-out.
      */
     public void testDataPathOpenOutOfBandFail() {
         if (!TestUtils.shouldTestWifiAware(getContext())) {
             return;
         }
+        MacAddress mac = MacAddress.fromString("00:01:02:03:04:05");
 
         WifiAwareSession session = attachAndGetSession();
 
@@ -805,7 +737,8 @@
         NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
                 NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier(
                 session.createNetworkSpecifierOpen(
-                        WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER, null)).build();
+                        WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER,
+                        mac.toByteArray())).build();
         mConnectivityManager.requestNetwork(nr, networkCb, 2000);
         assertTrue("OnUnavailable received", networkCb.waitForOnUnavailable());
 
@@ -813,13 +746,14 @@
     }
 
     /**
-     * Request an Aware data-path (encrypted) as a Responder with no peer MAC address (i.e.
-     * accept any peer request). Validate that times-out.
+     * Request an Aware data-path (encrypted) as a Responder with an arbitrary peer MAC address.
+     * Validate that times-out.
      */
     public void testDataPathPassphraseOutOfBandFail() {
         if (!TestUtils.shouldTestWifiAware(getContext())) {
             return;
         }
+        MacAddress mac = MacAddress.fromString("00:01:02:03:04:05");
 
         WifiAwareSession session = attachAndGetSession();
 
@@ -832,7 +766,7 @@
         NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
                 NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier(
                 session.createNetworkSpecifierPassphrase(
-                        WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER, null,
+                        WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER, mac.toByteArray(),
                         "abcdefghihk")).build();
         mConnectivityManager.requestNetwork(nr, networkCb, 2000);
         assertTrue("OnUnavailable received", networkCb.waitForOnUnavailable());