Merge "Modify testNetworkSetupWizardPermission let it fit Factory Ota use case." into qt-dev
diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml
index dbd8fef..44a00ef 100644
--- a/tests/cts/net/AndroidManifest.xml
+++ b/tests/cts/net/AndroidManifest.xml
@@ -16,7 +16,8 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.net.cts">
+ 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" />
@@ -36,12 +37,6 @@
<application android:usesCleartextTraffic="true">
<uses-library android:name="android.test.runner" />
<uses-library android:name="org.apache.http.legacy" android:required="false" />
-
- <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"
diff --git a/tests/cts/net/AndroidTest.xml b/tests/cts/net/AndroidTest.xml
index ff93afc..1807a6b 100644
--- a/tests/cts/net/AndroidTest.xml
+++ b/tests/cts/net/AndroidTest.xml
@@ -16,11 +16,12 @@
<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="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="CtsNetTestCases.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" />
diff --git a/tests/cts/net/api23Test/Android.bp b/tests/cts/net/api23Test/Android.bp
new file mode 100644
index 0000000..48161cf
--- /dev/null
+++ b/tests/cts/net/api23Test/Android.bp
@@ -0,0 +1,51 @@
+// 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.stubs",
+ ],
+
+ srcs: [
+ "src/**/*.java",
+ "src/**/*.kt",
+ ],
+
+ static_libs: [
+ "core-tests-support",
+ "compatibility-device-util-axt",
+ "ctstestrunner-axt",
+ "ctstestserver",
+ "mockwebserver",
+ "junit",
+ "junit-params",
+ "truth-prebuilt",
+ ],
+
+ platform_apis: true,
+
+ // Tag this module as a cts test artifact
+ test_suites: [
+ "cts",
+ "vts",
+ "general-tests",
+ ],
+
+}
diff --git a/tests/cts/net/api23Test/AndroidManifest.xml b/tests/cts/net/api23Test/AndroidManifest.xml
new file mode 100644
index 0000000..8af87f6
--- /dev/null
+++ b/tests/cts/net/api23Test/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?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_WIFI_STATE" />
+ <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+ <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
new file mode 100644
index 0000000..21f28fc
--- /dev/null
+++ b/tests/cts/net/api23Test/AndroidTest.xml
@@ -0,0 +1,30 @@
+<!-- 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="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
new file mode 100644
index 0000000..f38490e
--- /dev/null
+++ b/tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityManagerApi23Test.java
@@ -0,0 +1,399 @@
+/*
+ * 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.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkInfo;
+import android.net.NetworkInfo.State;
+import android.net.NetworkRequest;
+import android.net.wifi.WifiManager;
+import android.os.Looper;
+import android.system.Os;
+import android.system.OsConstants;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.concurrent.CountDownLatch;
+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 String TEST_HOST = "connectivitycheck.gstatic.com";
+ private static final int SOCKET_TIMEOUT_MS = 2000;
+ private static final int SEND_BROADCAST_TIMEOUT = 30000;
+ private static final int HTTP_PORT = 80;
+ // 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 static final String NETWORK_CALLBACK_ACTION =
+ "ConnectivityManagerTest.NetworkCallbackAction";
+ private 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";
+
+ private Context mContext;
+ private ConnectivityManager mCm;
+ private WifiManager mWifiManager;
+ private PackageManager mPackageManager;
+
+ @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);
+ mPackageManager = mContext.getPackageManager();
+ }
+
+ /**
+ * 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();
+
+ 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);
+
+ 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);
+
+ toggleWifi();
+ Intent finalIntent = new Intent(ConnectivityReceiver.FINAL_ACTION);
+ finalIntent.setClass(mContext, ConnectivityReceiver.class);
+ mContext.sendBroadcast(finalIntent);
+
+ assertTrue(ConnectivityReceiver.waitForBroadcast());
+ }
+
+ // Toggle WiFi twice, leaving it in the state it started in
+ private void toggleWifi() {
+ if (mWifiManager.isWifiEnabled()) {
+ Network wifiNetwork = getWifiNetwork();
+ disconnectFromWifi(wifiNetwork);
+ connectToWifi();
+ } else {
+ connectToWifi();
+ Network wifiNetwork = getWifiNetwork();
+ disconnectFromWifi(wifiNetwork);
+ }
+ }
+
+ 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;
+ }
+
+ private 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;
+ }
+
+ /** Disable WiFi and wait for it to become disconnected from the network. */
+ private void disconnectFromWifi(Network wifiNetworkToCheck) {
+ final TestNetworkCallback callback = new TestNetworkCallback();
+ mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback);
+ Network lostWifiNetwork = null;
+
+ ConnectivityActionReceiver receiver = new ConnectivityActionReceiver(
+ ConnectivityManager.TYPE_WIFI, NetworkInfo.State.DISCONNECTED);
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+ mContext.registerReceiver(receiver, filter);
+
+ // Assert that we can establish a TCP connection on wifi.
+ Socket wifiBoundSocket = null;
+ if (wifiNetworkToCheck != null) {
+ try {
+ wifiBoundSocket = getBoundSocket(wifiNetworkToCheck, TEST_HOST, HTTP_PORT);
+ testHttpRequest(wifiBoundSocket);
+ } catch (IOException e) {
+ fail("HTTP request before wifi disconnected failed with: " + e);
+ }
+ }
+
+ boolean disconnected = false;
+ try {
+ assertTrue(mWifiManager.setWifiEnabled(false));
+ // Ensure we get both an onLost callback and a CONNECTIVITY_ACTION.
+ lostWifiNetwork = callback.waitForLost();
+ assertNotNull(lostWifiNetwork);
+ disconnected = receiver.waitForState();
+ } catch (InterruptedException ex) {
+ fail("disconnectFromWifi was interrupted");
+ } finally {
+ mCm.unregisterNetworkCallback(callback);
+ mContext.unregisterReceiver(receiver);
+ }
+
+ assertTrue("Wifi failed to reach DISCONNECTED state.", disconnected);
+
+ // 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());
+ }
+ }
+ }
+
+ /** Enable WiFi and wait for it to become connected to a network. */
+ private Network connectToWifi() {
+ final TestNetworkCallback callback = new TestNetworkCallback();
+ mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback);
+ Network wifiNetwork = null;
+
+ ConnectivityActionReceiver receiver = new ConnectivityActionReceiver(
+ ConnectivityManager.TYPE_WIFI, NetworkInfo.State.CONNECTED);
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+ mContext.registerReceiver(receiver, filter);
+
+ boolean connected = false;
+ try {
+ assertTrue(mWifiManager.setWifiEnabled(true));
+ // Ensure we get both an onAvailable callback and a CONNECTIVITY_ACTION.
+ wifiNetwork = callback.waitForAvailable();
+ assertNotNull(wifiNetwork);
+ connected = receiver.waitForState();
+ } catch (InterruptedException ex) {
+ fail("connectToWifi was interrupted");
+ } finally {
+ mCm.unregisterNetworkCallback(callback);
+ mContext.unregisterReceiver(receiver);
+ }
+
+ assertTrue("Wifi must be configured to connect to an access point for this test.",
+ connected);
+ return wifiNetwork;
+ }
+
+ 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;
+ }
+
+ /**
+ * Receiver that captures the last connectivity change's network type and state. Recognizes
+ * both {@code CONNECTIVITY_ACTION} and {@code NETWORK_CALLBACK_ACTION} intents.
+ */
+ private class ConnectivityActionReceiver extends BroadcastReceiver {
+
+ private final CountDownLatch mReceiveLatch = new CountDownLatch(1);
+
+ private final int mNetworkType;
+ private final NetworkInfo.State mNetState;
+
+ ConnectivityActionReceiver(int networkType, NetworkInfo.State netState) {
+ 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 = 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(30, TimeUnit.SECONDS);
+ }
+ }
+
+ /**
+ * Callback used in testRegisterNetworkCallback that allows caller to block on
+ * {@code onAvailable}.
+ */
+ private 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(30, TimeUnit.SECONDS) ? currentNetwork : null;
+ }
+
+ public Network waitForLost() throws InterruptedException {
+ return mLostLatch.await(30, 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();
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityReceiver.java b/tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityReceiver.java
similarity index 98%
rename from tests/cts/net/src/android/net/cts/ConnectivityReceiver.java
rename to tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityReceiver.java
index 6a7b4a0..9d2b8ad 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityReceiver.java
+++ b/tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityReceiver.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.net.cts;
+package android.net.cts.api23test;
import android.content.BroadcastReceiver;
import android.content.Context;
diff --git a/tests/cts/net/src/android/net/cts/AirplaneModeTest.java b/tests/cts/net/src/android/net/cts/AirplaneModeTest.java
index 0a3146c..524e549 100644
--- a/tests/cts/net/src/android/net/cts/AirplaneModeTest.java
+++ b/tests/cts/net/src/android/net/cts/AirplaneModeTest.java
@@ -18,13 +18,14 @@
import android.content.ContentResolver;
import android.content.Context;
-import android.content.pm.PackageManager;
+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";
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index cb1aa09..c444445 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -35,7 +35,6 @@
import android.app.PendingIntent;
import android.app.UiAutomation;
import android.content.BroadcastReceiver;
-import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -43,6 +42,8 @@
import android.content.pm.PackageManager;
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;
@@ -52,11 +53,13 @@
import android.net.NetworkInfo.State;
import android.net.NetworkRequest;
import android.net.SocketKeepalive;
+import android.net.util.KeepaliveUtils;
import android.net.wifi.WifiManager;
import android.os.Looper;
import android.os.MessageQueue;
import android.os.SystemClock;
import android.os.SystemProperties;
+import android.platform.test.annotations.AppModeFull;
import android.provider.Settings;
import android.system.Os;
import android.system.OsConstants;
@@ -86,6 +89,7 @@
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;
@@ -99,8 +103,6 @@
private static final String TAG = ConnectivityManagerTest.class.getSimpleName();
- private static final String FEATURE_ENABLE_HIPRI = "enableHIPRI";
-
public static final int TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE;
public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI;
@@ -110,7 +112,6 @@
private static final int CONNECT_TIMEOUT_MS = 2000;
private static final int KEEPALIVE_CALLBACK_TIMEOUT_MS = 2000;
private static final int KEEPALIVE_SOCKET_TIMEOUT_MS = 5000;
- private static final int SEND_BROADCAST_TIMEOUT = 30000;
private static final int MIN_KEEPALIVE_INTERVAL = 10;
private static final int NETWORK_CHANGE_METEREDNESS_TIMEOUT = 5000;
private static final int NUM_TRIES_MULTIPATH_PREF_CHECK = 20;
@@ -125,10 +126,6 @@
private static final String NETWORK_CALLBACK_ACTION =
"ConnectivityManagerTest.NetworkCallbackAction";
- // 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";
-
// device could have only one interface: data, wifi.
private static final int MIN_NUM_NETWORK_TYPES = 1;
@@ -294,6 +291,7 @@
* 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")
public void testOpenConnection() throws Exception {
boolean canRunTest = mPackageManager.hasSystemFeature(FEATURE_WIFI)
&& mPackageManager.hasSystemFeature(FEATURE_TELEPHONY);
@@ -456,6 +454,7 @@
* 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")
public void testRegisterNetworkCallback() {
if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
Log.i(TAG, "testRegisterNetworkCallback cannot execute unless device supports WiFi");
@@ -496,6 +495,7 @@
* {@link #testRegisterNetworkCallback} except that a {@code PendingIntent} is used instead
* of a {@code NetworkCallback}.
*/
+ @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
public void testRegisterNetworkCallback_withPendingIntent() {
if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
Log.i(TAG, "testRegisterNetworkCallback cannot execute unless device supports WiFi");
@@ -540,6 +540,7 @@
* 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")
public void testRequestNetworkCallback() {
final TestNetworkCallback callback = new TestNetworkCallback();
mCm.requestNetwork(new NetworkRequest.Builder()
@@ -562,6 +563,7 @@
* 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")
public void testRequestNetworkCallback_onUnavailable() {
final boolean previousWifiEnabledState = mWifiManager.isWifiEnabled();
if (previousWifiEnabledState) {
@@ -587,93 +589,6 @@
}
}
- /**
- * 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();
-
- 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_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);
-
- toggleWifi();
- Intent finalIntent = new Intent(ConnectivityReceiver.FINAL_ACTION);
- finalIntent.setClass(mContext, ConnectivityReceiver.class);
- mContext.sendBroadcast(finalIntent);
-
- assertTrue(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);
-
- toggleWifi();
-
- Intent getConnectivityCount = new Intent(GET_WIFI_CONNECTIVITY_ACTION_COUNT);
- assertEquals(2, sendOrderedBroadcastAndReturnResultCode(
- getConnectivityCount, SEND_BROADCAST_TIMEOUT));
- }
-
- 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;
- }
-
- // Toggle WiFi twice, leaving it in the state it started in
- private 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. */
private Network connectToWifi() {
final TestNetworkCallback callback = new TestNetworkCallback();
@@ -705,6 +620,16 @@
return wifiNetwork;
}
+ private InetAddress getFirstV4Address(Network network) {
+ LinkProperties linkProperties = mCm.getLinkProperties(network);
+ for (InetAddress address : linkProperties.getAddresses()) {
+ if (address instanceof Inet4Address) {
+ return address;
+ }
+ }
+ return null;
+ }
+
private Socket getBoundSocket(Network network, String host, int port) throws IOException {
InetSocketAddress addr = new InetSocketAddress(host, port);
Socket s = network.getSocketFactory().createSocket();
@@ -899,6 +824,7 @@
}
/** Verify restricted networks cannot be requested. */
+ @AppModeFull(reason = "CHANGE_NETWORK_STATE permission can't be granted to instant apps")
public void testRestrictedNetworks() {
// Verify we can request unrestricted networks:
NetworkRequest request = new NetworkRequest.Builder()
@@ -1016,6 +942,7 @@
* Verify that getMultipathPreference does return appropriate values
* for metered and unmetered networks.
*/
+ @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
public void testGetMultipathPreference() throws Exception {
final ContentResolver resolver = mContext.getContentResolver();
final Network network = ensureWifiConnected();
@@ -1171,6 +1098,16 @@
return s;
}
+ private int getSupportedKeepalivesFromRes() throws Exception {
+ final Network network = ensureWifiConnected();
+ 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 boolean isKeepaliveSupported() throws Exception {
final Network network = ensureWifiConnected();
final Executor executor = mContext.getMainExecutor();
@@ -1207,6 +1144,7 @@
}
}
+ @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
public void testCreateTcpKeepalive() throws Exception {
adoptShellPermissionIdentity();
@@ -1278,4 +1216,150 @@
}
}
+
+ private int createConcurrentSocketKeepalives(int nattCount, int tcpCount) throws Exception {
+ // Use customization value in resource to prevent the need of privilege.
+ if (getSupportedKeepalivesFromRes() == 0) return 0;
+
+ final Network network = ensureWifiConnected();
+
+ final ArrayList<SocketKeepalive> kalist = new ArrayList<>();
+ final TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback();
+ final Executor executor = mContext.getMainExecutor();
+
+ // Create concurrent TCP keepalives.
+ for (int i = 0; i < tcpCount; i++) {
+ // Assert that TCP connections can be established on wifi. The file descriptor of tcp
+ // sockets will be duplicated and kept valid in service side if the keepalives are
+ // successfully started.
+ try (Socket tcpSocket = getConnectedSocket(network, TEST_HOST, HTTP_PORT,
+ 0 /* Unused */, AF_INET)) {
+ final SocketKeepalive ka = mCm.createSocketKeepalive(network, tcpSocket, executor,
+ callback);
+ ka.start(MIN_KEEPALIVE_INTERVAL);
+ TestSocketKeepaliveCallback.CallbackValue cv = callback.pollCallback();
+ assertNotNull(cv);
+ if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_ERROR
+ && cv.error == SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES) {
+ // Limit reached.
+ break;
+ }
+ if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_STARTED) {
+ kalist.add(ka);
+ } else {
+ fail("Unexpected error when creating " + (i + 1) + " TCP keepalives: " + cv);
+ }
+ }
+ }
+
+ // Assert that a Nat-T socket can be created.
+ final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE);
+ final UdpEncapsulationSocket nattSocket = mIpSec.openUdpEncapsulationSocket();
+
+ final InetAddress srcAddr = getFirstV4Address(network);
+ final InetAddress dstAddr = getAddrByName(TEST_HOST, AF_INET);
+ assertNotNull(srcAddr);
+ assertNotNull(dstAddr);
+
+ // Test concurrent Nat-T keepalives.
+ for (int i = 0; i < nattCount; i++) {
+ final SocketKeepalive ka = mCm.createSocketKeepalive(network, nattSocket,
+ srcAddr, dstAddr, executor, callback);
+ ka.start(MIN_KEEPALIVE_INTERVAL);
+ TestSocketKeepaliveCallback.CallbackValue cv = callback.pollCallback();
+ assertNotNull(cv);
+ if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_ERROR
+ && cv.error == SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES) {
+ // Limit reached.
+ break;
+ }
+ if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_STARTED) {
+ kalist.add(ka);
+ } else {
+ fail("Unexpected error when creating " + (i + 1) + " Nat-T keepalives: " + cv);
+ }
+ }
+
+ final int ret = kalist.size();
+
+ // Clean up.
+ for (final SocketKeepalive ka : kalist) {
+ ka.stop();
+ callback.expectStopped();
+ }
+ kalist.clear();
+ nattSocket.close();
+
+ 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")
+ public void testSocketKeepaliveLimit() throws Exception {
+ adoptShellPermissionIdentity();
+
+ final int supported = getSupportedKeepalivesFromRes();
+
+ if (!isKeepaliveSupported()) {
+ // Sanity check.
+ assertEquals(0, supported);
+ return;
+ }
+
+ // Verifies that the supported keepalive slots meet MIN_SUPPORTED_KEEPALIVE_COUNT.
+ assertGreaterOrEqual(supported, KeepaliveUtils.MIN_SUPPORTED_KEEPALIVE_COUNT);
+
+ // Verifies that different types of keepalives can be established.
+ assertEquals(supported, createConcurrentSocketKeepalives(supported + 1, 0));
+ assertEquals(supported, createConcurrentSocketKeepalives(0, supported + 1));
+
+ // Verifies that different types can be established at the same time.
+ assertEquals(supported, createConcurrentSocketKeepalives(
+ supported / 2, supported - supported / 2));
+
+ // Verifies that keepalives don't get leaked in second round.
+ assertEquals(supported, createConcurrentSocketKeepalives(supported + 1, 0));
+ assertEquals(supported, createConcurrentSocketKeepalives(0, supported + 1));
+ assertEquals(supported, createConcurrentSocketKeepalives(
+ supported / 2, supported - supported / 2));
+
+ dropShellPermissionIdentity();
+ }
+
+ /**
+ * Verifies that the keepalive slots are limited as customized for unprivileged requests.
+ */
+ @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
+ public void testSocketKeepaliveUnprivileged() throws Exception {
+ final int supported = getSupportedKeepalivesFromRes();
+
+ adoptShellPermissionIdentity();
+ if (!isKeepaliveSupported()) {
+ // Sanity check.
+ assertEquals(0, supported);
+ return;
+ }
+ dropShellPermissionIdentity();
+
+ final int allowedUnprivilegedPerUid = mContext.getResources().getInteger(
+ R.integer.config_allowedUnprivilegedKeepalivePerUid);
+ final int reservedPrivilegedSlots = mContext.getResources().getInteger(
+ R.integer.config_reservedPrivilegedKeepaliveSlots);
+ // 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(supported + 1, 0));
+ }
+
+ private static void assertGreaterOrEqual(long greater, long lesser) {
+ assertTrue("" + greater + " expected to be greater than or equal to " + lesser,
+ greater >= lesser);
+ }
}
diff --git a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java
index 858891f..26049cc 100644
--- a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java
+++ b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java
@@ -23,6 +23,7 @@
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;
@@ -479,6 +480,7 @@
}
@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);
@@ -490,6 +492,7 @@
}
@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);
@@ -502,6 +505,7 @@
}
@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);
@@ -514,6 +518,7 @@
}
@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);
@@ -526,6 +531,7 @@
}
@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);
@@ -538,6 +544,7 @@
}
@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);
diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java
index 8d5a068..1241785 100644
--- a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java
@@ -26,6 +26,7 @@
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;
@@ -35,6 +36,7 @@
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;
@@ -54,6 +56,7 @@
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();
diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java
index 9c94dc9..93638ac 100644
--- a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java
+++ b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java
@@ -39,7 +39,6 @@
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.app.AppOpsManager;
@@ -56,8 +55,10 @@
import android.net.TestNetworkManager;
import android.net.cts.PacketUtils.Payload;
import android.os.Binder;
+import android.os.Build;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
+import android.os.SystemProperties;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
@@ -67,9 +68,7 @@
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
-import java.net.InterfaceAddress;
import java.net.NetworkInterface;
-import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
@@ -169,7 +168,9 @@
}
private static boolean hasTunnelsFeature() {
- return sContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS);
+ return sContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
+ || SystemProperties.getInt("ro.product.first_api_level", 0)
+ >= Build.VERSION_CODES.Q;
}
private static void setAppop(int appop, boolean allow) {
@@ -508,11 +509,10 @@
NetworkInterface netIntf = NetworkInterface.getByName(tunnelIntf.getInterfaceName());
assertNotNull(netIntf);
- // Check addresses
- List<InterfaceAddress> intfAddrs = netIntf.getInterfaceAddresses();
- assertEquals(1, intfAddrs.size());
- assertEquals(localInner, intfAddrs.get(0).getAddress());
- assertEquals(innerPrefixLen, intfAddrs.get(0).getNetworkPrefixLength());
+ // Verify address was added
+ netIntf = NetworkInterface.getByInetAddress(localInner);
+ assertNotNull(netIntf);
+ assertEquals(tunnelIntf.getInterfaceName(), netIntf.getDisplayName());
// Configure Transform parameters
IpSecTransform.Builder transformBuilder = new IpSecTransform.Builder(sContext);
@@ -540,15 +540,14 @@
// Teardown the test network
sTNM.teardownTestNetwork(testNetwork);
- // Remove addresses and check
+ // Remove addresses and check that interface is still present, but fails lookup-by-addr
tunnelIntf.removeAddress(localInner, innerPrefixLen);
- netIntf = NetworkInterface.getByName(tunnelIntf.getInterfaceName());
- assertTrue(netIntf.getInterfaceAddresses().isEmpty());
+ assertNotNull(NetworkInterface.getByName(tunnelIntf.getInterfaceName()));
+ assertNull(NetworkInterface.getByInetAddress(localInner));
// Check interface was cleaned up
tunnelIntf.close();
- netIntf = NetworkInterface.getByName(tunnelIntf.getInterfaceName());
- assertNull(netIntf);
+ assertNull(NetworkInterface.getByName(tunnelIntf.getInterfaceName()));
} finally {
if (testNetworkCb != null) {
sCM.unregisterNetworkCallback(testNetworkCb);
diff --git a/tests/cts/net/src/android/net/cts/NetworkWatchlistTest.java b/tests/cts/net/src/android/net/cts/NetworkWatchlistTest.java
index e0c03a1..cb0cda8 100644
--- a/tests/cts/net/src/android/net/cts/NetworkWatchlistTest.java
+++ b/tests/cts/net/src/android/net/cts/NetworkWatchlistTest.java
@@ -23,6 +23,7 @@
import android.content.Context;
import android.net.ConnectivityManager;
+import android.platform.test.annotations.AppModeFull;
import android.os.FileUtils;
import androidx.test.InstrumentationRegistry;
@@ -99,6 +100,7 @@
* 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);
diff --git a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java
index 60ac226..5250450 100644
--- a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java
+++ b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java
@@ -24,6 +24,7 @@
import javax.net.ssl.SSLPeerUnverifiedException;
import android.net.SSLCertificateSocketFactory;
+import android.platform.test.annotations.AppModeFull;
import android.test.AndroidTestCase;
import libcore.javax.net.ssl.SSLConfigurationAsserts;
@@ -101,6 +102,7 @@
*
* NOTE: Test will fail if external server is not available.
*/
+ @AppModeFull(reason = "Socket cannot bind in instant app mode")
public void test_createSocket_simple() throws Exception {
try {
mFactory.createSocket(TEST_CREATE_SOCKET_HOST, TEST_CREATE_SOCKET_PORT);
@@ -117,6 +119,7 @@
*
* NOTE: Test will fail if external server is not available.
*/
+ @AppModeFull(reason = "Socket cannot bind in instant app mode")
public void test_createSocket_wrapping() throws Exception {
try {
Socket underlying = new Socket(TEST_CREATE_SOCKET_HOST, TEST_CREATE_SOCKET_PORT);
@@ -135,6 +138,7 @@
*
* NOTE: Test will fail if external server is not available.
*/
+ @AppModeFull(reason = "Socket cannot bind in instant app mode")
public void test_createSocket_bind() throws Exception {
try {
mFactory.createSocket(TEST_CREATE_SOCKET_HOST, TEST_CREATE_SOCKET_PORT, null, 0);
diff --git a/tests/cts/net/src/android/net/cts/TheaterModeTest.java b/tests/cts/net/src/android/net/cts/TheaterModeTest.java
index 10fca6f..d1ddeaa 100644
--- a/tests/cts/net/src/android/net/cts/TheaterModeTest.java
+++ b/tests/cts/net/src/android/net/cts/TheaterModeTest.java
@@ -18,12 +18,11 @@
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;
-
public class TheaterModeTest extends AndroidTestCase {
private static final String TAG = "TheaterModeTest";
private static final String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
@@ -40,6 +39,7 @@
|| mContext.getPackageManager().hasSystemFeature(FEATURE_WIFI));
}
+ @AppModeFull(reason = "WRITE_SECURE_SETTINGS permission can't be granted to instant apps")
public void testTheaterMode() {
setup();
if (!mHasFeature) {
diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java
index 503ba51..5bd1e20 100755
--- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java
+++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java
@@ -21,6 +21,7 @@
import android.net.TrafficStats;
import android.os.Process;
import android.os.SystemProperties;
+import android.platform.test.annotations.AppModeFull;
import android.test.AndroidTestCase;
import android.util.Log;
@@ -81,6 +82,7 @@
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();
diff --git a/tests/cts/net/src/android/net/cts/VpnServiceTest.java b/tests/cts/net/src/android/net/cts/VpnServiceTest.java
index 8bdd7b0..15af23c 100644
--- a/tests/cts/net/src/android/net/cts/VpnServiceTest.java
+++ b/tests/cts/net/src/android/net/cts/VpnServiceTest.java
@@ -18,6 +18,7 @@
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;
@@ -35,6 +36,7 @@
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);
@@ -60,6 +62,7 @@
}
}
+ @AppModeFull(reason = "Socket cannot bind in instant app mode")
public void testProtect_DatagramSocket() throws Exception {
DatagramSocket socket = new DatagramSocket();
try {
@@ -88,6 +91,7 @@
}
}
+ @AppModeFull(reason = "Socket cannot bind in instant app mode")
public void testProtect_int() throws Exception {
DatagramSocket socket = new DatagramSocket();
ParcelFileDescriptor descriptor = ParcelFileDescriptor.fromDatagramSocket(socket);
diff --git a/tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java b/tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java
index 2e5306d..8d7dff0 100644
--- a/tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java
+++ b/tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java
@@ -22,6 +22,7 @@
import org.apache.http.impl.client.DefaultHttpClient;
import android.net.Uri;
+import android.platform.test.annotations.AppModeFull;
import android.test.AndroidTestCase;
import android.webkit.cts.CtsTestServer;
@@ -30,6 +31,7 @@
import java.util.ArrayList;
import java.util.List;
+@AppModeFull(reason = "Socket cannot bind in instant app mode")
public class ApacheHttpClientTest extends AndroidTestCase {
private static final int NUM_DOWNLOADS = 20;
diff --git a/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java b/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java
index 198f973..354954e 100644
--- a/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java
+++ b/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java
@@ -22,6 +22,7 @@
import junit.framework.TestCase;
import android.net.http.HttpResponseCache;
+import android.platform.test.annotations.AppModeFull;
import com.android.compatibility.common.util.FileUtils;
@@ -126,6 +127,7 @@
* Make sure that statistics tracking are wired all the way through the
* wrapper class. http://code.google.com/p/android/issues/detail?id=25418
*/
+ @AppModeFull(reason = "Socket cannot bind in instant app mode")
public void testStatisticsTracking() throws Exception {
HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
diff --git a/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java b/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java
index f06d7e9..1bd7fad 100644
--- a/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java
+++ b/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java
@@ -21,13 +21,14 @@
import android.net.rtp.AudioGroup;
import android.net.rtp.AudioStream;
import android.net.rtp.RtpStream;
+import android.platform.test.annotations.AppModeFull;
import android.test.AndroidTestCase;
-import android.util.Log;
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();
diff --git a/tests/cts/net/src/android/net/rtp/cts/AudioStreamTest.java b/tests/cts/net/src/android/net/rtp/cts/AudioStreamTest.java
index 323b022..f2db6ee 100644
--- a/tests/cts/net/src/android/net/rtp/cts/AudioStreamTest.java
+++ b/tests/cts/net/src/android/net/rtp/cts/AudioStreamTest.java
@@ -17,10 +17,12 @@
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 {
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 389621e..1901f02 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
@@ -40,6 +40,7 @@
import android.os.Handler;
import android.os.HandlerThread;
import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
import android.test.AndroidTestCase;
import com.android.compatibility.common.util.SystemUtil;
@@ -56,6 +57,7 @@
* Wi-Fi Aware CTS test suite: single device testing. Performs tests on a single
* device to validate Wi-Fi Aware.
*/
+@AppModeFull(reason = "Cannot get WifiAwareManager in instant app mode")
public class SingleDeviceTest extends AndroidTestCase {
private static final String TAG = "WifiAwareCtsTests";
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 c80e372..628571c 100644
--- a/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java
@@ -32,6 +32,7 @@
import android.net.wifi.WifiManager;
import android.net.wifi.p2p.WifiP2pManager;
import android.provider.Settings;
+import android.platform.test.annotations.AppModeFull;
import android.test.AndroidTestCase;
import android.util.Log;
@@ -45,6 +46,7 @@
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
+@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
public class ConcurrencyTest extends AndroidTestCase {
private class MySync {
static final int WIFI_STATE = 0;
diff --git a/tests/cts/net/src/android/net/wifi/cts/MulticastLockTest.java b/tests/cts/net/src/android/net/wifi/cts/MulticastLockTest.java
index 54fe9c7..71f04a3 100644
--- a/tests/cts/net/src/android/net/wifi/cts/MulticastLockTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/MulticastLockTest.java
@@ -19,8 +19,10 @@
import android.content.Context;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.MulticastLock;
+import android.platform.test.annotations.AppModeFull;
import android.test.AndroidTestCase;
+@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
public class MulticastLockTest extends AndroidTestCase {
private static final String WIFI_TAG = "MulticastLockTest";
diff --git a/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java
index 2e2e75b..f2a2b48 100644
--- a/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.net.nsd.NsdManager;
import android.net.nsd.NsdServiceInfo;
+import android.platform.test.annotations.AppModeFull;
import android.test.AndroidTestCase;
import android.util.Log;
@@ -29,6 +30,7 @@
import java.util.List;
import java.util.ArrayList;
+@AppModeFull(reason = "Socket cannot bind in instant app mode")
public class NsdManagerTest extends AndroidTestCase {
private static final String TAG = "NsdManagerTest";
diff --git a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java
index 836df61..ccf5fe2 100644
--- a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java
@@ -25,11 +25,13 @@
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
+import android.platform.test.annotations.AppModeFull;
import android.test.AndroidTestCase;
import android.util.Log;
import com.android.compatibility.common.util.SystemUtil;
+@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
public class ScanResultTest extends AndroidTestCase {
private static class MySync {
int expectedState = STATE_NULL;
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..a59c85e 100644
--- a/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java
@@ -21,8 +21,10 @@
import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
+import android.platform.test.annotations.AppModeFull;
import android.test.AndroidTestCase;
+@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
public class WifiConfigurationTest extends AndroidTestCase {
private WifiManager mWifiManager;
@Override
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
index 0fce1ee..b592c10 100644
--- a/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
@@ -22,6 +22,7 @@
import android.net.wifi.WifiEnterpriseConfig.Eap;
import android.net.wifi.WifiEnterpriseConfig.Phase2;
import android.net.wifi.WifiManager;
+import android.platform.test.annotations.AppModeFull;
import android.test.AndroidTestCase;
import com.android.compatibility.common.util.SystemUtil;
@@ -33,6 +34,7 @@
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
+@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
public class WifiEnterpriseConfigTest extends AndroidTestCase {
private WifiManager mWifiManager;
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 77598ed..5367722 100644
--- a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java
@@ -26,6 +26,7 @@
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
import android.net.wifi.WifiSsid;
+import android.platform.test.annotations.AppModeFull;
import android.test.AndroidTestCase;
import com.android.compatibility.common.util.PollingCheck;
@@ -33,6 +34,7 @@
import java.util.concurrent.Callable;
+@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
public class WifiInfoTest extends AndroidTestCase {
private static class MySync {
int expectedState = STATE_NULL;
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiLockTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiLockTest.java
index 0703e60..6ac92d4 100644
--- a/tests/cts/net/src/android/net/wifi/cts/WifiLockTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/WifiLockTest.java
@@ -19,8 +19,10 @@
import android.content.Context;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
+import android.platform.test.annotations.AppModeFull;
import android.test.AndroidTestCase;
+@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
public class WifiLockTest extends AndroidTestCase {
private static final String WIFI_TAG = "WifiLockTest";
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 331e834..d8c7dc8 100644
--- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -36,6 +36,7 @@
import android.net.wifi.hotspot2.pps.HomeSp;
import android.os.Process;
import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
import android.provider.Settings;
import android.support.test.uiautomator.UiDevice;
import android.test.AndroidTestCase;
@@ -57,6 +58,7 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
+@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
public class WifiManagerTest extends AndroidTestCase {
private static class MySync {
int expectedState = STATE_NULL;
diff --git a/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java b/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java
index 20791c0..f71cadb 100644
--- a/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java
+++ b/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java
@@ -19,6 +19,7 @@
import android.net.wifi.ScanResult;
import android.net.wifi.rtt.RangingRequest;
import android.net.wifi.rtt.RangingResult;
+import android.platform.test.annotations.AppModeFull;
import com.android.compatibility.common.util.DeviceReportLog;
import com.android.compatibility.common.util.ResultType;
@@ -31,6 +32,7 @@
/**
* Wi-Fi RTT CTS test: range to all available Access Points which support IEEE 802.11mc.
*/
+@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
public class WifiRttTest extends TestBase {
// Number of scans to do while searching for APs supporting IEEE 802.11mc
private static final int NUM_SCANS_SEARCHING_FOR_IEEE80211MC_AP = 2;