Merge "Add IpConfigurationTest for new @SystemApi" into rvc-dev
diff --git a/tests/cts/hostside/Android.bp b/tests/cts/hostside/Android.bp
index b6f5142..a8cc95b 100644
--- a/tests/cts/hostside/Android.bp
+++ b/tests/cts/hostside/Android.bp
@@ -25,6 +25,7 @@
test_suites: [
"cts",
"vts",
+ "vts10",
"general-tests",
],
}
diff --git a/tests/cts/hostside/app/Android.bp b/tests/cts/hostside/app/Android.bp
index e988ea4..8b6d38b 100644
--- a/tests/cts/hostside/app/Android.bp
+++ b/tests/cts/hostside/app/Android.bp
@@ -36,6 +36,7 @@
test_suites: [
"cts",
"vts",
+ "vts10",
"general-tests",
],
}
diff --git a/tests/cts/hostside/app2/Android.bp b/tests/cts/hostside/app2/Android.bp
index 8a3c8e7..0bb0d2f 100644
--- a/tests/cts/hostside/app2/Android.bp
+++ b/tests/cts/hostside/app2/Android.bp
@@ -24,6 +24,7 @@
test_suites: [
"cts",
"vts",
+ "vts10",
"general-tests",
],
certificate: ":cts-net-app",
diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp
index 624d149..d77f416 100644
--- a/tests/cts/net/Android.bp
+++ b/tests/cts/net/Android.bp
@@ -65,6 +65,7 @@
test_suites: [
"cts",
"vts",
+ "vts10",
"general-tests",
],
test_config_template: "AndroidTestTemplate.xml",
diff --git a/tests/cts/net/api23Test/Android.bp b/tests/cts/net/api23Test/Android.bp
index ffe854e..614a5a2 100644
--- a/tests/cts/net/api23Test/Android.bp
+++ b/tests/cts/net/api23Test/Android.bp
@@ -46,6 +46,7 @@
test_suites: [
"cts",
"vts",
+ "vts10",
"general-tests",
],
diff --git a/tests/cts/net/appForApi23/Android.bp b/tests/cts/net/appForApi23/Android.bp
index 82e2a08..17cfe38 100644
--- a/tests/cts/net/appForApi23/Android.bp
+++ b/tests/cts/net/appForApi23/Android.bp
@@ -27,6 +27,7 @@
test_suites: [
"cts",
"vts",
+ "vts10",
"general-tests",
],
diff --git a/tests/cts/net/native/qtaguid/Android.bp b/tests/cts/net/native/qtaguid/Android.bp
index c0f0613..054937b 100644
--- a/tests/cts/net/native/qtaguid/Android.bp
+++ b/tests/cts/net/native/qtaguid/Android.bp
@@ -43,6 +43,7 @@
test_suites: [
"cts",
"vts",
+ "vts10",
],
cflags: [
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 5eb3e36..8f23324 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
@@ -16,7 +16,9 @@
package android.net.wifi.aware.cts;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
+import static org.mockito.Mockito.mock;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -30,17 +32,21 @@
import android.net.wifi.WifiManager;
import android.net.wifi.aware.AttachCallback;
import android.net.wifi.aware.Characteristics;
+import android.net.wifi.aware.DiscoverySession;
import android.net.wifi.aware.DiscoverySessionCallback;
import android.net.wifi.aware.IdentityChangedListener;
+import android.net.wifi.aware.ParcelablePeerHandle;
import android.net.wifi.aware.PeerHandle;
import android.net.wifi.aware.PublishConfig;
import android.net.wifi.aware.PublishDiscoverySession;
import android.net.wifi.aware.SubscribeConfig;
import android.net.wifi.aware.SubscribeDiscoverySession;
import android.net.wifi.aware.WifiAwareManager;
+import android.net.wifi.aware.WifiAwareNetworkSpecifier;
import android.net.wifi.aware.WifiAwareSession;
import android.os.Handler;
import android.os.HandlerThread;
+import android.os.Parcel;
import android.platform.test.annotations.AppModeFull;
import android.test.AndroidTestCase;
@@ -64,6 +70,9 @@
// wait for Wi-Fi Aware state changes & network requests callbacks
static private final int WAIT_FOR_AWARE_CHANGE_SECS = 10; // 10 seconds
+ private static final int MIN_DISTANCE_MM = 1 * 1000;
+ private static final int MAX_DISTANCE_MM = 3 * 1000;
+ private static final byte[] PMK_VALID = "01234567890123456789012345678901".getBytes();
private final Object mLock = new Object();
private final HandlerThread mHandlerThread = new HandlerThread("SingleDeviceTest");
@@ -615,7 +624,8 @@
// 2. update-subscribe
subscribeConfig = new SubscribeConfig.Builder().setServiceName(
- serviceName).setServiceSpecificInfo("extras".getBytes()).build();
+ serviceName).setServiceSpecificInfo("extras".getBytes())
+ .setMinDistanceMm(MIN_DISTANCE_MM).build();
discoverySession.updateSubscribe(subscribeConfig);
assertTrue("Subscribe update", discoveryCb.waitForCallback(
DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED));
@@ -741,7 +751,8 @@
}
/**
- * Request an Aware data-path (encrypted) as a Responder with an arbitrary peer MAC address.
+ * Request an Aware data-path (encrypted with Passphrase) as a Responder with an arbitrary peer
+ * MAC address.
* Validate that receive an onUnavailable() callback.
*/
public void testDataPathPassphraseOutOfBandFail() {
@@ -773,6 +784,77 @@
session.close();
}
+ /**
+ * Request an Aware data-path (encrypted with PMK) as a Responder with an arbitrary peer MAC
+ * address.
+ * Validate that receive an onUnavailable() callback.
+ */
+ public void testDataPathPmkOutOfBandFail() {
+ if (!TestUtils.shouldTestWifiAware(getContext())) {
+ return;
+ }
+ MacAddress mac = MacAddress.fromString("00:01:02:03:04:05");
+
+ // 1. initialize Aware: only purpose is to make sure it is available for OOB data-path
+ WifiAwareSession session = attachAndGetSession();
+
+ PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
+ "ValidName").build();
+ DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
+ session.publish(publishConfig, discoveryCb, mHandler);
+ assertTrue("Publish started",
+ discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
+
+ // 2. request an AWARE network
+ NetworkCallbackTest networkCb = new NetworkCallbackTest();
+ NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
+ NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier(
+ session.createNetworkSpecifierPmk(
+ WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, mac.toByteArray(),
+ PMK_VALID)).build();
+ mConnectivityManager.requestNetwork(nr, networkCb);
+ assertTrue("OnUnavailable not received", networkCb.waitForOnUnavailable());
+
+ session.close();
+ }
+
+ /**
+ * Test WifiAwareNetworkSpecifier.
+ */
+ public void testWifiAwareNetworkSpecifier() {
+ DiscoverySession session = mock(DiscoverySession.class);
+ PeerHandle handle = mock(PeerHandle.class);
+ WifiAwareNetworkSpecifier networkSpecifier =
+ new WifiAwareNetworkSpecifier.Builder(session, handle).build();
+ assertFalse(networkSpecifier.satisfiedBy(null));
+ assertTrue(networkSpecifier.satisfiedBy(networkSpecifier));
+
+ WifiAwareNetworkSpecifier anotherNetworkSpecifier =
+ new WifiAwareNetworkSpecifier.Builder(session, handle).setPmk(PMK_VALID).build();
+ assertFalse(networkSpecifier.satisfiedBy(anotherNetworkSpecifier));
+ }
+
+ /**
+ * Test ParcelablePeerHandle parcel.
+ */
+ public void testParcelablePeerHandle() {
+ PeerHandle peerHandle = mock(PeerHandle.class);
+ ParcelablePeerHandle parcelablePeerHandle = new ParcelablePeerHandle(peerHandle);
+ Parcel parcelW = Parcel.obtain();
+ parcelablePeerHandle.writeToParcel(parcelW, 0);
+ byte[] bytes = parcelW.marshall();
+ parcelW.recycle();
+
+ Parcel parcelR = Parcel.obtain();
+ parcelR.unmarshall(bytes, 0, bytes.length);
+ parcelR.setDataPosition(0);
+ ParcelablePeerHandle rereadParcelablePeerHandle =
+ ParcelablePeerHandle.CREATOR.createFromParcel(parcelR);
+
+ assertEquals(parcelablePeerHandle, rereadParcelablePeerHandle);
+ assertEquals(parcelablePeerHandle.hashCode(), rereadParcelablePeerHandle.hashCode());
+ }
+
// local utilities
private WifiAwareSession attachAndGetSession() {
diff --git a/tests/cts/net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java b/tests/cts/net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java
new file mode 100644
index 0000000..ce5bb81
--- /dev/null
+++ b/tests/cts/net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java
@@ -0,0 +1,344 @@
+/*
+ * Copyright (C) 2020 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.wifi.cts;
+
+import static android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_FAILURE;
+import static android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_NO_PROBE;
+import static android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_SUCCESS;
+import static android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_UNKNOWN;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.UiAutomation;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiUsabilityStatsEntry;
+import android.support.test.uiautomator.UiDevice;
+import android.telephony.TelephonyManager;
+import android.test.AndroidTestCase;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.compatibility.common.util.PollingCheck;
+import com.android.compatibility.common.util.ShellIdentityUtils;
+import com.android.compatibility.common.util.SystemUtil;
+
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+public class ConnectedNetworkScorerTest extends AndroidTestCase {
+ private WifiManager mWifiManager;
+ private UiDevice mUiDevice;
+ private boolean mWasVerboseLoggingEnabled;
+
+ private static final int DURATION = 10_000;
+ private static final int DURATION_SCREEN_TOGGLE = 2000;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
+ mWifiManager = getContext().getSystemService(WifiManager.class);
+ assertThat(mWifiManager).isNotNull();
+
+ // turn on verbose logging for tests
+ mWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions(
+ () -> mWifiManager.isVerboseLoggingEnabled());
+ ShellIdentityUtils.invokeWithShellPermissions(
+ () -> mWifiManager.setVerboseLoggingEnabled(true));
+
+ if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true);
+ mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ turnScreenOn();
+ PollingCheck.check("Wifi not enabled", DURATION, () -> mWifiManager.isWifiEnabled());
+ List<WifiConfiguration> savedNetworks = ShellIdentityUtils.invokeWithShellPermissions(
+ () -> mWifiManager.getConfiguredNetworks());
+ assertFalse("Need at least one saved network", savedNetworks.isEmpty());
+ // Wait for wifi is to be connected
+ PollingCheck.check(
+ "Wifi not connected",
+ DURATION,
+ () -> mWifiManager.getConnectionInfo().getNetworkId() != -1);
+ assertThat(mWifiManager.getConnectionInfo().getNetworkId()).isNotEqualTo(-1);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ super.tearDown();
+ return;
+ }
+ if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true);
+ turnScreenOff();
+ ShellIdentityUtils.invokeWithShellPermissions(
+ () -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled));
+ super.tearDown();
+ }
+
+ private void setWifiEnabled(boolean enable) throws Exception {
+ // now trigger the change using shell commands.
+ SystemUtil.runShellCommand("svc wifi " + (enable ? "enable" : "disable"));
+ }
+
+ private void turnScreenOn() throws Exception {
+ mUiDevice.executeShellCommand("input keyevent KEYCODE_WAKEUP");
+ mUiDevice.executeShellCommand("wm dismiss-keyguard");
+ // Since the screen on/off intent is ordered, they will not be sent right now.
+ Thread.sleep(DURATION_SCREEN_TOGGLE);
+ }
+
+ private void turnScreenOff() throws Exception {
+ mUiDevice.executeShellCommand("input keyevent KEYCODE_SLEEP");
+ }
+
+ private static class TestUsabilityStatsListener implements
+ WifiManager.OnWifiUsabilityStatsListener {
+ private final CountDownLatch mCountDownLatch;
+ public int seqNum;
+ public boolean isSameBssidAndFre;
+ public WifiUsabilityStatsEntry statsEntry;
+
+ TestUsabilityStatsListener(CountDownLatch countDownLatch) {
+ mCountDownLatch = countDownLatch;
+ }
+
+ @Override
+ public void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq,
+ WifiUsabilityStatsEntry statsEntry) {
+ this.seqNum = seqNum;
+ this.isSameBssidAndFre = isSameBssidAndFreq;
+ this.statsEntry = statsEntry;
+ mCountDownLatch.countDown();
+ }
+ }
+
+ /**
+ * Tests the {@link android.net.wifi.WifiUsabilityStatsEntry} retrieved from
+ * {@link WifiManager.OnWifiUsabilityStatsListener}.
+ */
+ public void testWifiUsabilityStatsEntry() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
+ CountDownLatch countDownLatch = new CountDownLatch(1);
+ UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+ TestUsabilityStatsListener usabilityStatsListener =
+ new TestUsabilityStatsListener(countDownLatch);
+ try {
+ uiAutomation.adoptShellPermissionIdentity();
+ mWifiManager.addOnWifiUsabilityStatsListener(
+ Executors.newSingleThreadExecutor(), usabilityStatsListener);
+ // Wait for new usability stats (while connected & screen on this is triggered
+ // by platform periodically).
+ assertThat(countDownLatch.await(DURATION, TimeUnit.MILLISECONDS)).isTrue();
+
+ assertThat(usabilityStatsListener.statsEntry).isNotNull();
+ WifiUsabilityStatsEntry statsEntry = usabilityStatsListener.statsEntry;
+
+ assertThat(statsEntry.getTimeStampMillis()).isGreaterThan(0L);
+ assertThat(statsEntry.getRssi()).isLessThan(0);
+ assertThat(statsEntry.getLinkSpeedMbps()).isGreaterThan(0);
+ assertThat(statsEntry.getTotalTxSuccess()).isGreaterThan(0L);
+ assertThat(statsEntry.getTotalTxRetries()).isAtLeast(0L);
+ assertThat(statsEntry.getTotalTxBad()).isAtLeast(0L);
+ assertThat(statsEntry.getTotalRxSuccess()).isAtLeast(0L);
+ assertThat(statsEntry.getTotalRadioOnTimeMillis()).isGreaterThan(0L);
+ assertThat(statsEntry.getTotalRadioTxTimeMillis()).isGreaterThan(0L);
+ assertThat(statsEntry.getTotalRadioRxTimeMillis()).isGreaterThan(0L);
+ assertThat(statsEntry.getTotalScanTimeMillis()).isGreaterThan(0L);
+ assertThat(statsEntry.getTotalNanScanTimeMillis()).isAtLeast(0L);
+ assertThat(statsEntry.getTotalBackgroundScanTimeMillis()).isAtLeast(0L);
+ assertThat(statsEntry.getTotalRoamScanTimeMillis()).isAtLeast(0L);
+ assertThat(statsEntry.getTotalPnoScanTimeMillis()).isAtLeast(0L);
+ assertThat(statsEntry.getTotalHotspot2ScanTimeMillis()).isAtLeast(0L);
+ assertThat(statsEntry.getTotalCcaBusyFreqTimeMillis()).isAtLeast(0L);
+ assertThat(statsEntry.getTotalRadioOnTimeMillis()).isGreaterThan(0L);
+ assertThat(statsEntry.getTotalBeaconRx()).isGreaterThan(0L);
+ assertThat(statsEntry.getProbeStatusSinceLastUpdate())
+ .isAnyOf(PROBE_STATUS_SUCCESS,
+ PROBE_STATUS_FAILURE,
+ PROBE_STATUS_NO_PROBE,
+ PROBE_STATUS_UNKNOWN);
+ // -1 is default value for some of these fields if they're not available.
+ assertThat(statsEntry.getProbeElapsedTimeSinceLastUpdateMillis()).isAtLeast(-1);
+ assertThat(statsEntry.getProbeMcsRateSinceLastUpdate()).isAtLeast(-1);
+ assertThat(statsEntry.getRxLinkSpeedMbps()).isAtLeast(-1);
+ // no longer populated, return default value.
+ assertThat(statsEntry.getCellularDataNetworkType())
+ .isAnyOf(TelephonyManager.NETWORK_TYPE_UNKNOWN,
+ TelephonyManager.NETWORK_TYPE_GPRS,
+ TelephonyManager.NETWORK_TYPE_EDGE,
+ TelephonyManager.NETWORK_TYPE_UMTS,
+ TelephonyManager.NETWORK_TYPE_CDMA,
+ TelephonyManager.NETWORK_TYPE_EVDO_0,
+ TelephonyManager.NETWORK_TYPE_EVDO_A,
+ TelephonyManager.NETWORK_TYPE_1xRTT,
+ TelephonyManager.NETWORK_TYPE_HSDPA,
+ TelephonyManager.NETWORK_TYPE_HSUPA,
+ TelephonyManager.NETWORK_TYPE_HSPA,
+ TelephonyManager.NETWORK_TYPE_IDEN,
+ TelephonyManager.NETWORK_TYPE_EVDO_B,
+ TelephonyManager.NETWORK_TYPE_LTE,
+ TelephonyManager.NETWORK_TYPE_EHRPD,
+ TelephonyManager.NETWORK_TYPE_HSPAP,
+ TelephonyManager.NETWORK_TYPE_GSM,
+ TelephonyManager.NETWORK_TYPE_TD_SCDMA,
+ TelephonyManager.NETWORK_TYPE_IWLAN,
+ TelephonyManager.NETWORK_TYPE_NR);
+ assertThat(statsEntry.getCellularSignalStrengthDbm()).isAtMost(0);
+ assertThat(statsEntry.getCellularSignalStrengthDb()).isAtMost(0);
+ assertThat(statsEntry.isSameRegisteredCell()).isFalse();
+ } finally {
+ mWifiManager.removeOnWifiUsabilityStatsListener(usabilityStatsListener);
+ uiAutomation.dropShellPermissionIdentity();
+ }
+ }
+
+ /**
+ * Tests the {@link android.net.wifi.WifiManager#updateWifiUsabilityScore(int, int, int)}
+ */
+ public void testUpdateWifiUsabilityScore() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
+ UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+ try {
+ uiAutomation.adoptShellPermissionIdentity();
+ // update scoring with dummy values.
+ mWifiManager.updateWifiUsabilityScore(0, 50, 50);
+ } finally {
+ uiAutomation.dropShellPermissionIdentity();
+ }
+ }
+
+ private static class TestConnectedNetworkScorer implements
+ WifiManager.WifiConnectedNetworkScorer {
+ private CountDownLatch mCountDownLatch;
+ public int startSessionId;
+ public int stopSessionId;
+ public WifiManager.ScoreUpdateObserver scoreUpdateObserver;
+
+ TestConnectedNetworkScorer(CountDownLatch countDownLatch) {
+ mCountDownLatch = countDownLatch;
+ }
+
+ @Override
+ public void onStart(int sessionId) {
+ synchronized (mCountDownLatch) {
+ this.startSessionId = sessionId;
+ mCountDownLatch.countDown();
+ }
+ }
+
+ @Override
+ public void onStop(int sessionId) {
+ synchronized (mCountDownLatch) {
+ this.stopSessionId = sessionId;
+ mCountDownLatch.countDown();
+ }
+ }
+
+ @Override
+ public void onSetScoreUpdateObserver(WifiManager.ScoreUpdateObserver observerImpl) {
+ this.scoreUpdateObserver = observerImpl;
+ }
+
+ public void resetCountDownLatch(CountDownLatch countDownLatch) {
+ synchronized (mCountDownLatch) {
+ mCountDownLatch = countDownLatch;
+ }
+ }
+ }
+
+ /**
+ * Tests the {@link android.net.wifi.WifiConnectedNetworkScorer} interface.
+ *
+ * Note: We could write more interesting test cases (if the device has a mobile connection), but
+ * that would make the test flaky. The default network/route selection on the device is not just
+ * controlled by the wifi scorer input, but also based on params which are controlled by
+ * other parts of the platform (likely in connectivity service) and hence will behave
+ * differently on OEM devices.
+ */
+ public void testSetWifiConnectedNetworkScorer() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
+ CountDownLatch countDownLatchScorer = new CountDownLatch(1);
+ CountDownLatch countDownLatchUsabilityStats = new CountDownLatch(1);
+ UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+ TestConnectedNetworkScorer connectedNetworkScorer =
+ new TestConnectedNetworkScorer(countDownLatchScorer);
+ TestUsabilityStatsListener usabilityStatsListener =
+ new TestUsabilityStatsListener(countDownLatchUsabilityStats);
+ try {
+ uiAutomation.adoptShellPermissionIdentity();
+ mWifiManager.setWifiConnectedNetworkScorer(
+ Executors.newSingleThreadExecutor(), connectedNetworkScorer);
+ // Since we're already connected, wait for onStart to be invoked.
+ assertThat(countDownLatchScorer.await(DURATION, TimeUnit.MILLISECONDS)).isTrue();
+
+ assertThat(connectedNetworkScorer.startSessionId).isAtLeast(0);
+ assertThat(connectedNetworkScorer.scoreUpdateObserver).isNotNull();
+ WifiManager.ScoreUpdateObserver scoreUpdateObserver =
+ connectedNetworkScorer.scoreUpdateObserver;
+
+ // Now trigger a dummy score update.
+ scoreUpdateObserver.notifyScoreUpdate(connectedNetworkScorer.startSessionId, 50);
+
+ // Register the usability listener
+ mWifiManager.addOnWifiUsabilityStatsListener(
+ Executors.newSingleThreadExecutor(), usabilityStatsListener);
+ // Trigger a usability stats update.
+ scoreUpdateObserver.triggerUpdateOfWifiUsabilityStats(
+ connectedNetworkScorer.startSessionId);
+ // Ensure that we got the stats update callback.
+ assertThat(countDownLatchUsabilityStats.await(DURATION, TimeUnit.MILLISECONDS))
+ .isTrue();
+ assertThat(usabilityStatsListener.seqNum).isAtLeast(0);
+
+ // Reset the scorer countdown latch for onStop
+ countDownLatchScorer = new CountDownLatch(1);
+ connectedNetworkScorer.resetCountDownLatch(countDownLatchScorer);
+ // Now disconnect from the network.
+ mWifiManager.disconnect();
+ // Wait for it to be disconnected.
+ PollingCheck.check(
+ "Wifi not disconnected",
+ DURATION,
+ () -> mWifiManager.getConnectionInfo().getNetworkId() == -1);
+ assertThat(mWifiManager.getConnectionInfo().getNetworkId()).isEqualTo(-1);
+
+ // Wait for stop to be invoked and ensure that the session id matches.
+ assertThat(countDownLatchScorer.await(DURATION, TimeUnit.MILLISECONDS)).isTrue();
+ assertThat(connectedNetworkScorer.stopSessionId)
+ .isEqualTo(connectedNetworkScorer.startSessionId);
+ } finally {
+ mWifiManager.removeOnWifiUsabilityStatsListener(usabilityStatsListener);
+ mWifiManager.clearWifiConnectedNetworkScorer();
+ uiAutomation.dropShellPermissionIdentity();
+ }
+ }
+}
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 161b0b4..1977378 100644
--- a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java
@@ -34,6 +34,7 @@
import android.platform.test.annotations.AppModeFull;
import android.test.AndroidTestCase;
+import com.android.compatibility.common.util.ShellIdentityUtils;
import com.android.compatibility.common.util.SystemUtil;
@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
@@ -45,6 +46,8 @@
private WifiManager mWifiManager;
private WifiLock mWifiLock;
private static MySync mMySync;
+ private boolean mWasVerboseLoggingEnabled;
+ private boolean mWasScanThrottleEnabled;
private static final int STATE_NULL = 0;
private static final int STATE_WIFI_CHANGING = 1;
@@ -113,6 +116,18 @@
mContext.registerReceiver(mReceiver, mIntentFilter);
mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
assertThat(mWifiManager).isNotNull();
+
+ // turn on verbose logging for tests
+ mWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions(
+ () -> mWifiManager.isVerboseLoggingEnabled());
+ ShellIdentityUtils.invokeWithShellPermissions(
+ () -> mWifiManager.setVerboseLoggingEnabled(true));
+ // Disable scan throttling for tests.
+ mWasScanThrottleEnabled = ShellIdentityUtils.invokeWithShellPermissions(
+ () -> mWifiManager.isScanThrottleEnabled());
+ ShellIdentityUtils.invokeWithShellPermissions(
+ () -> mWifiManager.setScanThrottleEnabled(false));
+
mWifiLock = mWifiManager.createWifiLock(TAG);
mWifiLock.acquire();
if (!mWifiManager.isWifiEnabled())
@@ -133,6 +148,10 @@
mContext.unregisterReceiver(mReceiver);
if (!mWifiManager.isWifiEnabled())
setWifiEnabled(true);
+ ShellIdentityUtils.invokeWithShellPermissions(
+ () -> mWifiManager.setScanThrottleEnabled(mWasScanThrottleEnabled));
+ ShellIdentityUtils.invokeWithShellPermissions(
+ () -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled));
Thread.sleep(ENABLE_WAIT_MSEC);
super.tearDown();
}
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiFeature.java b/tests/cts/net/src/android/net/wifi/cts/WifiFeature.java
index 63fa1dd..3e9fef4 100644
--- a/tests/cts/net/src/android/net/wifi/cts/WifiFeature.java
+++ b/tests/cts/net/src/android/net/wifi/cts/WifiFeature.java
@@ -20,12 +20,12 @@
import android.content.pm.PackageManager;
public class WifiFeature {
- static boolean isWifiSupported(Context context) {
+ public static boolean isWifiSupported(Context context) {
PackageManager packageManager = context.getPackageManager();
return packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI);
}
- static boolean isP2pSupported(Context context) {
+ public static boolean isP2pSupported(Context context) {
PackageManager packageManager = context.getPackageManager();
return packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT);
}
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiHotspot2Test.java b/tests/cts/net/src/android/net/wifi/cts/WifiHotspot2Test.java
index 96e1caa..a05b81b 100644
--- a/tests/cts/net/src/android/net/wifi/cts/WifiHotspot2Test.java
+++ b/tests/cts/net/src/android/net/wifi/cts/WifiHotspot2Test.java
@@ -18,23 +18,45 @@
import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NONE;
+import android.net.Uri;
+import android.net.wifi.hotspot2.OsuProvider;
import android.net.wifi.hotspot2.PasspointConfiguration;
import android.net.wifi.hotspot2.pps.Credential;
import android.net.wifi.hotspot2.pps.HomeSp;
import android.test.AndroidTestCase;
+import android.text.TextUtils;
+import java.lang.reflect.Constructor;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
public class WifiHotspot2Test extends AndroidTestCase {
static final int SIM_CREDENTIAL = 0;
static final int USER_CREDENTIAL = 1;
static final int CERT_CREDENTIAL = 2;
-
+ private static final String TEST_SSID = "TEST SSID";
+ private static final String TEST_FRIENDLY_NAME = "Friendly Name";
+ private static final Map<String, String> TEST_FRIENDLY_NAMES =
+ new HashMap<String, String>() {
+ {
+ put("en", TEST_FRIENDLY_NAME);
+ put("kr", TEST_FRIENDLY_NAME + 2);
+ put("jp", TEST_FRIENDLY_NAME + 3);
+ }
+ };
+ private static final String TEST_SERVICE_DESCRIPTION = "Dummy Service";
+ private static final Uri TEST_SERVER_URI = Uri.parse("https://test.com");
+ private static final String TEST_NAI = "test.access.com";
+ private static final List<Integer> TEST_METHOD_LIST =
+ Arrays.asList(1 /* METHOD_SOAP_XML_SPP */);
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -434,4 +456,33 @@
return createCredential(userCred, null, null, null, null,
FakeKeys.CA_CERT0);
}
+
+ /**
+ * Tests {@link OsuProvider#getFriendlyName()} and {@link OsuProvider#getServerUri()} methods.
+ * <p>
+ * Test that getting a set friendly name and server URI produces the same value
+ */
+ public void testOsuProviderGetters() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
+
+ // Using Java reflection to construct an OsuProvider instance because its constructor is
+ // hidden and not available to apps.
+ Class<?> osuProviderClass = Class.forName("android.net.wifi.hotspot2.OsuProvider");
+ Constructor<?> osuProviderClassConstructor = osuProviderClass.getConstructor(String.class,
+ Map.class, String.class, Uri.class, String.class, List.class);
+
+ OsuProvider osuProvider = (OsuProvider) osuProviderClassConstructor.newInstance(TEST_SSID,
+ TEST_FRIENDLY_NAMES, TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI,
+ TEST_METHOD_LIST);
+ String lang = Locale.getDefault().getLanguage();
+ String friendlyName = TEST_FRIENDLY_NAMES.get(lang);
+ if (TextUtils.isEmpty(friendlyName)) {
+ friendlyName = TEST_FRIENDLY_NAMES.get("en");
+ }
+ assertEquals(friendlyName, osuProvider.getFriendlyName());
+ assertEquals(TEST_SERVER_URI, osuProvider.getServerUri());
+ }
}
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 2e3f188..3153149 100644
--- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -32,7 +32,6 @@
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
-import android.net.util.MacAddressUtils;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.MacAddress;
@@ -40,15 +39,28 @@
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkRequest;
+import android.net.TetheringManager;
+import android.net.Uri;
+import android.net.util.MacAddressUtils;
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;
import android.net.wifi.WifiManager.WifiLock;
import android.net.wifi.WifiNetworkConnectionStatistics;
import android.net.wifi.hotspot2.ConfigParser;
+import android.net.wifi.hotspot2.OsuProvider;
import android.net.wifi.hotspot2.PasspointConfiguration;
+import android.net.wifi.hotspot2.ProvisioningCallback;
+import android.net.wifi.hotspot2.pps.Credential;
+import android.net.wifi.hotspot2.pps.HomeSp;
+import android.os.Handler;
+import android.os.HandlerExecutor;
+import android.os.HandlerThread;
import android.os.Process;
import android.os.SystemClock;
import android.os.UserHandle;
@@ -72,12 +84,18 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.lang.reflect.Constructor;
import java.net.HttpURLConnection;
import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.Objects;
-import java.util.concurrent.Callable;
+import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
@@ -92,6 +110,7 @@
private WifiManager mWifiManager;
private ConnectivityManager mConnectivityManager;
+ private TetheringManager mTetheringManager;
private WifiLock mWifiLock;
private static MySync mMySync;
private List<ScanResult> mScanResults = null;
@@ -99,6 +118,8 @@
private final Object mLock = new Object();
private UiDevice mUiDevice;
private boolean mWasVerboseLoggingEnabled;
+ private boolean mWasScanThrottleEnabled;
+ private SoftApConfiguration mOriginalSoftApConfig = null;
// Please refer to WifiManager
private static final int MIN_RSSI = -100;
@@ -119,7 +140,7 @@
private static final int SCAN_TIMEOUT_MSEC = 9000;
private static final int TIMEOUT_MSEC = 6000;
private static final int WAIT_MSEC = 60;
- private static final int DURATION = 10_000;
+ private static final int TEST_WAIT_DURATION_MS = 10_000;
private static final int DURATION_SCREEN_TOGGLE = 2000;
private static final int DURATION_SETTINGS_TOGGLE = 1_000;
private static final int WIFI_SCAN_TEST_INTERVAL_MILLIS = 60 * 1000;
@@ -179,6 +200,54 @@
}
}
};
+ // Initialize with an invalid status value (0)
+ private int mProvisioningStatus = 0;
+ // Initialize with an invalid status value (0)
+ private int mProvisioningFailureStatus = 0;
+ private boolean mProvisioningComplete = false;
+ private ProvisioningCallback mProvisioningCallback = new ProvisioningCallback() {
+ @Override
+ public void onProvisioningFailure(int status) {
+ synchronized (mLock) {
+ mProvisioningFailureStatus = status;
+ mLock.notify();
+ }
+ }
+
+ @Override
+ public void onProvisioningStatus(int status) {
+ synchronized (mLock) {
+ mProvisioningStatus = status;
+ mLock.notify();
+ }
+ }
+
+ @Override
+ public void onProvisioningComplete() {
+ mProvisioningComplete = true;
+ }
+ };
+ private static final String TEST_SSID = "TEST SSID";
+ private static final String TEST_FRIENDLY_NAME = "Friendly Name";
+ private static final Map<String, String> TEST_FRIENDLY_NAMES =
+ new HashMap<String, String>() {
+ {
+ put("en", TEST_FRIENDLY_NAME);
+ put("kr", TEST_FRIENDLY_NAME + 2);
+ put("jp", TEST_FRIENDLY_NAME + 3);
+ }
+ };
+ private static final String TEST_SERVICE_DESCRIPTION = "Dummy Service";
+ private static final Uri TEST_SERVER_URI = Uri.parse("https://test.com");
+ private static final String TEST_NAI = "test.access.com";
+ private static final List<Integer> TEST_METHOD_LIST =
+ Arrays.asList(1 /* METHOD_SOAP_XML_SPP */);
+ private final HandlerThread mHandlerThread = new HandlerThread("WifiManagerTest");
+ protected final Executor mExecutor;
+ {
+ mHandlerThread.start();
+ mExecutor = new HandlerExecutor(new Handler(mHandlerThread.getLooper()));
+ }
@Override
protected void setUp() throws Exception {
@@ -201,13 +270,20 @@
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(
() -> mWifiManager.isVerboseLoggingEnabled());
ShellIdentityUtils.invokeWithShellPermissions(
() -> mWifiManager.setVerboseLoggingEnabled(true));
+ // Disable scan throttling for tests.
+ mWasScanThrottleEnabled = ShellIdentityUtils.invokeWithShellPermissions(
+ () -> mWifiManager.isScanThrottleEnabled());
+ ShellIdentityUtils.invokeWithShellPermissions(
+ () -> mWifiManager.setScanThrottleEnabled(false));
mWifiLock = mWifiManager.createWifiLock(TAG);
mWifiLock.acquire();
@@ -215,7 +291,7 @@
setWifiEnabled(true);
mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
turnScreenOnNoDelay();
- Thread.sleep(DURATION);
+ Thread.sleep(TEST_WAIT_DURATION_MS);
assertTrue(mWifiManager.isWifiEnabled());
synchronized (mMySync) {
mMySync.expectedState = STATE_NULL;
@@ -224,6 +300,10 @@
List<WifiConfiguration> 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
@@ -238,8 +318,13 @@
mWifiLock.release();
mContext.unregisterReceiver(mReceiver);
ShellIdentityUtils.invokeWithShellPermissions(
+ () -> mWifiManager.setScanThrottleEnabled(mWasScanThrottleEnabled));
+ ShellIdentityUtils.invokeWithShellPermissions(
() -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled));
- Thread.sleep(DURATION);
+ // restore original softap config
+ ShellIdentityUtils.invokeWithShellPermissions(
+ () -> mWifiManager.setSoftApConfiguration(mOriginalSoftApConfig));
+ Thread.sleep(TEST_WAIT_DURATION_MS);
super.tearDown();
}
@@ -357,7 +442,7 @@
+ " empty when location is disabled!");
}
setWifiEnabled(false);
- Thread.sleep(DURATION);
+ Thread.sleep(TEST_WAIT_DURATION_MS);
startScan();
if (mWifiManager.isScanAlwaysAvailable() && isScanCurrentlyAvailable()) {
// Make sure at least one AP is found.
@@ -508,6 +593,140 @@
}
}
+ public class TestSoftApCallback implements WifiManager.SoftApCallback {
+ Object softApLock;
+ int currentState;
+ int currentFailureReason;
+ List<WifiClient> 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<WifiClient> 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<WifiClient> 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;
@@ -558,12 +777,15 @@
try {
mWifiManager.startLocalOnlyHotspot(callback, null);
// now wait for callback
- mLock.wait(DURATION);
+ mLock.wait(TEST_WAIT_DURATION_MS);
} catch (InterruptedException e) {
}
// 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,
@@ -649,7 +871,7 @@
boolean wifiEnabled = mWifiManager.isWifiEnabled();
// now we should fail to toggle wifi state.
assertFalse(mWifiManager.setWifiEnabled(!wifiEnabled));
- Thread.sleep(DURATION);
+ Thread.sleep(TEST_WAIT_DURATION_MS);
assertEquals(wifiEnabled, mWifiManager.isWifiEnabled());
}
@@ -1057,8 +1279,12 @@
Thread.sleep(DURATION_SCREEN_TOGGLE);
}
- private void turnScreenOff() throws Exception {
+ private void turnScreenOffNoDelay() throws Exception {
mUiDevice.executeShellCommand("input keyevent KEYCODE_SLEEP");
+ }
+
+ private void turnScreenOff() throws Exception {
+ turnScreenOffNoDelay();
// Since the screen on/off intent is ordered, they will not be sent right now.
Thread.sleep(DURATION_SCREEN_TOGGLE);
}
@@ -1158,6 +1384,180 @@
> 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();
+ TestExecutor executor = new TestExecutor();
+ TestSoftApCallback callback = new TestSoftApCallback(mLock);
+ try {
+ uiAutomation.adoptShellPermissionIdentity();
+ turnOffWifiAndTetheredHotspotIfEnabled();
+ 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 {
+ mWifiManager.unregisterSoftApCallback(callback);
+ uiAutomation.dropShellPermissionIdentity();
+ }
+ }
+
+ /**
+ * Verify that startTetheredHotspot with specific channel config.
+ * @throws Exception
+ */
+ public void testStartTetheredHotspotWithChannelConfigAndSoftApStateAndInfoCallback()
+ throws Exception {
+ UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+ TestExecutor executor = new TestExecutor();
+ TestSoftApCallback callback = new TestSoftApCallback(mLock);
+ try {
+ uiAutomation.adoptShellPermissionIdentity();
+ turnOffWifiAndTetheredHotspotIfEnabled();
+ 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 {
+ mWifiManager.unregisterSoftApCallback(callback);
+ uiAutomation.dropShellPermissionIdentity();
+ }
+ }
+
private static class TestActionListener implements WifiManager.ActionListener {
private final Object mLock;
public boolean onSuccessCalled = false;
@@ -1220,7 +1620,7 @@
mWifiManager.connect(savedNetworks.get(0), actionListener);
}
// now wait for callback
- mLock.wait(DURATION);
+ mLock.wait(TEST_WAIT_DURATION_MS);
} catch (InterruptedException e) {
}
}
@@ -1299,7 +1699,7 @@
.build(),
networkCallbackListener);
// now wait for callback
- mLock.wait(DURATION);
+ mLock.wait(TEST_WAIT_DURATION_MS);
} catch (InterruptedException e) {
}
}
@@ -1347,7 +1747,7 @@
modSavedNetwork.meteredOverride = WifiConfiguration.METERED_OVERRIDE_METERED;
mWifiManager.save(modSavedNetwork, actionListener);
// now wait for callback
- mLock.wait(DURATION);
+ mLock.wait(TEST_WAIT_DURATION_MS);
} catch (InterruptedException e) {
}
}
@@ -1395,7 +1795,7 @@
try {
mWifiManager.forget(newNetworkId, actionListener);
// now wait for callback
- mLock.wait(DURATION);
+ mLock.wait(TEST_WAIT_DURATION_MS);
} catch (InterruptedException e) {
}
}
@@ -1472,13 +1872,107 @@
mWifiManager.isPreferredNetworkOffloadSupported();
}
+ /** Test that PNO scans reconnects us when the device is disconnected and the screen is off. */
+ public void testPnoScan() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
+ if (!mWifiManager.isPreferredNetworkOffloadSupported()) {
+ // skip the test if PNO scanning is not supported
+ return;
+ }
+
+ // make sure we're connected
+ waitForConnection();
+
+ WifiInfo currentNetwork = ShellIdentityUtils.invokeWithShellPermissions(
+ mWifiManager::getConnectionInfo);
+
+ // disable all networks that aren't already disabled
+ List<WifiConfiguration> savedNetworks = ShellIdentityUtils.invokeWithShellPermissions(
+ mWifiManager::getConfiguredNetworks);
+ Set<Integer> disabledNetworkIds = new HashSet<>();
+ for (WifiConfiguration config : savedNetworks) {
+ if (config.getNetworkSelectionStatus().getNetworkSelectionDisableReason()
+ == WifiConfiguration.NetworkSelectionStatus.DISABLED_NONE) {
+ ShellIdentityUtils.invokeWithShellPermissions(
+ () -> mWifiManager.disableNetwork(config.networkId));
+ disabledNetworkIds.add(config.networkId);
+ }
+ }
+
+ try {
+ // wait for disconnection from current network
+ waitForDisconnection();
+
+ // turn screen off
+ turnScreenOffNoDelay();
+
+ // re-enable the current network - this will trigger PNO
+ ShellIdentityUtils.invokeWithShellPermissions(
+ () -> mWifiManager.enableNetwork(currentNetwork.getNetworkId(), false));
+ disabledNetworkIds.remove(currentNetwork.getNetworkId());
+
+ // PNO should reconnect us back to the network we disconnected from
+ waitForConnection();
+ } finally {
+ // re-enable disabled networks
+ for (int disabledNetworkId : disabledNetworkIds) {
+ ShellIdentityUtils.invokeWithShellPermissions(
+ () -> mWifiManager.enableNetwork(disabledNetworkId, false));
+ }
+ }
+ }
+
+ /**
+ * Tests {@link WifiManager#isTdlsSupported()} does not crash.
+ */
+ public void testIsTdlsSupported() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
+ mWifiManager.isTdlsSupported();
+ }
+
+ /**
+ * Tests {@link WifiManager#isStaApConcurrencySupported().
+ */
+ public void testIsStaApConcurrencySupported() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
+ // check that softap mode is supported by the device
+ if (!mWifiManager.isPortableHotspotSupported()) {
+ return;
+ }
+ assertTrue(mWifiManager.isWifiEnabled());
+
+ boolean isStaApConcurrencySupported = mWifiManager.isStaApConcurrencySupported();
+ // start local only hotspot.
+ TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot();
+ if (isStaApConcurrencySupported) {
+ assertTrue(mWifiManager.isWifiEnabled());
+ } else {
+ // no concurrency, wifi should be disabled.
+ assertFalse(mWifiManager.isWifiEnabled());
+ }
+ stopLocalOnlyHotspot(callback, true);
+
+ assertTrue(mWifiManager.isWifiEnabled());
+ }
+
private static class TestTrafficStateCallback implements WifiManager.TrafficStateCallback {
private final Object mLock;
+ private final int mWaitForState;
public boolean onStateChangedCalled = false;
public int state = -1;
- TestTrafficStateCallback(Object lock) {
+ TestTrafficStateCallback(Object lock, int waitForState) {
mLock = lock;
+ mWaitForState = waitForState;
}
@Override
@@ -1486,7 +1980,9 @@
synchronized (mLock) {
onStateChangedCalled = true;
this.state = state;
- mLock.notify();
+ if (mWaitForState == state) { // only notify if we got the expected state.
+ mLock.notify();
+ }
}
}
}
@@ -1520,7 +2016,8 @@
// skip the test if WiFi is not supported
return;
}
- TestTrafficStateCallback trafficStateCallback = new TestTrafficStateCallback(mLock);
+ TestTrafficStateCallback trafficStateCallback =
+ new TestTrafficStateCallback(mLock, DATA_ACTIVITY_INOUT);
UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
try {
uiAutomation.adoptShellPermissionIdentity();
@@ -1537,7 +2034,7 @@
// Send some traffic to trigger the traffic state change callbacks.
sendTraffic();
// now wait for callback
- mLock.wait(DURATION);
+ mLock.wait(TEST_WAIT_DURATION_MS);
} catch (InterruptedException e) {
}
}
@@ -1677,7 +2174,7 @@
uiAutomation.adoptShellPermissionIdentity();
// These below API's only work with privileged permissions (obtained via shell identity
// for test)
- savedNetworks = mWifiManager.getConfiguredNetworks();
+ savedNetworks = mWifiManager.getPrivilegedConfiguredNetworks();
mWifiManager.factoryReset();
// Ensure all the saved networks are removed.
@@ -1686,7 +2183,9 @@
// Restore the original saved networks.
if (savedNetworks != null) {
for (WifiConfiguration network : savedNetworks) {
- mWifiManager.save(network, null);
+ network.networkId = WifiConfiguration.INVALID_NETWORK_ID;
+ int networkId = mWifiManager.addNetwork(network);
+ mWifiManager.enableNetwork(networkId, false);
}
}
uiAutomation.dropShellPermissionIdentity();
@@ -1760,7 +2259,7 @@
.build(),
networkCallbackListener);
// now wait for callback
- mLock.wait(DURATION);
+ mLock.wait(TEST_WAIT_DURATION_MS);
} catch (InterruptedException e) {
}
}
@@ -1940,4 +2439,88 @@
assertTrue(is11axSupportedEnabled);
}
}
+
+ private static PasspointConfiguration createPasspointConfiguration() {
+ PasspointConfiguration config = new PasspointConfiguration();
+ HomeSp homeSp = new HomeSp();
+ homeSp.setFqdn("test.com");
+ homeSp.setFriendlyName("friendly name");
+ homeSp.setRoamingConsortiumOis(new long[]{0x55, 0x66});
+ config.setHomeSp(homeSp);
+ Credential.SimCredential simCred = new Credential.SimCredential();
+ simCred.setImsi("123456*");
+ simCred.setEapType(23 /* EAP_AKA */);
+ Credential cred = new Credential();
+ cred.setRealm("realm");
+ cred.setSimCredential(simCred);
+ config.setCredential(cred);
+
+ return config;
+ }
+
+ /**
+ * Tests {@link WifiManager#addOrUpdatePasspointConfiguration(PasspointConfiguration)}
+ * adds a Passpoint configuration correctly by getting it once it is added, and comparing it
+ * to the local copy of the configuration.
+ */
+ public void testAddOrUpdatePasspointConfiguration() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
+
+ // Create and install a Passpoint configuration
+ PasspointConfiguration passpointConfiguration = createPasspointConfiguration();
+ mWifiManager.addOrUpdatePasspointConfiguration(passpointConfiguration);
+
+ // Compare configurations
+ List<PasspointConfiguration> configurations = mWifiManager.getPasspointConfigurations();
+ assertNotNull(configurations);
+ assertEquals(passpointConfiguration, configurations.get(0));
+
+ // Clean up
+ mWifiManager.removePasspointConfiguration(passpointConfiguration.getHomeSp().getFqdn());
+ }
+
+ /**
+ * Tests that
+ * {@link WifiManager#startSubscriptionProvisioning(OsuProvider, Executor, ProvisioningCallback)}
+ * starts a subscription provisioning, and confirm a status callback invoked once.
+ */
+ public void testStartSubscriptionProvisioning() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
+
+ // Using Java reflection to construct an OsuProvider instance because its constructor is
+ // hidden and not available to apps.
+ Class<?> osuProviderClass = Class.forName("android.net.wifi.hotspot2.OsuProvider");
+ Constructor<?> osuProviderClassConstructor = osuProviderClass.getConstructor(String.class,
+ Map.class, String.class, Uri.class, String.class, List.class);
+
+ OsuProvider osuProvider = (OsuProvider) osuProviderClassConstructor.newInstance(TEST_SSID,
+ TEST_FRIENDLY_NAMES, TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI,
+ TEST_METHOD_LIST);
+
+ UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+ try {
+ uiAutomation.adoptShellPermissionIdentity();
+ synchronized (mLock) {
+ // Start a subscription provisioning for a non-existent Passpoint R2 AP
+ mWifiManager.startSubscriptionProvisioning(osuProvider, mExecutor,
+ mProvisioningCallback);
+ mLock.wait(TEST_WAIT_DURATION_MS);
+ }
+ } finally {
+ uiAutomation.dropShellPermissionIdentity();
+ }
+
+ // Expect only a single callback event, connecting. Since AP doesn't exist, it ends here
+ assertEquals(ProvisioningCallback.OSU_STATUS_AP_CONNECTING, mProvisioningStatus);
+ // No failure callbacks expected
+ assertEquals(0, mProvisioningFailureStatus);
+ // No completion callback expected
+ assertFalse(mProvisioningComplete);
+ }
}
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java
index 6e19a21..c74c177 100644
--- a/tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java
@@ -16,16 +16,12 @@
package android.net.wifi.cts;
-import static org.junit.Assert.assertNotNull;
-
-import android.net.wifi.SoftApConfiguration;
-import android.net.wifi.WifiConfiguration;
+import android.app.ActivityManager;
import android.net.wifi.WifiMigration;
+import android.os.UserHandle;
+import android.os.UserManager;
import android.test.AndroidTestCase;
-import java.util.Arrays;
-import java.util.List;
-
public class WifiMigrationTest extends AndroidTestCase {
private static final String TEST_SSID_UNQUOTED = "testSsid1";
@@ -49,42 +45,7 @@
}
/**
- * Tests {@link android.net.wifi.WifiMigration.ConfigStoreMigrationData} class.
- */
- public void testWifiMigrationConfigStoreDataBuilder() throws Exception {
- if (!WifiFeature.isWifiSupported(getContext())) {
- // skip the test if WiFi is not supported
- return;
- }
- WifiConfiguration savedNetwork1 = new WifiConfiguration();
- savedNetwork1.SSID = "\"test1\"";
- WifiConfiguration savedNetwork2 = new WifiConfiguration();
- savedNetwork1.SSID = "\"test2\"";
- List<WifiConfiguration> savedNetworks = Arrays.asList(savedNetwork1, savedNetwork2);
-
- SoftApConfiguration softApConfiguration = new SoftApConfiguration.Builder()
- .setSsid("\"test3\"")
- .build();
-
- WifiMigration.ConfigStoreMigrationData migrationData =
- new WifiMigration.ConfigStoreMigrationData.Builder()
- .setUserSavedNetworkConfigurations(savedNetworks)
- .setUserSoftApConfiguration(softApConfiguration)
- .build();
-
- assertNotNull(migrationData);
- assertEquals(savedNetworks.size(),
- migrationData.getUserSavedNetworkConfigurations().size());
- assertEquals(savedNetwork1.SSID,
- migrationData.getUserSavedNetworkConfigurations().get(0).SSID);
- assertEquals(savedNetwork2.SSID,
- migrationData.getUserSavedNetworkConfigurations().get(1).SSID);
- assertEquals(softApConfiguration.getSsid(),
- migrationData.getUserSoftApConfiguration().getSsid());
- }
-
- /**
- * Tests {@link android.net.wifi.WifiMigration.ConfigStoreMigrationData} class.
+ * Tests {@link android.net.wifi.WifiMigration.SettingsMigrationData.Builder} class.
*/
public void testWifiMigrationSettingsDataBuilder() throws Exception {
if (!WifiFeature.isWifiSupported(getContext())) {
@@ -111,4 +72,67 @@
assertTrue(migrationData.isVerboseLoggingEnabled());
assertEquals(TEST_SSID_UNQUOTED, migrationData.getP2pDeviceName());
}
+
+ /**
+ * Tests {@link android.net.wifi.WifiMigration.SettingsMigrationData} class.
+ */
+ public void testWifiMigrationSettings() throws Exception {
+ try {
+ WifiMigration.loadFromSettings(getContext());
+ } catch (Exception ignore) {
+ }
+ }
+
+ /**
+ * Tests {@link WifiMigration#convertAndRetrieveSharedConfigStoreFile(int)},
+ * {@link WifiMigration#convertAndRetrieveUserConfigStoreFile(int, UserHandle)},
+ * {@link WifiMigration#removeSharedConfigStoreFile(int)} and
+ * {@link WifiMigration#removeUserConfigStoreFile(int, UserHandle)}.
+ */
+ public void testWifiMigrationConfigStore() throws Exception {
+ try {
+ WifiMigration.convertAndRetrieveSharedConfigStoreFile(
+ WifiMigration.STORE_FILE_SHARED_GENERAL);
+ } catch (Exception ignore) {
+ }
+ try {
+ WifiMigration.convertAndRetrieveSharedConfigStoreFile(
+ WifiMigration.STORE_FILE_SHARED_SOFTAP);
+ } catch (Exception ignore) {
+ }
+ try {
+ WifiMigration.convertAndRetrieveUserConfigStoreFile(
+ WifiMigration.STORE_FILE_USER_GENERAL,
+ UserHandle.of(ActivityManager.getCurrentUser()));
+ } catch (Exception ignore) {
+ }
+ try {
+ WifiMigration.convertAndRetrieveUserConfigStoreFile(
+ WifiMigration.STORE_FILE_USER_NETWORK_SUGGESTIONS,
+ UserHandle.of(ActivityManager.getCurrentUser()));
+ } catch (Exception ignore) {
+ }
+ try {
+ WifiMigration.removeSharedConfigStoreFile(
+ WifiMigration.STORE_FILE_SHARED_GENERAL);
+ } catch (Exception ignore) {
+ }
+ try {
+ WifiMigration.removeSharedConfigStoreFile(
+ WifiMigration.STORE_FILE_SHARED_SOFTAP);
+ } catch (Exception ignore) {
+ }
+ try {
+ WifiMigration.removeUserConfigStoreFile(
+ WifiMigration.STORE_FILE_USER_GENERAL,
+ UserHandle.of(ActivityManager.getCurrentUser()));
+ } catch (Exception ignore) {
+ }
+ try {
+ WifiMigration.removeUserConfigStoreFile(
+ WifiMigration.STORE_FILE_USER_NETWORK_SUGGESTIONS,
+ UserHandle.of(ActivityManager.getCurrentUser()));
+ } catch (Exception ignore) {
+ }
+ }
}
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java
index 96cf45f..83018fa 100644
--- a/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java
@@ -31,6 +31,7 @@
import android.net.NetworkRequest;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.NetworkRequestMatchCallback;
@@ -70,6 +71,7 @@
private final Object mUiLock = new Object();
private WifiConfiguration mTestNetwork;
private boolean mWasVerboseLoggingEnabled;
+ private boolean mWasScanThrottleEnabled;
private static final int DURATION = 10_000;
private static final int DURATION_UI_INTERACTION = 15_000;
@@ -92,6 +94,11 @@
() -> mWifiManager.isVerboseLoggingEnabled());
ShellIdentityUtils.invokeWithShellPermissions(
() -> mWifiManager.setVerboseLoggingEnabled(true));
+ // Disable scan throttling for tests.
+ mWasScanThrottleEnabled = ShellIdentityUtils.invokeWithShellPermissions(
+ () -> mWifiManager.isScanThrottleEnabled());
+ ShellIdentityUtils.invokeWithShellPermissions(
+ () -> mWifiManager.setScanThrottleEnabled(false));
if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true);
mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
@@ -126,6 +133,8 @@
ShellIdentityUtils.invokeWithShellPermissions(
() -> mWifiManager.enableNetwork(mTestNetwork.networkId, false));
ShellIdentityUtils.invokeWithShellPermissions(
+ () -> mWifiManager.setScanThrottleEnabled(mWasScanThrottleEnabled));
+ ShellIdentityUtils.invokeWithShellPermissions(
() -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled));
super.tearDown();
}
@@ -506,4 +515,44 @@
.build();
testUserRejectionWithSpecifier(specifier);
}
+
+ /**
+ * Tests the builder for WPA2 enterprise networks.
+ * Note: Can't do end to end tests for such networks in CTS environment.
+ */
+ public void testBuilderForWpa2Enterprise() {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
+ WifiNetworkSpecifier specifier1 = new WifiNetworkSpecifier.Builder()
+ .setSsid(WifiInfo.sanitizeSsid(mTestNetwork.SSID))
+ .setWpa2EnterpriseConfig(new WifiEnterpriseConfig())
+ .build();
+ WifiNetworkSpecifier specifier2 = new WifiNetworkSpecifier.Builder()
+ .setSsid(WifiInfo.sanitizeSsid(mTestNetwork.SSID))
+ .setWpa2EnterpriseConfig(new WifiEnterpriseConfig())
+ .build();
+ assertThat(specifier1.satisfiedBy(specifier2)).isTrue();
+ }
+
+ /**
+ * Tests the builder for WPA3 enterprise networks.
+ * Note: Can't do end to end tests for such networks in CTS environment.
+ */
+ public void testBuilderForWpa3Enterprise() {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
+ WifiNetworkSpecifier specifier1 = new WifiNetworkSpecifier.Builder()
+ .setSsid(WifiInfo.sanitizeSsid(mTestNetwork.SSID))
+ .setWpa3EnterpriseConfig(new WifiEnterpriseConfig())
+ .build();
+ WifiNetworkSpecifier specifier2 = new WifiNetworkSpecifier.Builder()
+ .setSsid(WifiInfo.sanitizeSsid(mTestNetwork.SSID))
+ .setWpa3EnterpriseConfig(new WifiEnterpriseConfig())
+ .build();
+ assertThat(specifier1.satisfiedBy(specifier2)).isTrue();
+ }
}
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java
index 994b6c9..e73abb8 100644
--- a/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java
@@ -17,6 +17,7 @@
package android.net.wifi.cts;
import static android.net.wifi.WifiEnterpriseConfig.Eap.AKA;
+import static android.net.wifi.WifiEnterpriseConfig.Eap.WAPI_CERT;
import android.net.MacAddress;
import android.net.wifi.WifiEnterpriseConfig;
@@ -199,6 +200,28 @@
}
/**
+ * Tests {@link android.net.wifi.WifiNetworkSuggestion.Builder} class.
+ */
+ public void testBuilderWithWapiEnterprise() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
+ WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
+ enterpriseConfig.setEapMethod(WAPI_CERT);
+ WifiNetworkSuggestion suggestion =
+ createBuilderWithCommonParams()
+ .setWapiEnterpriseConfig(enterpriseConfig)
+ .build();
+ validateCommonParams(suggestion);
+ assertNull(suggestion.getPassphrase());
+ assertNotNull(suggestion.getEnterpriseConfig());
+ assertEquals(enterpriseConfig.getEapMethod(),
+ suggestion.getEnterpriseConfig().getEapMethod());
+ assertNull(suggestion.getPasspointConfig());
+ }
+
+ /**
* Helper function for creating a {@link PasspointConfiguration} for testing.
*
* @return {@link PasspointConfiguration}
diff --git a/tests/cts/net/src/android/net/wifi/nl80211/cts/DeviceWiphyCapabilitiesTest.java b/tests/cts/net/src/android/net/wifi/nl80211/cts/DeviceWiphyCapabilitiesTest.java
new file mode 100644
index 0000000..d8f5e57
--- /dev/null
+++ b/tests/cts/net/src/android/net/wifi/nl80211/cts/DeviceWiphyCapabilitiesTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2020 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.wifi.nl80211.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.net.wifi.ScanResult;
+import android.net.wifi.cts.WifiFeature;
+import android.net.wifi.nl80211.DeviceWiphyCapabilities;
+import android.os.Parcel;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** CTS tests for {@link DeviceWiphyCapabilities}. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class DeviceWiphyCapabilitiesTest {
+
+ @Before
+ public void setUp() {
+ Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ // skip tests if Wifi is not supported
+ assumeTrue(WifiFeature.isWifiSupported(context));
+ }
+
+ /**
+ * Test that a {@link DeviceWiphyCapabilities} object can be serialized and deserialized,
+ * while keeping its values unchanged.
+ */
+ @Test
+ public void canSerializeAndDeserialize() {
+ DeviceWiphyCapabilities capa = new DeviceWiphyCapabilities();
+
+ capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true);
+ capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true);
+ capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false);
+
+ Parcel parcel = Parcel.obtain();
+ capa.writeToParcel(parcel, 0);
+ // Rewind the pointer to the head of the parcel.
+ parcel.setDataPosition(0);
+ DeviceWiphyCapabilities capaDeserialized =
+ DeviceWiphyCapabilities.CREATOR.createFromParcel(parcel);
+
+ assertThat(capaDeserialized.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11N)).isTrue();
+ assertThat(capaDeserialized.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AC))
+ .isTrue();
+ assertThat(capaDeserialized.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AX))
+ .isFalse();
+ assertThat(capaDeserialized).isEqualTo(capa);
+ assertThat(capaDeserialized.hashCode()).isEqualTo(capa.hashCode());
+ }
+
+ /** Test mapping wifi standard support into channel width support */
+ @Test
+ public void testMappingWifiStandardIntoChannelWidthSupport() {
+ DeviceWiphyCapabilities capa = new DeviceWiphyCapabilities();
+
+ capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, false);
+ capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, false);
+ capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false);
+ assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)).isTrue();
+ assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)).isFalse();
+ assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)).isFalse();
+
+ capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true);
+ assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)).isTrue();
+ assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)).isTrue();
+ assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)).isFalse();
+
+ capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true);
+ assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)).isTrue();
+ assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)).isTrue();
+ assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)).isTrue();
+ }
+}
diff --git a/tests/cts/net/src/android/net/wifi/nl80211/cts/NativeWifiClientTest.java b/tests/cts/net/src/android/net/wifi/nl80211/cts/NativeWifiClientTest.java
new file mode 100644
index 0000000..3149b54
--- /dev/null
+++ b/tests/cts/net/src/android/net/wifi/nl80211/cts/NativeWifiClientTest.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2020 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.wifi.nl80211.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.net.MacAddress;
+import android.net.wifi.cts.WifiFeature;
+import android.net.wifi.nl80211.NativeWifiClient;
+import android.os.Parcel;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** CTS tests for {@link NativeWifiClient}. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class NativeWifiClientTest {
+
+ private static final byte[] TEST_MAC = { 1, 2, 3, 4, 5, 6 };
+
+ @Before
+ public void setUp() {
+ Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ // skip tests if Wifi is not supported
+ assumeTrue(WifiFeature.isWifiSupported(context));
+ }
+
+ @Test
+ public void testGetters() {
+ NativeWifiClient client = new NativeWifiClient(MacAddress.fromBytes(TEST_MAC));
+
+ assertThat(client.getMacAddress().toByteArray()).isEqualTo(TEST_MAC);
+ }
+
+ @Test
+ public void canSerializeAndDeserialize() {
+ NativeWifiClient client = new NativeWifiClient(MacAddress.fromBytes(TEST_MAC));
+
+ Parcel parcel = Parcel.obtain();
+ client.writeToParcel(parcel, 0);
+ // Rewind the pointer to the head of the parcel.
+ parcel.setDataPosition(0);
+ NativeWifiClient clientDeserialized = NativeWifiClient.CREATOR.createFromParcel(parcel);
+
+ assertThat(clientDeserialized.getMacAddress().toByteArray()).isEqualTo(TEST_MAC);
+ assertThat(clientDeserialized).isEqualTo(client);
+ assertThat(clientDeserialized.hashCode()).isEqualTo(client.hashCode());
+ }
+
+ @Test
+ public void testEquals() {
+ NativeWifiClient client = new NativeWifiClient(MacAddress.fromBytes(TEST_MAC));
+ NativeWifiClient client2 =
+ new NativeWifiClient(MacAddress.fromBytes(new byte[] { 7, 8, 9, 10, 11, 12 }));
+
+ assertThat(client2).isNotEqualTo(client);
+ }
+}
diff --git a/tests/cts/net/src/android/net/wifi/nl80211/cts/PnoNetworkTest.java b/tests/cts/net/src/android/net/wifi/nl80211/cts/PnoNetworkTest.java
new file mode 100644
index 0000000..f3a8f05
--- /dev/null
+++ b/tests/cts/net/src/android/net/wifi/nl80211/cts/PnoNetworkTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2020 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.wifi.nl80211.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.net.wifi.cts.WifiFeature;
+import android.net.wifi.nl80211.PnoNetwork;
+import android.os.Parcel;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** CTS tests for {@link PnoNetwork}. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class PnoNetworkTest {
+
+ private static final byte[] TEST_SSID = { 's', 's', 'i', 'd' };
+ private static final int[] TEST_FREQUENCIES = { 2412, 2417, 5035 };
+
+ @Before
+ public void setUp() {
+ Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ // skip tests if Wifi is not supported
+ assumeTrue(WifiFeature.isWifiSupported(context));
+ }
+
+ @Test
+ public void testGetters() {
+ PnoNetwork network = new PnoNetwork();
+ network.setSsid(TEST_SSID);
+ network.setFrequenciesMhz(TEST_FREQUENCIES);
+ network.setHidden(true);
+
+ assertThat(network.getSsid()).isEqualTo(TEST_SSID);
+ assertThat(network.getFrequenciesMhz()).isEqualTo(TEST_FREQUENCIES);
+ assertThat(network.isHidden()).isTrue();
+ }
+
+ @Test
+ public void canSerializeAndDeserialize() {
+ PnoNetwork network = new PnoNetwork();
+ network.setSsid(TEST_SSID);
+ network.setFrequenciesMhz(TEST_FREQUENCIES);
+ network.setHidden(true);
+
+ Parcel parcel = Parcel.obtain();
+ network.writeToParcel(parcel, 0);
+ // Rewind the pointer to the head of the parcel.
+ parcel.setDataPosition(0);
+ PnoNetwork networkDeserialized = PnoNetwork.CREATOR.createFromParcel(parcel);
+
+ assertThat(networkDeserialized.getSsid()).isEqualTo(TEST_SSID);
+ assertThat(networkDeserialized.getFrequenciesMhz()).isEqualTo(TEST_FREQUENCIES);
+ assertThat(networkDeserialized.isHidden()).isTrue();
+ assertThat(networkDeserialized).isEqualTo(network);
+ assertThat(networkDeserialized.hashCode()).isEqualTo(network.hashCode());
+ }
+
+ @Test
+ public void testEquals() {
+ PnoNetwork network = new PnoNetwork();
+ network.setSsid(TEST_SSID);
+ network.setFrequenciesMhz(TEST_FREQUENCIES);
+ network.setHidden(true);
+
+ PnoNetwork network2 = new PnoNetwork();
+ network.setSsid(new byte[] { 'a', 's', 'd', 'f'});
+ network.setFrequenciesMhz(new int[] { 1, 2, 3 });
+ network.setHidden(false);
+
+ assertThat(network2).isNotEqualTo(network);
+ }
+}
diff --git a/tests/cts/net/src/android/net/wifi/nl80211/cts/PnoSettingsTest.java b/tests/cts/net/src/android/net/wifi/nl80211/cts/PnoSettingsTest.java
new file mode 100644
index 0000000..59f5d99
--- /dev/null
+++ b/tests/cts/net/src/android/net/wifi/nl80211/cts/PnoSettingsTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2020 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.wifi.nl80211.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.net.wifi.cts.WifiFeature;
+import android.net.wifi.nl80211.PnoNetwork;
+import android.net.wifi.nl80211.PnoSettings;
+import android.os.Parcel;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.List;
+
+/** CTS tests for {@link PnoSettings}. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class PnoSettingsTest {
+
+ private static List<PnoNetwork> createTestNetworks() {
+ PnoNetwork network1 = new PnoNetwork();
+ network1.setSsid(new byte[] { 's', 's', 'i', 'd' });
+ network1.setFrequenciesMhz(new int[] { 2412, 2417, 5035 });
+ network1.setHidden(true);
+
+ PnoNetwork network2 = new PnoNetwork();
+ network2.setSsid(new byte[] { 'a', 's', 'd', 'f' });
+ network2.setFrequenciesMhz(new int[] { 2422, 2427, 5040 });
+ network2.setHidden(false);
+
+ return Arrays.asList(network1, network2);
+ }
+
+ @Before
+ public void setUp() {
+ Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ // skip tests if Wifi is not supported
+ assumeTrue(WifiFeature.isWifiSupported(context));
+ }
+
+ @Test
+ public void testGetters() {
+ PnoSettings settings = new PnoSettings();
+ settings.setIntervalMillis(1000);
+ settings.setMin2gRssiDbm(-70);
+ settings.setMin5gRssiDbm(-60);
+ settings.setMin6gRssiDbm(-50);
+ settings.setPnoNetworks(createTestNetworks());
+
+ assertThat(settings.getIntervalMillis()).isEqualTo(1000);
+ assertThat(settings.getMin2gRssiDbm()).isEqualTo(-70);
+ assertThat(settings.getMin5gRssiDbm()).isEqualTo(-60);
+ assertThat(settings.getMin6gRssiDbm()).isEqualTo(-50);
+ assertThat(settings.getPnoNetworks()).isEqualTo(createTestNetworks());
+ }
+
+ @Test
+ public void canSerializeAndDeserialize() {
+ PnoSettings settings = new PnoSettings();
+ settings.setIntervalMillis(1000);
+ settings.setMin2gRssiDbm(-70);
+ settings.setMin5gRssiDbm(-60);
+ settings.setMin6gRssiDbm(-50);
+ settings.setPnoNetworks(createTestNetworks());
+
+ Parcel parcel = Parcel.obtain();
+ settings.writeToParcel(parcel, 0);
+ // Rewind the pointer to the head of the parcel.
+ parcel.setDataPosition(0);
+ PnoSettings settingsDeserialized = PnoSettings.CREATOR.createFromParcel(parcel);
+
+ assertThat(settingsDeserialized.getIntervalMillis()).isEqualTo(1000);
+ assertThat(settingsDeserialized.getMin2gRssiDbm()).isEqualTo(-70);
+ assertThat(settingsDeserialized.getMin5gRssiDbm()).isEqualTo(-60);
+ assertThat(settingsDeserialized.getMin6gRssiDbm()).isEqualTo(-50);
+ assertThat(settingsDeserialized.getPnoNetworks()).isEqualTo(createTestNetworks());
+ assertThat(settingsDeserialized).isEqualTo(settings);
+ assertThat(settingsDeserialized.hashCode()).isEqualTo(settings.hashCode());
+ }
+
+ @Test
+ public void testEquals() {
+ PnoSettings settings = new PnoSettings();
+ settings.setIntervalMillis(1000);
+ settings.setMin2gRssiDbm(-70);
+ settings.setMin5gRssiDbm(-60);
+ settings.setMin6gRssiDbm(-50);
+ settings.setPnoNetworks(createTestNetworks());
+
+ PnoSettings settings2 = new PnoSettings();
+ settings.setIntervalMillis(2000);
+ settings.setMin2gRssiDbm(-70);
+ settings.setMin5gRssiDbm(-60);
+ settings.setMin6gRssiDbm(-50);
+ settings.setPnoNetworks(createTestNetworks());
+
+ assertThat(settings2).isNotEqualTo(settings);
+ }
+}
diff --git a/tests/cts/net/src/android/net/wifi/nl80211/cts/RadioChainInfoTest.java b/tests/cts/net/src/android/net/wifi/nl80211/cts/RadioChainInfoTest.java
new file mode 100644
index 0000000..0a76bdb
--- /dev/null
+++ b/tests/cts/net/src/android/net/wifi/nl80211/cts/RadioChainInfoTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2020 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.wifi.nl80211.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.net.wifi.cts.WifiFeature;
+import android.net.wifi.nl80211.RadioChainInfo;
+import android.os.Parcel;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** CTS tests for {@link RadioChainInfo}. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class RadioChainInfoTest {
+
+ private static final int TEST_CHAIN_ID = 1;
+ private static final int TEST_CHAIN_ID2 = 2;
+ private static final int TEST_LEVEL_DBM = -50;
+ private static final int TEST_LEVEL_DBM2 = -80;
+
+ @Before
+ public void setUp() {
+ Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ // skip tests if Wifi is not supported
+ assumeTrue(WifiFeature.isWifiSupported(context));
+ }
+
+ @Test
+ public void testGetters() {
+ RadioChainInfo info = new RadioChainInfo(TEST_CHAIN_ID, TEST_LEVEL_DBM);
+ assertThat(info.getChainId()).isEqualTo(TEST_CHAIN_ID);
+ assertThat(info.getLevelDbm()).isEqualTo(TEST_LEVEL_DBM);
+ }
+
+ @Test
+ public void canSerializeAndDeserialize() {
+ RadioChainInfo info = new RadioChainInfo(TEST_CHAIN_ID, TEST_LEVEL_DBM);
+
+ Parcel parcel = Parcel.obtain();
+ info.writeToParcel(parcel, 0);
+ // Rewind the pointer to the head of the parcel.
+ parcel.setDataPosition(0);
+ RadioChainInfo infoDeserialized = RadioChainInfo.CREATOR.createFromParcel(parcel);
+
+ assertThat(infoDeserialized.getChainId()).isEqualTo(TEST_CHAIN_ID);
+ assertThat(infoDeserialized.getLevelDbm()).isEqualTo(TEST_LEVEL_DBM);
+ assertThat(infoDeserialized).isEqualTo(info);
+ assertThat(infoDeserialized.hashCode()).isEqualTo(info.hashCode());
+ }
+
+ @Test
+ public void testEquals() {
+ RadioChainInfo info = new RadioChainInfo(TEST_CHAIN_ID, TEST_LEVEL_DBM);
+ RadioChainInfo info2 = new RadioChainInfo(TEST_CHAIN_ID2, TEST_LEVEL_DBM2);
+
+ assertThat(info2).isNotEqualTo(info);
+ }
+}
diff --git a/tests/cts/net/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java b/tests/cts/net/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java
new file mode 100644
index 0000000..f1f3010
--- /dev/null
+++ b/tests/cts/net/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2020 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.wifi.nl80211.cts;
+
+import static android.net.wifi.nl80211.WifiNl80211Manager.OemSecurityType;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.net.wifi.ScanResult;
+import android.net.wifi.cts.WifiFeature;
+import android.net.wifi.nl80211.WifiNl80211Manager;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+
+/** CTS tests for {@link WifiNl80211Manager}. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class WifiNl80211ManagerTest {
+
+ private Context mContext;
+
+ @Before
+ public void setUp() {
+ mContext = InstrumentationRegistry.getInstrumentation().getContext();
+ // skip tests if Wifi is not supported
+ assumeTrue(WifiFeature.isWifiSupported(mContext));
+ }
+
+ @Test
+ public void testOemSecurityTypeConstructor() {
+ OemSecurityType securityType = new OemSecurityType(
+ ScanResult.PROTOCOL_WPA,
+ Arrays.asList(ScanResult.KEY_MGMT_PSK, ScanResult.KEY_MGMT_SAE),
+ Arrays.asList(ScanResult.CIPHER_NONE, ScanResult.CIPHER_TKIP),
+ ScanResult.CIPHER_CCMP);
+
+ assertThat(securityType.protocol).isEqualTo(ScanResult.PROTOCOL_WPA);
+ assertThat(securityType.keyManagement)
+ .isEqualTo(Arrays.asList(ScanResult.KEY_MGMT_PSK, ScanResult.KEY_MGMT_SAE));
+ assertThat(securityType.pairwiseCipher)
+ .isEqualTo(Arrays.asList(ScanResult.CIPHER_NONE, ScanResult.CIPHER_TKIP));
+ assertThat(securityType.groupCipher).isEqualTo(ScanResult.CIPHER_CCMP);
+ }
+
+ @Test
+ public void testSendMgmtFrame() {
+ try {
+ WifiNl80211Manager manager = mContext.getSystemService(WifiNl80211Manager.class);
+ manager.sendMgmtFrame("wlan0", new byte[]{}, -1, Runnable::run,
+ new WifiNl80211Manager.SendMgmtFrameCallback() {
+ @Override
+ public void onAck(int elapsedTimeMs) {}
+
+ @Override
+ public void onFailure(int reason) {}
+ });
+ } catch (Exception ignore) {}
+ }
+}
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 d5361d7..49aa47e 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
@@ -18,9 +18,12 @@
import static org.mockito.Mockito.mock;
+import android.net.MacAddress;
import android.net.wifi.ScanResult;
+import android.net.wifi.aware.PeerHandle;
import android.net.wifi.rtt.RangingRequest;
import android.net.wifi.rtt.RangingResult;
+import android.net.wifi.rtt.ResponderLocation;
import android.platform.test.annotations.AppModeFull;
import com.android.compatibility.common.util.DeviceReportLog;
@@ -51,6 +54,9 @@
// Minimum valid RSSI value
private static final int MIN_VALID_RSSI = -100;
+ // Valid Mac Address
+ private static final MacAddress MAC = MacAddress.fromString("00:01:02:03:04:05");
+
/**
* Test Wi-Fi RTT ranging operation:
* - Scan for visible APs for the test AP (which is validated to support IEEE 802.11mc)
@@ -163,7 +169,8 @@
// Analyze results
assertTrue("Wi-Fi RTT failure rate exceeds threshold: FAIL=" + numFailures + ", ITERATIONS="
- + NUM_OF_RTT_ITERATIONS + ", AP RSSI=" + testAp.level,
+ + NUM_OF_RTT_ITERATIONS + ", AP RSSI=" + testAp.level
+ + ", AP SSID=" + testAp.SSID,
numFailures <= NUM_OF_RTT_ITERATIONS * MAX_FAILURE_RATE_PERCENT / 100);
if (numFailures != NUM_OF_RTT_ITERATIONS) {
double distanceAvg = distanceSum / (NUM_OF_RTT_ITERATIONS - numFailures);
@@ -213,4 +220,189 @@
+ "many peers",
false);
}
+
+ /**
+ * Verify ResponderLocation API
+ */
+ public void testRangingToTestApWithResponderLocation() throws InterruptedException {
+ if (!shouldTestWifiRtt(getContext())) {
+ return;
+ }
+ // Scan for IEEE 802.11mc supporting APs
+ ScanResult testAp = scanForTestAp(NUM_SCANS_SEARCHING_FOR_IEEE80211MC_AP);
+ assertTrue(
+ "Cannot find any test APs which support RTT / IEEE 802.11mc - please verify that "
+ + "your test setup includes them!",
+ testAp != null);
+
+ // Perform RTT operations
+ RangingRequest request = new RangingRequest.Builder().addAccessPoint(testAp).build();
+ ResultCallback callback = new ResultCallback();
+ mWifiRttManager.startRanging(request, mExecutor, callback);
+ assertTrue("Wi-Fi RTT results: no callback! ",
+ callback.waitForCallback());
+
+ RangingResult result = callback.getResults().get(0);
+ assertEquals("Ranging request not success",
+ result.getStatus(), RangingResult.STATUS_SUCCESS);
+ ResponderLocation responderLocation = result.getUnverifiedResponderLocation();
+ assertNotNull("ResponderLocation should not be null", responderLocation);
+ assertTrue("ResponderLocation is not valid", responderLocation.isLciSubelementValid());
+
+ // Check LCI related APIs
+ int exceptionCount = 0;
+ int apiCount = 0;
+ try {
+ apiCount++;
+ responderLocation.getLatitudeUncertainty();
+ } catch (IllegalStateException e) {
+ exceptionCount++;
+ }
+ try {
+ apiCount++;
+ responderLocation.getLatitude();
+ } catch (IllegalStateException e) {
+ exceptionCount++;
+ }
+ try {
+ apiCount++;
+ responderLocation.getLongitudeUncertainty();
+ } catch (IllegalStateException e) {
+ exceptionCount++;
+ }
+ try {
+ apiCount++;
+ responderLocation.getLongitude();
+ } catch (IllegalStateException e) {
+ exceptionCount++;
+ }
+ try {
+ apiCount++;
+ responderLocation.getAltitudeType();
+ } catch (IllegalStateException e) {
+ exceptionCount++;
+ }
+ try {
+ apiCount++;
+ responderLocation.getAltitudeUncertainty();
+ } catch (IllegalStateException e) {
+ exceptionCount++;
+ }
+ try {
+ apiCount++;
+ responderLocation.getAltitude();
+ } catch (IllegalStateException e) {
+ exceptionCount++;
+ }
+ try {
+ apiCount++;
+ responderLocation.getDatum();
+ } catch (IllegalStateException e) {
+ exceptionCount++;
+ }
+ try {
+ apiCount++;
+ responderLocation.getRegisteredLocationAgreementIndication();
+ } catch (IllegalStateException e) {
+ exceptionCount++;
+ }
+ try {
+ apiCount++;
+ responderLocation.getLciVersion();
+ } catch (IllegalStateException e) {
+ exceptionCount++;
+ }
+ try {
+ apiCount++;
+ assertNotNull(responderLocation.toLocation());
+ } catch (IllegalStateException e) {
+ exceptionCount++;
+ }
+ // If LCI is not valid, all APIs should throw exception, otherwise no exception.
+ assertEquals("Exception number should equal to API number",
+ responderLocation.isLciSubelementValid()? 0 : apiCount, exceptionCount);
+
+ // Verify ZaxisSubelement APIs
+ apiCount = 0;
+ exceptionCount = 0;
+
+ try {
+ apiCount++;
+ responderLocation.getExpectedToMove();
+ } catch (IllegalStateException e) {
+ exceptionCount++;
+ }
+
+ try {
+ apiCount++;
+ responderLocation.getFloorNumber();
+ } catch (IllegalStateException e) {
+ exceptionCount++;
+ }
+
+ try {
+ apiCount++;
+ responderLocation.getHeightAboveFloorMeters();
+ } catch (IllegalStateException e) {
+ exceptionCount++;
+ }
+
+ try {
+ apiCount++;
+ responderLocation.getHeightAboveFloorUncertaintyMeters();
+ } catch (IllegalStateException e) {
+ exceptionCount++;
+ }
+ // If Zaxis is not valid, all APIs should throw exception, otherwise no exception.
+ assertEquals("Exception number should equal to API number",
+ responderLocation.isZaxisSubelementValid() ? 0 : apiCount, exceptionCount);
+ // Verify civic location
+ if (responderLocation.toCivicLocationAddress() == null) {
+ assertNull(responderLocation.toCivicLocationSparseArray());
+ } else {
+ assertNotNull(responderLocation.toCivicLocationSparseArray());
+ }
+ // Verify map image
+ if (responderLocation.getMapImageUri() == null) {
+ assertNull(responderLocation.getMapImageMimeType());
+ } else {
+ assertNotNull(responderLocation.getMapImageMimeType());
+ }
+ boolean extraInfoOnAssociationIndication =
+ responderLocation.getExtraInfoOnAssociationIndication();
+ assertNotNull("ColocatedBSSID list should be nonNull",
+ responderLocation.getColocatedBssids());
+ }
+
+ /**
+ * Verify ranging request with aware peer Mac address and peer handle.
+ */
+ public void testAwareRttWithMacAddress() throws InterruptedException {
+ RangingRequest request = new RangingRequest.Builder()
+ .addWifiAwarePeer(MAC).build();
+ ResultCallback callback = new ResultCallback();
+ mWifiRttManager.startRanging(request, mExecutor, callback);
+ assertTrue("Wi-Fi RTT results: no callback",
+ callback.waitForCallback());
+ List<RangingResult> rangingResults = callback.getResults();
+ assertNotNull("Wi-Fi RTT results: null results", rangingResults);
+ assertEquals(1, rangingResults.size());
+ assertEquals(RangingResult.STATUS_FAIL, rangingResults.get(0).getStatus());
+ }
+
+ /**
+ * Verify ranging request with aware peer handle.
+ */
+ public void testAwareRttWithPeerHandle() throws InterruptedException {
+ PeerHandle peerHandle = mock(PeerHandle.class);
+ RangingRequest request = new RangingRequest.Builder()
+ .addWifiAwarePeer(peerHandle).build();
+ ResultCallback callback = new ResultCallback();
+ mWifiRttManager.startRanging(request, mExecutor, callback);
+ assertTrue("Wi-Fi RTT results: no callback",
+ callback.waitForCallback());
+ List<RangingResult> rangingResults = callback.getResults();
+ assertNotNull("Wi-Fi RTT results: null results", rangingResults);
+ assertEquals("Invalid peerHandle should return 0 result", 0, rangingResults.size());
+ }
}
diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
index 98dbe52..4d72eae 100644
--- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
+++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
@@ -180,15 +180,15 @@
}
}
- private class StartTetheringCallback extends TetheringManager.StartTetheringCallback {
+ private class StartTetheringCallback implements TetheringManager.StartTetheringCallback {
@Override
public void onTetheringStarted() {
// Do nothing, TetherChangeReceiver will wait until it receives the broadcast.
}
@Override
- public void onTetheringFailed(final int resultCode) {
- fail("startTethering fail: " + resultCode);
+ public void onTetheringFailed(final int error) {
+ fail("startTethering fail: " + error);
}
}