From 7f53eead8b34f59b588d3e5365fae24ef4143a55 Mon Sep 17 00:00:00 2001 From: lesl Date: Wed, 11 Mar 2020 19:30:49 +0800 Subject: [PATCH] cts: Add SoftAp API test in CTS Bug: 150307166 Bug: 150972516 Bug: 150972218 Bug: 150972206 Bug: 150969780 Bug: 150969541 Bug: 150969225 Bug: 150967334 Bug: 150643333 Test: atest android.net.wifi.cts.WifiManagerTest Change-Id: I10e19223b6370c6e149c48f43da45a64e235bccf --- .../android/net/wifi/cts/WifiManagerTest.java | 327 +++++++++++++++++- 1 file changed, 326 insertions(+), 1 deletion(-) 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 f4c20e3072..c8ace7c611 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -40,8 +40,12 @@ import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkRequest; +import android.net.TetheringManager; import android.net.wifi.ScanResult; +import android.net.wifi.SoftApCapability; import android.net.wifi.SoftApConfiguration; +import android.net.wifi.SoftApInfo; +import android.net.wifi.WifiClient; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; @@ -73,6 +77,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; +import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Objects; @@ -90,6 +95,7 @@ public class WifiManagerTest extends AndroidTestCase { private WifiManager mWifiManager; private ConnectivityManager mConnectivityManager; + private TetheringManager mTetheringManager; private WifiLock mWifiLock; private static MySync mMySync; private List mScanResults = null; @@ -97,6 +103,7 @@ public class WifiManagerTest extends AndroidTestCase { private final Object mLock = new Object(); private UiDevice mUiDevice; private boolean mWasVerboseLoggingEnabled; + private SoftApConfiguration mOriginalSoftApConfig = null; // Please refer to WifiManager private static final int MIN_RSSI = -100; @@ -199,7 +206,9 @@ public class WifiManagerTest extends AndroidTestCase { mContext.registerReceiver(mReceiver, mIntentFilter); mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); mConnectivityManager = getContext().getSystemService(ConnectivityManager.class); + mTetheringManager = getContext().getSystemService(TetheringManager.class); assertNotNull(mWifiManager); + assertNotNull(mTetheringManager); // turn on verbose logging for tests mWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions( @@ -222,6 +231,10 @@ public class WifiManagerTest extends AndroidTestCase { List savedNetworks = ShellIdentityUtils.invokeWithShellPermissions( mWifiManager::getConfiguredNetworks); assertFalse("Need at least one saved network", savedNetworks.isEmpty()); + + // Get original config for restore + mOriginalSoftApConfig = ShellIdentityUtils.invokeWithShellPermissions( + mWifiManager::getSoftApConfiguration); } @Override @@ -237,6 +250,9 @@ public class WifiManagerTest extends AndroidTestCase { mContext.unregisterReceiver(mReceiver); ShellIdentityUtils.invokeWithShellPermissions( () -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled)); + // restore original softap config + ShellIdentityUtils.invokeWithShellPermissions( + () -> mWifiManager.setSoftApConfiguration(mOriginalSoftApConfig)); Thread.sleep(DURATION); super.tearDown(); } @@ -506,6 +522,140 @@ public class WifiManagerTest extends AndroidTestCase { } } + public class TestSoftApCallback implements WifiManager.SoftApCallback { + Object softApLock; + int currentState; + int currentFailureReason; + List currentClientList; + SoftApInfo currentSoftApInfo; + SoftApCapability currentSoftApCapability; + MacAddress lastBlockedClientMacAddress; + int lastBlockedClientReason; + boolean onStateChangedCalled = false; + boolean onSoftapInfoChangedCalled = false; + boolean onSoftApCapabilityChangedCalled = false; + boolean onConnectedClientCalled = false; + boolean onBlockedClientConnectingCalled = false; + + TestSoftApCallback(Object lock) { + softApLock = lock; + } + + public boolean getOnStateChangedCalled() { + synchronized(softApLock) { + return onStateChangedCalled; + } + } + + public boolean getOnSoftapInfoChangedCalled() { + synchronized(softApLock) { + return onSoftapInfoChangedCalled; + } + } + + public boolean getOnSoftApCapabilityChangedCalled() { + synchronized(softApLock) { + return onSoftApCapabilityChangedCalled; + } + } + + public boolean getOnConnectedClientCalled() { + synchronized(softApLock) { + return onConnectedClientCalled; + } + } + + public boolean getOnBlockedClientConnectingCalled() { + synchronized(softApLock) { + return onBlockedClientConnectingCalled; + } + } + + public int getCurrentState() { + synchronized(softApLock) { + return currentState; + } + } + + public int getCurrentStateFailureReason() { + synchronized(softApLock) { + return currentFailureReason; + } + } + + public List getCurrentClientList() { + synchronized(softApLock) { + return currentClientList; + } + } + + public SoftApInfo getCurrentSoftApInfo() { + synchronized(softApLock) { + return currentSoftApInfo; + } + } + + public SoftApCapability getCurrentSoftApCapability() { + synchronized(softApLock) { + return currentSoftApCapability; + } + } + + public MacAddress getLastBlockedClientMacAddress() { + synchronized(softApLock) { + return lastBlockedClientMacAddress; + } + } + + public int getLastBlockedClientReason() { + synchronized(softApLock) { + return lastBlockedClientReason; + } + } + + @Override + public void onStateChanged(int state, int failureReason) { + synchronized(softApLock) { + currentState = state; + currentFailureReason = failureReason; + onStateChangedCalled = true; + } + } + + @Override + public void onConnectedClientsChanged(List clients) { + synchronized(softApLock) { + currentClientList = new ArrayList<>(clients); + onConnectedClientCalled = true; + } + } + + @Override + public void onInfoChanged(SoftApInfo softApInfo) { + synchronized(softApLock) { + currentSoftApInfo = softApInfo; + onSoftapInfoChangedCalled = true; + } + } + + @Override + public void onCapabilityChanged(SoftApCapability softApCapability) { + synchronized(softApLock) { + currentSoftApCapability = softApCapability; + onSoftApCapabilityChangedCalled = true; + } + } + + @Override + public void onBlockedClientConnecting(WifiClient client, int blockedReason) { + synchronized(softApLock) { + lastBlockedClientMacAddress = client.getMacAddress(); + lastBlockedClientReason = blockedReason; + onBlockedClientConnectingCalled = true; + } + } + } + private static class TestLocalOnlyHotspotCallback extends WifiManager.LocalOnlyHotspotCallback { Object hotspotLock; WifiManager.LocalOnlyHotspotReservation reservation = null; @@ -561,7 +711,10 @@ public class WifiManagerTest extends AndroidTestCase { } // check if we got the callback assertTrue(callback.onStartedCalled); - assertNotNull(callback.reservation.getSoftApConfiguration()); + + SoftApConfiguration softApConfig = callback.reservation.getSoftApConfiguration(); + assertNotNull(softApConfig); + assertNotNull(softApConfig.toWifiConfiguration()); if (!hasAutomotiveFeature()) { assertEquals( SoftApConfiguration.BAND_2GHZ, @@ -1141,6 +1294,178 @@ public class WifiManagerTest extends AndroidTestCase { > ENFORCED_NUM_NETWORK_SUGGESTIONS_PER_APP); } + private void verifyRegisterSoftApCallback(TestExecutor executor, TestSoftApCallback callback) + throws Exception{ + // Register callback to get SoftApCapability + mWifiManager.registerSoftApCallback(executor, callback); + PollingCheck.check( + "SoftAp register failed!", 1_000, + () -> { executor.runAll(); + // Verify callback is run on the supplied executor and called + return callback.getOnStateChangedCalled() && + callback.getOnSoftapInfoChangedCalled() && + callback.getOnSoftApCapabilityChangedCalled() && + callback.getOnConnectedClientCalled(); + }); + } + + private void verifySetGetSoftApConfig(SoftApConfiguration targetConfig) { + mWifiManager.setSoftApConfiguration(targetConfig); + // Bssid set dodesn't support for tethered hotspot + SoftApConfiguration currentConfig = mWifiManager.getSoftApConfiguration(); + assertNull(currentConfig.getBssid()); + compareSoftApConfiguration(targetConfig, currentConfig); + } + + private void compareSoftApConfiguration(SoftApConfiguration currentConfig, + SoftApConfiguration testSoftApConfig) { + assertEquals(currentConfig.getSsid(), testSoftApConfig.getSsid()); + assertEquals(currentConfig.getSecurityType(), testSoftApConfig.getSecurityType()); + assertEquals(currentConfig.getPassphrase(), testSoftApConfig.getPassphrase()); + assertEquals(currentConfig.isHiddenSsid(), testSoftApConfig.isHiddenSsid()); + assertEquals(currentConfig.getBand(), testSoftApConfig.getBand()); + assertEquals(currentConfig.getChannel(), testSoftApConfig.getChannel()); + assertEquals(currentConfig.getMaxNumberOfClients(), + testSoftApConfig.getMaxNumberOfClients()); + assertEquals(currentConfig.isAutoShutdownEnabled(), + testSoftApConfig.isAutoShutdownEnabled()); + assertEquals(currentConfig.getShutdownTimeoutMillis(), + testSoftApConfig.getShutdownTimeoutMillis()); + assertEquals(currentConfig.isClientControlByUserEnabled(), + testSoftApConfig.isClientControlByUserEnabled()); + assertEquals(currentConfig.getAllowedClientList(), + testSoftApConfig.getAllowedClientList()); + assertEquals(currentConfig.getBlockedClientList(), + testSoftApConfig.getBlockedClientList()); + } + + private void turnOffWifiAndTetheredHotspotIfEnabled() throws Exception { + if (mWifiManager.isWifiEnabled()) { + Log.d(TAG, "Turn off WiFi"); + mWifiManager.setWifiEnabled(false); + PollingCheck.check( + "Wifi turn off failed!", 2_000, + () -> mWifiManager.isWifiEnabled() == false); + } + if (mWifiManager.isWifiApEnabled()) { + mTetheringManager.stopTethering(ConnectivityManager.TETHERING_WIFI); + Log.d(TAG, "Turn off tethered Hotspot"); + PollingCheck.check( + "SoftAp turn off failed!", 2_000, + () -> mWifiManager.isWifiApEnabled() == false); + mTetheringManager.stopTethering(ConnectivityManager.TETHERING_WIFI); + } + } + + /** + * Verify that the configuration from getSoftApConfiguration is same as the configuration which + * set by setSoftApConfiguration. And depends softap capability callback to test different + * configuration. + * @throws Exception + */ + public void testSetGetSoftApConfigurationAndSoftApCapabilityCallback() throws Exception { + UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); + try { + uiAutomation.adoptShellPermissionIdentity(); + turnOffWifiAndTetheredHotspotIfEnabled(); + TestExecutor executor = new TestExecutor(); + TestSoftApCallback callback = new TestSoftApCallback(mLock); + verifyRegisterSoftApCallback(executor, callback); + + SoftApConfiguration.Builder softApConfigBuilder = new SoftApConfiguration.Builder() + .setSsid(TEST_SSID_UNQUOTED) + .setBssid(TEST_MAC) + .setPassphrase(TEST_PASSPHRASE, SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) + .setAutoShutdownEnabled(true) + .setShutdownTimeoutMillis(100000) + .setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ) + .setHiddenSsid(false); + + // Test SoftApConfiguration set and get + verifySetGetSoftApConfig(softApConfigBuilder.build()); + + // Test CLIENT_FORCE_DISCONNECT supported config. + if (callback.getCurrentSoftApCapability() + .areFeaturesSupported( + SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT)) { + softApConfigBuilder.setMaxNumberOfClients(10); + softApConfigBuilder.setClientControlByUserEnabled(true); + softApConfigBuilder.setBlockedClientList(new ArrayList<>()); + softApConfigBuilder.setAllowedClientList(new ArrayList<>()); + verifySetGetSoftApConfig(softApConfigBuilder.build()); + } + + // Test SAE config + if (callback.getCurrentSoftApCapability() + .areFeaturesSupported(SoftApCapability.SOFTAP_FEATURE_WPA3_SAE)) { + softApConfigBuilder + .setPassphrase(TEST_PASSPHRASE, + SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION); + verifySetGetSoftApConfig(softApConfigBuilder.build()); + softApConfigBuilder + .setPassphrase(TEST_PASSPHRASE, + SoftApConfiguration.SECURITY_TYPE_WPA3_SAE); + verifySetGetSoftApConfig(softApConfigBuilder.build()); + } + } finally { + uiAutomation.dropShellPermissionIdentity(); + } + } + + /** + * Verify that startTetheredHotspot with specific channel config. + * @throws Exception + */ + public void testStartTetheredHotspotWithChannelConfigAndSoftApStateAndInfoCallback() + throws Exception { + UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); + try { + uiAutomation.adoptShellPermissionIdentity(); + turnOffWifiAndTetheredHotspotIfEnabled(); + TestExecutor executor = new TestExecutor(); + TestSoftApCallback callback = new TestSoftApCallback(mLock); + verifyRegisterSoftApCallback(executor, callback); + + SoftApConfiguration testSoftApConfig = new SoftApConfiguration.Builder() + .setSsid(TEST_SSID_UNQUOTED) + .setPassphrase(TEST_PASSPHRASE, SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) + .setChannel(11, SoftApConfiguration.BAND_2GHZ) // Channel 11 = Freq 2462 + .build(); + + mWifiManager.setSoftApConfiguration(testSoftApConfig); + + // start tethering which used to verify startTetheredHotspot + mTetheringManager.startTethering(ConnectivityManager.TETHERING_WIFI, executor, + new TetheringManager.StartTetheringCallback() { + @Override + public void onTetheringFailed(final int result) { + } + }); + + // Verify state and info callback value as expected + PollingCheck.check( + "SoftAp channel and state mismatch!!!", 5_000, + () -> { executor.runAll(); + return WifiManager.WIFI_AP_STATE_ENABLED == callback.getCurrentState() && + 2462 == callback.getCurrentSoftApInfo().getFrequency(); + }); + + // stop tethering which used to verify stopSoftAp + mTetheringManager.stopTethering(ConnectivityManager.TETHERING_WIFI); + + // Verify clean up + PollingCheck.check( + "Stop Softap failed", 2_000, + () -> { executor.runAll(); + return WifiManager.WIFI_AP_STATE_DISABLED == callback.getCurrentState() && + 0 == callback.getCurrentSoftApInfo().getBandwidth() && + 0 == callback.getCurrentSoftApInfo().getFrequency(); + }); + } finally { + uiAutomation.dropShellPermissionIdentity(); + } + } + private static class TestActionListener implements WifiManager.ActionListener { private final Object mLock; public boolean onSuccessCalled = false;