Merge "Toggle wifi when running CaptivePortalTest"
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java
index f3cd8a9..aa59959 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java
@@ -83,6 +83,7 @@
}
private class TestNetworkCallback extends INetworkCallback.Stub {
+ private static final int TEST_CONNECT_TIMEOUT_MS = 30_000;
private static final int TEST_CALLBACK_TIMEOUT_MS = 5_000;
private final LinkedBlockingQueue<CallbackInfo> mCallbacks = new LinkedBlockingQueue<>();
@@ -131,7 +132,7 @@
}
public Network expectAvailableCallbackAndGetNetwork() {
- final CallbackInfo cb = nextCallback(TEST_CALLBACK_TIMEOUT_MS);
+ final CallbackInfo cb = nextCallback(TEST_CONNECT_TIMEOUT_MS);
if (cb.state != CallbackState.AVAILABLE) {
fail("Network is not available. Instead obtained the following callback :"
+ cb);
diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp
index 82b7413..052ab26 100644
--- a/tests/cts/net/Android.bp
+++ b/tests/cts/net/Android.bp
@@ -82,6 +82,7 @@
min_sdk_version: "29",
target_sdk_version: "29",
test_suites: [
+ "device-tests",
"mts",
],
test_config_template: "AndroidTestTemplate.xml",
diff --git a/tests/cts/net/TEST_MAPPING b/tests/cts/net/TEST_MAPPING
new file mode 100644
index 0000000..e2a9c75
--- /dev/null
+++ b/tests/cts/net/TEST_MAPPING
@@ -0,0 +1,13 @@
+{
+ // TODO: move to mainline-presubmit once supported
+ "postsubmit": [
+ {
+ "name": "CtsNetTestCasesLatestSdk",
+ "options": [
+ {
+ "exclude-annotation": "com.android.testutils.SkipPresubmit"
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java
index 0509fc0..13f953a 100644
--- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java
+++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java
@@ -18,13 +18,14 @@
import static android.app.AppOpsManager.OP_MANAGE_IPSEC_TUNNELS;
import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_INTERNAL_ADDRESS_FAILURE;
import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN;
+import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_TS_UNACCEPTABLE;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import android.net.LinkAddress;
+import android.net.ipsec.ike.ChildSessionParams;
import android.net.ipsec.ike.IkeFqdnIdentification;
import android.net.ipsec.ike.IkeSession;
import android.net.ipsec.ike.IkeSessionParams;
@@ -84,7 +85,15 @@
+ "9352D71100777B00ABCC6BD7DBEA697827FFAAA48DF9A54D1D68161939F5DC8"
+ "6743A7CEB2BE34AC00095A5B8";
- private IkeSession openIkeSessionWithRemoteAddress(InetAddress remoteAddress) {
+ private IkeSession openIkeSessionWithTunnelModeChild(InetAddress remoteAddress) {
+ return openIkeSession(remoteAddress, buildTunnelModeChildSessionParams());
+ }
+
+ private IkeSession openIkeSessionWithTransportModeChild(InetAddress remoteAddress) {
+ return openIkeSession(remoteAddress, buildTransportModeChildParamsWithDefaultTs());
+ }
+
+ private IkeSession openIkeSession(InetAddress remoteAddress, ChildSessionParams childParams) {
IkeSessionParams ikeParams =
new IkeSessionParams.Builder(sContext)
.setNetwork(mTunNetwork)
@@ -98,7 +107,7 @@
return new IkeSession(
sContext,
ikeParams,
- buildTunnelModeChildSessionParams(),
+ childParams,
mUserCbExecutor,
mIkeSessionCallback,
mFirstChildSessionCallback);
@@ -124,7 +133,7 @@
if (!hasTunnelsFeature()) return;
// Open IKE Session
- IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
+ IkeSession ikeSession = openIkeSessionWithTunnelModeChild(mRemoteAddress);
performSetupIkeAndFirstChildBlocking(SUCCESS_IKE_INIT_RESP, SUCCESS_IKE_AUTH_RESP);
// IKE INIT and IKE AUTH takes two exchanges. Message ID starts from 2
@@ -222,7 +231,7 @@
setUpTestNetwork(mLocalAddress);
// Open IKE Session
- IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
+ IkeSession ikeSession = openIkeSessionWithTunnelModeChild(mRemoteAddress);
performSetupIkeAndFirstChildBlocking(
ikeInitResp,
1 /* expectedAuthReqPktCnt */,
@@ -258,7 +267,7 @@
if (!hasTunnelsFeature()) return;
// Open IKE Session
- IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
+ IkeSession ikeSession = openIkeSessionWithTunnelModeChild(mRemoteAddress);
performSetupIkeAndFirstChildBlocking(SUCCESS_IKE_INIT_RESP, SUCCESS_IKE_AUTH_RESP);
ikeSession.kill();
@@ -272,7 +281,7 @@
"46B8ECA1E0D72A180000000000000000292022200000000000000024000000080000000E";
// Open IKE Session
- IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
+ IkeSession ikeSession = openIkeSessionWithTransportModeChild(mRemoteAddress);
int expectedMsgId = 0;
mTunUtils.awaitReqAndInjectResp(
IKE_DETERMINISTIC_INITIATOR_SPI,
@@ -309,7 +318,7 @@
+ "AB6E4808BAC0CA1DAD6ADD0A126A41BD";
// Open IKE Session
- IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
+ IkeSession ikeSession = openIkeSessionWithTransportModeChild(mRemoteAddress);
performSetupIkeAndFirstChildBlocking(ikeInitRespHex, ikeAuthFailRespHex);
mFirstChildSessionCallback.awaitOnClosed();
@@ -322,27 +331,28 @@
@Test
public void testIkeAuthHandlesFirstChildCreationFail() throws Exception {
final String ikeInitRespHex =
- "46B8ECA1E0D72A182B300285DA19E6452120222000000000000001502200"
- + "00300000002C010100040300000C0100000C800E01000300000803000005"
- + "0300000802000004000000080400000228000088000200005C9DE629981F"
- + "DB1FC45DB6CCF15D076C1F51BD9F63C771DC089F05CCDE6247965D15C616"
- + "C7B5A62342491715E4D1FEA19326477D24143E8E56AB6AD93F54B19BC32A"
- + "44BC0A5B5632E57D0A3C43E466E1547D8E4EF65EA4B864A348161666E229"
- + "84975A486251A17C4F096A6D5CF3DB83874B70324A31AA7ADDE2D73BADD8"
- + "238029000024CF06260F7C4923295E7C91F2B8479212892DA7A519A0322F"
- + "F5B2BF570B92972B2900001C00004004C7ACC2C7D58CF8C9F5E953993AF4"
- + "6CAC976635B42900001C00004005B64B190DFE7BDE8B9B1475EDE67B63D6"
- + "F1DBBF44290000080000402E290000100000402F00020003000400050000"
+ "46B8ECA1E0D72A18F5ABBF896A1240BE2120222000000000000001502200"
+ + "00300000002C010100040300000C0100000C800E0100030000080300000C"
+ + "03000008020000050000000804000002280000880002000074950F016B85"
+ + "605E57E24651843AB70E41B552EDEE227DFE51E6CBEC00E75FFEFC7D5453"
+ + "109B15F721FCD811FC9F113BE06050882F2FC5F5FF25857E555CCFB5AB64"
+ + "8B0D1D7A819A3B05DE1FE89A4A627C60D5AA06CD0F66ACD3748722F9CD4F"
+ + "F30AE7477CBC12049821F07AD6C9F0ED732321A6A36FA817722E025AC34B"
+ + "ABE62900002432E3807F595070E95EDA341A787599B24B1151B535B0222B"
+ + "65C003401B9B38F82900001C000040043BB760DB3037B51768DFFAB4B21D"
+ + "B1716EA1C1382900001C0000400531098EB04DF1BE3F304606BD59B454A8"
+ + "CC7E7311290000080000402E290000100000402F00020003000400050000"
+ "000800004014";
final String ikeAuthCreateChildFailHex =
- "46B8ECA1E0D72A182B300285DA19E6452E202320000000010000008C2400"
- + "0070386FC9CCC67495A17915D0544390A2963A769F4A42C6FA668CEEC07F"
- + "EC0C87D681DE34267023DD394F1401B5A563E71002C0CE0928D0ABC0C4570"
- + "E39C2EDEF820F870AB71BD70A3F3EB5C96CA294B6D3F01677690DCF9F8CFC"
- + "9584650957573502BA83E32F18207A9ADEB1FA";
+ "46B8ECA1E0D72A18F5ABBF896A1240BE2E20232000000001000000B02400"
+ + "009400B0861242E0C88ECB3848D772B560CAD65B6AC9DFFDC8622A394B8E"
+ + "64E550BDD69FCD7E768129787ED9062992C1D6DB0F0631C2E05765B403CF"
+ + "EF1D0A055B32F6698FF7DB5B8FB1B6A83A81634D00E22C86E35B3BFBEC73"
+ + "EAC6806678926945BC7A57003DC1A3528A1EC423EE56C1075B36C0B57A6B"
+ + "C6DD990182F6FABFFA167D199C7D629E5B830AAD2AFBD31CEBA6";
// Open IKE Session
- IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
+ IkeSession ikeSession = openIkeSessionWithTransportModeChild(mRemoteAddress);
performSetupIkeAndFirstChildBlocking(ikeInitRespHex, ikeAuthCreateChildFailHex);
// Even though the child creation failed, the authentication succeeded, so the IKE Session's
@@ -352,7 +362,7 @@
// Verify Child Creation failed
IkeProtocolException protocolException =
(IkeProtocolException) mFirstChildSessionCallback.awaitOnClosedException();
- assertEquals(ERROR_TYPE_INTERNAL_ADDRESS_FAILURE, protocolException.getErrorType());
+ assertEquals(ERROR_TYPE_TS_UNACCEPTABLE, protocolException.getErrorType());
assertArrayEquals(EXPECTED_PROTOCOL_ERROR_DATA_NONE, protocolException.getErrorData());
ikeSession.kill();
diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java
index 2458b25..a81063b 100644
--- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java
+++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java
@@ -276,6 +276,13 @@
.build();
}
+ TransportModeChildSessionParams buildTransportModeChildParamsWithDefaultTs() {
+ return new TransportModeChildSessionParams.Builder()
+ .addSaProposal(SaProposalTest.buildChildSaProposalWithCombinedModeCipher())
+ .addSaProposal(SaProposalTest.buildChildSaProposalWithNormalModeCipher())
+ .build();
+ }
+
TunnelModeChildSessionParams buildTunnelModeChildSessionParams() {
return new TunnelModeChildSessionParams.Builder()
.addSaProposal(SaProposalTest.buildChildSaProposalWithNormalModeCipher())
diff --git a/tests/cts/net/src/android/net/cts/CaptivePortalApiTest.kt b/tests/cts/net/src/android/net/cts/CaptivePortalApiTest.kt
index 40d0ca6..68d5281 100644
--- a/tests/cts/net/src/android/net/cts/CaptivePortalApiTest.kt
+++ b/tests/cts/net/src/android/net/cts/CaptivePortalApiTest.kt
@@ -61,7 +61,6 @@
import java.net.Inet4Address
import java.util.concurrent.ArrayBlockingQueue
import java.util.concurrent.TimeUnit
-import kotlin.reflect.KClass
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertTrue
@@ -90,7 +89,7 @@
private val eth by lazy { context.assertHasService(EthernetManager::class.java) }
private val cm by lazy { context.assertHasService(ConnectivityManager::class.java) }
- private val handlerThread = HandlerThread(CaptivePortalApiTest::class.simpleName)
+ private val handlerThread = HandlerThread(CaptivePortalApiTest::class.java.simpleName)
private val serverIpAddr = InetAddresses.parseNumericAddress("192.0.2.222") as Inet4Address
private val clientIpAddr = InetAddresses.parseNumericAddress("192.0.2.111") as Inet4Address
private val httpServer = HttpServer()
@@ -155,11 +154,11 @@
fun testApiCallbacks() {
// Handle the DHCP handshake that includes the capport API URL
val discover = reader.assertDhcpPacketReceived(
- DhcpDiscoverPacket::class, TEST_TIMEOUT_MS, DHCP_MESSAGE_TYPE_DISCOVER)
+ DhcpDiscoverPacket::class.java, TEST_TIMEOUT_MS, DHCP_MESSAGE_TYPE_DISCOVER)
reader.sendResponse(makeOfferPacket(discover.clientMac, discover.transactionId))
val request = reader.assertDhcpPacketReceived(
- DhcpRequestPacket::class, TEST_TIMEOUT_MS, DHCP_MESSAGE_TYPE_REQUEST)
+ DhcpRequestPacket::class.java, TEST_TIMEOUT_MS, DHCP_MESSAGE_TYPE_REQUEST)
assertEquals(discover.transactionId, request.transactionId)
assertEquals(clientIpAddr, request.mRequestedIp)
reader.sendResponse(makeAckPacket(request.clientMac, request.transactionId))
@@ -244,7 +243,7 @@
}
private fun <T : DhcpPacket> TapPacketReader.assertDhcpPacketReceived(
- packetType: KClass<T>,
+ packetType: Class<T>,
timeoutMs: Long,
type: Byte
): T {
@@ -254,7 +253,7 @@
val packet = DhcpPacket.decodeFullPacket(packetBytes, packetBytes.size, DhcpPacket.ENCAP_L2)
assertTrue(packetType.isInstance(packet),
"Expected ${packetType.simpleName} but got ${packet.javaClass.simpleName}")
- return packetType.java.cast(packet)
+ return packetType.cast(packet)
}
private fun <T> Context.assertHasService(manager: Class<T>): T {
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index d498ed9..3880664 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -96,6 +96,7 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.util.ArrayUtils;
+import com.android.testutils.SkipPresubmit;
import libcore.io.Streams;
@@ -325,6 +326,7 @@
*/
@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
@Test
+ @SkipPresubmit(reason = "Virtual devices use a single internet connection for all networks")
public void testOpenConnection() throws Exception {
boolean canRunTest = mPackageManager.hasSystemFeature(FEATURE_WIFI)
&& mPackageManager.hasSystemFeature(FEATURE_TELEPHONY);
@@ -990,6 +992,7 @@
@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
@Test
+ @SkipPresubmit(reason = "Keepalive is not supported on virtual hardware")
public void testCreateTcpKeepalive() throws Exception {
if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
Log.i(TAG, "testCreateTcpKeepalive cannot execute unless device supports WiFi");
@@ -1199,6 +1202,7 @@
*/
@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
@Test
+ @SkipPresubmit(reason = "Keepalive is not supported on virtual hardware")
public void testSocketKeepaliveLimitWifi() throws Exception {
if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
Log.i(TAG, "testSocketKeepaliveLimitWifi cannot execute unless device"
@@ -1252,6 +1256,7 @@
*/
@AppModeFull(reason = "Cannot request network in instant app mode")
@Test
+ @SkipPresubmit(reason = "Keepalive is not supported on virtual hardware")
public void testSocketKeepaliveLimitTelephony() throws Exception {
if (!mPackageManager.hasSystemFeature(FEATURE_TELEPHONY)) {
Log.i(TAG, "testSocketKeepaliveLimitTelephony cannot execute unless device"
@@ -1294,6 +1299,7 @@
*/
@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
@Test
+ @SkipPresubmit(reason = "Keepalive is not supported on virtual hardware")
public void testSocketKeepaliveUnprivileged() throws Exception {
if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
Log.i(TAG, "testSocketKeepaliveUnprivileged cannot execute unless device"
diff --git a/tests/cts/net/src/android/net/cts/DnsTest.java b/tests/cts/net/src/android/net/cts/DnsTest.java
index 746dcb0..fde27e9 100644
--- a/tests/cts/net/src/android/net/cts/DnsTest.java
+++ b/tests/cts/net/src/android/net/cts/DnsTest.java
@@ -27,6 +27,8 @@
import android.test.AndroidTestCase;
import android.util.Log;
+import com.android.testutils.SkipPresubmit;
+
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
@@ -68,6 +70,7 @@
* Perf - measure size of first and second tier caches and their effect
* Assert requires network permission
*/
+ @SkipPresubmit(reason = "IPv6 support may be missing on presubmit virtual hardware")
public void testDnsWorks() throws Exception {
ensureIpv6Connectivity();
diff --git a/tests/cts/net/src/android/net/cts/Ikev2VpnTest.java b/tests/cts/net/src/android/net/cts/Ikev2VpnTest.java
index 5cc0cb4..9eab024 100644
--- a/tests/cts/net/src/android/net/cts/Ikev2VpnTest.java
+++ b/tests/cts/net/src/android/net/cts/Ikev2VpnTest.java
@@ -16,6 +16,7 @@
package android.net.cts;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.cts.util.CtsNetUtils.TestNetworkCallback;
@@ -40,20 +41,25 @@
import android.net.IpSecAlgorithm;
import android.net.LinkAddress;
import android.net.Network;
+import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.ProxyInfo;
import android.net.TestNetworkInterface;
import android.net.TestNetworkManager;
import android.net.VpnManager;
import android.net.cts.util.CtsNetUtils;
+import android.os.Build;
+import android.os.Process;
import android.platform.test.annotations.AppModeFull;
import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
import com.android.internal.util.HexDump;
import com.android.org.bouncycastle.x509.X509V1CertificateGenerator;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+import com.android.testutils.DevSdkIgnoreRunner;
+import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -70,7 +76,8 @@
import javax.security.auth.x500.X500Principal;
-@RunWith(AndroidJUnit4.class)
+@RunWith(DevSdkIgnoreRunner.class)
+@IgnoreUpTo(Build.VERSION_CODES.Q)
@AppModeFull(reason = "Appops state changes disallowed for instant apps (OP_ACTIVATE_PLATFORM_VPN)")
public class Ikev2VpnTest {
private static final String TAG = Ikev2VpnTest.class.getSimpleName();
@@ -172,6 +179,12 @@
mUserCertKey = generateRandomCertAndKeyPair();
}
+ @After
+ public void tearDown() {
+ setAppop(AppOpsManager.OP_ACTIVATE_VPN, false);
+ setAppop(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN, false);
+ }
+
/**
* Sets the given appop using shell commands
*
@@ -416,6 +429,11 @@
final Network vpnNetwork = cb.currentNetwork;
assertNotNull(vpnNetwork);
+ final NetworkCapabilities caps = sCM.getNetworkCapabilities(vpnNetwork);
+ assertTrue(caps.hasTransport(TRANSPORT_VPN));
+ assertTrue(caps.hasCapability(NET_CAPABILITY_INTERNET));
+ assertEquals(Process.myUid(), caps.getOwnerUid());
+
sVpnMgr.stopProvisionedVpnProfile();
cb.waitForLost();
assertEquals(vpnNetwork, cb.lastLostNetwork);
diff --git a/tests/cts/net/src/android/net/cts/MultinetworkApiTest.java b/tests/cts/net/src/android/net/cts/MultinetworkApiTest.java
index 985e313..6d3db89 100644
--- a/tests/cts/net/src/android/net/cts/MultinetworkApiTest.java
+++ b/tests/cts/net/src/android/net/cts/MultinetworkApiTest.java
@@ -68,7 +68,6 @@
mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
mCR = getContext().getContentResolver();
mCtsNetUtils = new CtsNetUtils(getContext());
- mCtsNetUtils.storePrivateDnsSetting();
}
@Override
@@ -223,6 +222,7 @@
@AppModeFull(reason = "WRITE_SECURE_SETTINGS permission can't be granted to instant apps")
public void testResNApiNXDomainPrivateDns() throws InterruptedException {
+ mCtsNetUtils.storePrivateDnsSetting();
// Enable private DNS strict mode and set server to dns.google before doing NxDomain test.
// b/144521720
try {
diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
index 1055531..5e2f627 100644
--- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
+++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
@@ -57,8 +57,11 @@
import android.net.TetheringManager.TetheringRequest;
import android.net.cts.util.CtsNetUtils;
import android.net.cts.util.CtsNetUtils.TestNetworkCallback;
+import android.net.wifi.WifiClient;
import android.net.wifi.WifiManager;
+import android.net.wifi.WifiManager.SoftApCallback;
import android.os.Bundle;
+import android.os.ConditionVariable;
import android.os.PersistableBundle;
import android.os.ResultReceiver;
import android.telephony.CarrierConfigManager;
@@ -135,6 +138,40 @@
dropShellPermissionIdentity();
}
+ private static class StopSoftApCallback implements SoftApCallback {
+ private final ConditionVariable mWaiting = new ConditionVariable();
+ @Override
+ public void onStateChanged(int state, int failureReason) {
+ if (state == WifiManager.WIFI_AP_STATE_DISABLED) mWaiting.open();
+ }
+
+ @Override
+ public void onConnectedClientsChanged(List<WifiClient> clients) { }
+
+ public void waitForSoftApStopped() {
+ if (!mWaiting.block(DEFAULT_TIMEOUT_MS)) {
+ fail("stopSoftAp Timeout");
+ }
+ }
+ }
+
+ // Wait for softAp to be disabled. This is necessary on devices where stopping softAp
+ // deletes the interface. On these devices, tethering immediately stops when the softAp
+ // interface is removed, but softAp is not yet fully disabled. Wait for softAp to be
+ // fully disabled, because otherwise the next test might fail because it attempts to
+ // start softAp before it's fully stopped.
+ private void expectSoftApDisabled() {
+ final StopSoftApCallback callback = new StopSoftApCallback();
+ try {
+ mWm.registerSoftApCallback(c -> c.run(), callback);
+ // registerSoftApCallback will immediately call the callback with the current state, so
+ // this callback will fire even if softAp is already disabled.
+ callback.waitForSoftApStopped();
+ } finally {
+ mWm.unregisterSoftApCallback(callback);
+ }
+ }
+
private class TetherChangeReceiver extends BroadcastReceiver {
private class TetherState {
final ArrayList<String> mAvailable;
@@ -286,13 +323,15 @@
assertTrue(tetheredIfaces.length == 0);
final StartTetheringCallback startTetheringCallback = new StartTetheringCallback();
- mTM.startTethering(new TetheringRequest.Builder(TETHERING_WIFI).build(),
- c -> c.run() /* executor */, startTetheringCallback);
+ final TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI)
+ .setShouldShowEntitlementUi(false).build();
+ mTM.startTethering(request, c -> c.run() /* executor */, startTetheringCallback);
startTetheringCallback.verifyTetheringStarted();
mTetherChangeReceiver.expectTethering(true /* active */, wifiRegexs);
mTM.stopTethering(TETHERING_WIFI);
+ expectSoftApDisabled();
mTetherChangeReceiver.expectTethering(false /* active */, wifiRegexs);
}
@@ -529,8 +568,9 @@
assertFalse(isIfaceMatch(wifiRegexs, callback.getTetheredInterfaces()));
final StartTetheringCallback startTetheringCallback = new StartTetheringCallback();
- mTM.startTethering(new TetheringRequest.Builder(TETHERING_WIFI).build(),
- c -> c.run() /* executor */, startTetheringCallback);
+ final TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI)
+ .setShouldShowEntitlementUi(false).build();
+ mTM.startTethering(request, c -> c.run() /* executor */, startTetheringCallback);
startTetheringCallback.verifyTetheringStarted();
callback.expectTetheredInterfacesChanged(wifiRegexs);
@@ -542,6 +582,7 @@
private void stopWifiTethering(final TestTetheringEventCallback callback) {
mTM.stopTethering(TETHERING_WIFI);
+ expectSoftApDisabled();
callback.expectTetheredInterfacesChanged(null);
callback.expectOneOfOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
}