summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRebecca Silberstein <silberst@google.com>2016-04-14 15:25:13 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2016-04-14 15:25:14 +0000
commitc38419bd95b0934cb1dfc6f1e1f29eca9929da8c (patch)
tree32aff69b2e1ac1a6037000eeb00b6f039229b1ee
parentdeaf58e6f2c5fb93543f3ead79c1f160cc2248a8 (diff)
parent93332917bf29ddbe853a495816e486150f49da40 (diff)
Merge "Update hasEverConnected for wifi networks" into nyc-dev
-rw-r--r--service/java/com/android/server/wifi/WifiConfigManager.java130
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachine.java5
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java504
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java63
4 files changed, 691 insertions, 11 deletions
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index 2a8c78f0f..408269e6e 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -83,8 +83,10 @@ import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
+import java.security.cert.X509Certificate;
import java.text.DateFormat;
import java.util.ArrayList;
+import java.util.BitSet;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
@@ -1971,6 +1973,11 @@ public class WifiConfigManager {
// Fetch the existing config using networkID
currentConfig = mConfiguredNetworks.getForCurrentUser(config.networkId);
}
+
+ // originalConfig is used to check for credential and config changes that would cause
+ // HasEverConnected to be set to false.
+ WifiConfiguration originalConfig = new WifiConfiguration(currentConfig);
+
if (!mWifiConfigStore.addOrUpdateNetwork(config, currentConfig)) {
return new NetworkUpdateResult(INVALID_NETWORK_ID);
}
@@ -2097,6 +2104,16 @@ public class WifiConfigManager {
}
}
+ boolean passwordChanged = false;
+ // check passed in config to see if it has more than a password set.
+ if (!newNetwork && config.preSharedKey != null && !config.preSharedKey.equals("*")) {
+ passwordChanged = true;
+ }
+
+ if (newNetwork || passwordChanged || wasCredentialChange(originalConfig, currentConfig)) {
+ currentConfig.getNetworkSelectionStatus().setHasEverConnected(false);
+ }
+
// Persist configuration paramaters that are not saved by supplicant.
if (config.lastUpdateName != null) {
currentConfig.lastUpdateName = config.lastUpdateName;
@@ -2122,6 +2139,119 @@ public class WifiConfigManager {
return result;
}
+ private boolean wasBitSetUpdated(BitSet originalBitSet, BitSet currentBitSet) {
+ if (originalBitSet != null && currentBitSet != null) {
+ // both configs have values set, check if they are different
+ if (!originalBitSet.equals(currentBitSet)) {
+ // the BitSets are different
+ return true;
+ }
+ } else if (originalBitSet != null || currentBitSet != null) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean wasCredentialChange(WifiConfiguration originalConfig,
+ WifiConfiguration currentConfig) {
+ // Check if any core WifiConfiguration parameters changed that would impact new connections
+ if (originalConfig == null) {
+ return true;
+ }
+
+ if (wasBitSetUpdated(originalConfig.allowedKeyManagement,
+ currentConfig.allowedKeyManagement)) {
+ return true;
+ }
+
+ if (wasBitSetUpdated(originalConfig.allowedProtocols, currentConfig.allowedProtocols)) {
+ return true;
+ }
+
+ if (wasBitSetUpdated(originalConfig.allowedAuthAlgorithms,
+ currentConfig.allowedAuthAlgorithms)) {
+ return true;
+ }
+
+ if (wasBitSetUpdated(originalConfig.allowedPairwiseCiphers,
+ currentConfig.allowedPairwiseCiphers)) {
+ return true;
+ }
+
+ if (wasBitSetUpdated(originalConfig.allowedGroupCiphers,
+ currentConfig.allowedGroupCiphers)) {
+ return true;
+ }
+
+ if (originalConfig.wepKeys != null && currentConfig.wepKeys != null) {
+ if (originalConfig.wepKeys.length == currentConfig.wepKeys.length) {
+ for (int i = 0; i < originalConfig.wepKeys.length; i++) {
+ if (originalConfig.wepKeys[i] != currentConfig.wepKeys[i]) {
+ return true;
+ }
+ }
+ } else {
+ return true;
+ }
+ }
+
+ if (originalConfig.hiddenSSID != currentConfig.hiddenSSID) {
+ return true;
+ }
+
+ if (originalConfig.requirePMF != currentConfig.requirePMF) {
+ return true;
+ }
+
+ if (wasEnterpriseConfigChange(originalConfig.enterpriseConfig,
+ currentConfig.enterpriseConfig)) {
+ return true;
+ }
+ return false;
+ }
+
+
+ protected boolean wasEnterpriseConfigChange(WifiEnterpriseConfig originalEnterpriseConfig,
+ WifiEnterpriseConfig currentEnterpriseConfig) {
+ if (originalEnterpriseConfig != null && currentEnterpriseConfig != null) {
+ if (originalEnterpriseConfig.getEapMethod() != currentEnterpriseConfig.getEapMethod()) {
+ return true;
+ }
+
+ if (originalEnterpriseConfig.getPhase2Method()
+ != currentEnterpriseConfig.getPhase2Method()) {
+ return true;
+ }
+
+ X509Certificate[] originalCaCerts = originalEnterpriseConfig.getCaCertificates();
+ X509Certificate[] currentCaCerts = currentEnterpriseConfig.getCaCertificates();
+
+ if (originalCaCerts != null && currentCaCerts != null) {
+ if (originalCaCerts.length == currentCaCerts.length) {
+ for (int i = 0; i < originalCaCerts.length; i++) {
+ if (!originalCaCerts[i].equals(currentCaCerts[i])) {
+ return true;
+ }
+ }
+ } else {
+ // number of aliases is different, so the configs are different
+ return true;
+ }
+ } else {
+ // one of the enterprise configs may have aliases
+ if (originalCaCerts != null || currentCaCerts != null) {
+ return true;
+ }
+ }
+ } else {
+ // One of the configs may have an enterpriseConfig
+ if (originalEnterpriseConfig != null || currentEnterpriseConfig != null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public WifiConfiguration getWifiConfigForHomeSP(HomeSP homeSP) {
WifiConfiguration config = mConfiguredNetworks.getByFQDNForCurrentUser(homeSP.getFQDN());
if (config == null) {
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 19489bfe4..529774333 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -5174,8 +5174,11 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
//Here we will clear all disable counters once a network is connected
//records how long this network is connected in future
config.lastConnected = System.currentTimeMillis();
- config.getNetworkSelectionStatus().clearDisableReasonCounter();
config.numAssociation++;
+ WifiConfiguration.NetworkSelectionStatus networkSelectionStatus =
+ config.getNetworkSelectionStatus();
+ networkSelectionStatus.clearDisableReasonCounter();
+ networkSelectionStatus.setHasEverConnected(true);
}
// On connect, reset wifiScoreReport
mWifiScoreReport = null;
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
index 59cbd48b9..53353f997 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -38,7 +38,11 @@ import android.content.Context;
import android.content.pm.UserInfo;
import android.net.wifi.FakeKeys;
import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.AuthAlgorithm;
+import android.net.wifi.WifiConfiguration.GroupCipher;
import android.net.wifi.WifiConfiguration.KeyMgmt;
+import android.net.wifi.WifiConfiguration.PairwiseCipher;
+import android.net.wifi.WifiConfiguration.Protocol;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiEnterpriseConfig.Eap;
import android.net.wifi.WifiEnterpriseConfig.Phase2;
@@ -130,6 +134,14 @@ public class WifiConfigManagerTest {
}
}
+ /**
+ * Set of WifiConfigs for HasEverConnected tests.
+ */
+ private static final int HAS_EVER_CONNECTED_USER = 20;
+ private static final WifiConfiguration BASE_HAS_EVER_CONNECTED_CONFIG =
+ WifiConfigurationTestUtil.generateWifiConfig(
+ 0, HAS_EVER_CONNECTED_USER, "testHasEverConnected", false, true, null, null, 0);
+
public static final String TAG = "WifiConfigManagerTest";
@Mock private Context mContext;
@Mock private WifiNative mWifiNative;
@@ -216,21 +228,27 @@ public class WifiConfigManagerTest {
}
private void addNetworks() throws Exception {
+ for (int i = 0; i < CONFIGS.size(); ++i) {
+ assertEquals(i, CONFIGS.get(i).networkId);
+ addNetwork(CONFIGS.get(i));
+ }
+ }
+
+ private void addNetwork(WifiConfiguration config) throws Exception {
final int originalUserId = mWifiConfigManager.getCurrentUserId();
when(mWifiNative.setNetworkVariable(anyInt(), anyString(), anyString())).thenReturn(true);
when(mWifiNative.setNetworkExtra(anyInt(), anyString(), (Map<String, String>) anyObject()))
.thenReturn(true);
- for (int i = 0; i < CONFIGS.size(); ++i) {
- assertEquals(i, CONFIGS.get(i).networkId);
- switchUserToCreatorOrParentOf(CONFIGS.get(i));
- final WifiConfiguration config = new WifiConfiguration(CONFIGS.get(i));
- config.networkId = -1;
- when(mWifiNative.addNetwork()).thenReturn(i);
- when(mWifiNative.getNetworkVariable(i, WifiConfiguration.ssidVarName))
- .thenReturn(encodeConfigSSID(CONFIGS.get(i)));
- mWifiConfigManager.saveNetwork(config, config.creatorUid);
- }
+
+ switchUserToCreatorOrParentOf(config);
+ final WifiConfiguration configCopy = new WifiConfiguration(config);
+ int networkId = config.networkId;
+ config.networkId = -1;
+ when(mWifiNative.addNetwork()).thenReturn(networkId);
+ when(mWifiNative.getNetworkVariable(networkId, WifiConfiguration.ssidVarName))
+ .thenReturn(encodeConfigSSID(config));
+ mWifiConfigManager.saveNetwork(config, configCopy.creatorUid);
switchUser(originalUserId);
}
@@ -1156,4 +1174,470 @@ public class WifiConfigManagerTest {
new ArrayList(networkSelectionStatusToNetworkIdMap.values()));
}
}
+
+ /**
+ * Verifies that hasEverConnected is false for a newly added network
+ */
+ @Test
+ public void testAddNetworkHasEverConnectedFalse() throws Exception {
+ addNetwork(BASE_HAS_EVER_CONNECTED_CONFIG);
+ WifiConfiguration checkConfig = mWifiConfigManager.getWifiConfiguration(
+ BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+ assertFalse("Adding a new network should not have hasEverConnected set to true.",
+ checkConfig.getNetworkSelectionStatus().getHasEverConnected());
+ }
+
+
+ /**
+ * Verifies that hasEverConnected is false for a newly added network even when new config has
+ * mistakenly set HasEverConnected to true.
+ */
+ @Test
+ public void testAddNetworkOverridesHasEverConnectedWhenTrueInNewConfig() throws Exception {
+ WifiConfiguration newNetworkWithHasEverConnectedTrue =
+ new WifiConfiguration(BASE_HAS_EVER_CONNECTED_CONFIG);
+ newNetworkWithHasEverConnectedTrue.getNetworkSelectionStatus().setHasEverConnected(true);
+ addNetwork(newNetworkWithHasEverConnectedTrue);
+ // check if addNetwork clears the bit.
+ WifiConfiguration checkConfig = mWifiConfigManager.getWifiConfiguration(
+ newNetworkWithHasEverConnectedTrue.networkId);
+ assertFalse("Adding a new network should not have hasEverConnected set to true.",
+ checkConfig.getNetworkSelectionStatus().getHasEverConnected());
+ }
+
+
+ /**
+ * Verify that setting HasEverConnected with a config update can be read back.
+ */
+ @Test
+ public void testUpdateConfigToHasEverConnectedTrue() throws Exception {
+ addNetwork(BASE_HAS_EVER_CONNECTED_CONFIG);
+
+ // Get the newly saved config and update HasEverConnected
+ WifiConfiguration checkConfig = mWifiConfigManager.getWifiConfiguration(
+ BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+ assertFalse("Adding a new network should not have hasEverConnected set to true.",
+ checkConfig.getNetworkSelectionStatus().getHasEverConnected());
+ checkConfig.getNetworkSelectionStatus().setHasEverConnected(true);
+ mWifiConfigManager.addOrUpdateNetwork(checkConfig, HAS_EVER_CONNECTED_USER);
+
+ // verify that HasEverConnected was properly written and read back
+ checkHasEverConnectedTrue(BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+ }
+
+
+ /**
+ * Verifies that hasEverConnected is cleared when a network config preSharedKey is updated.
+ */
+ @Test
+ public void testUpdatePreSharedKeyClearsHasEverConnected() throws Exception {
+ final int originalUserId = mWifiConfigManager.getCurrentUserId();
+
+ testUpdateConfigToHasEverConnectedTrue();
+
+ WifiConfiguration original = mWifiConfigManager.getWifiConfiguration(
+ BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+
+ WifiConfiguration updatePreSharedKeyConfig = new WifiConfiguration();
+ updatePreSharedKeyConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId;
+ updatePreSharedKeyConfig.SSID = original.SSID;
+ updatePreSharedKeyConfig.preSharedKey = "newpassword";
+ switchUserToCreatorOrParentOf(original);
+ mWifiConfigManager.addOrUpdateNetwork(updatePreSharedKeyConfig,
+ BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+
+ checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+ switchUser(originalUserId);
+ }
+
+ /**
+ * Verifies that hasEverConnected is cleared when a network config allowedKeyManagement is
+ * updated.
+ */
+ @Test
+ public void testUpdateAllowedKeyManagementChanged() throws Exception {
+ final int originalUserId = mWifiConfigManager.getCurrentUserId();
+
+ testUpdateConfigToHasEverConnectedTrue();
+
+ WifiConfiguration updateAllowedKeyManagementConfig = new WifiConfiguration();
+ updateAllowedKeyManagementConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId;
+ updateAllowedKeyManagementConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID;
+ updateAllowedKeyManagementConfig.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
+
+ // Set up mock to allow the new value to be read back into the config
+ String allowedKeyManagementString = makeString(
+ updateAllowedKeyManagementConfig.allowedKeyManagement,
+ WifiConfiguration.KeyMgmt.strings);
+ when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId,
+ KeyMgmt.varName)).thenReturn(allowedKeyManagementString);
+
+ switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG);
+ mWifiConfigManager.addOrUpdateNetwork(updateAllowedKeyManagementConfig,
+ BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+
+ checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+ switchUser(originalUserId);
+ }
+
+ /**
+ * Verifies that hasEverConnected is cleared when a network config allowedProtocols is
+ * updated.
+ */
+ @Test
+ public void testUpdateAllowedProtocolsChanged() throws Exception {
+ final int originalUserId = mWifiConfigManager.getCurrentUserId();
+
+ testUpdateConfigToHasEverConnectedTrue();
+
+ WifiConfiguration updateAllowedProtocolsConfig = new WifiConfiguration();
+ updateAllowedProtocolsConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId;
+ updateAllowedProtocolsConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID;
+ updateAllowedProtocolsConfig.allowedProtocols.set(
+ WifiConfiguration.Protocol.RSN);
+
+ // Set up mock to allow the new value to be read back into the config
+ String allowedProtocolsString = makeString(
+ updateAllowedProtocolsConfig.allowedProtocols,
+ WifiConfiguration.Protocol.strings);
+ when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId,
+ Protocol.varName)).thenReturn(allowedProtocolsString);
+
+ switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG);
+ mWifiConfigManager.addOrUpdateNetwork(updateAllowedProtocolsConfig,
+ BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+
+ checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+ switchUser(originalUserId);
+ }
+
+ /**
+ * Verifies that hasEverConnected is cleared when a network config allowedAuthAlgorithms is
+ * updated.
+ */
+ @Test
+ public void testUpdateAllowedAuthAlgorithmsChanged() throws Exception {
+ final int originalUserId = mWifiConfigManager.getCurrentUserId();
+
+ testUpdateConfigToHasEverConnectedTrue();
+
+ WifiConfiguration updateAllowedAuthAlgorithmsConfig = new WifiConfiguration();
+ updateAllowedAuthAlgorithmsConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId;
+ updateAllowedAuthAlgorithmsConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID;
+ updateAllowedAuthAlgorithmsConfig.allowedAuthAlgorithms.set(
+ WifiConfiguration.AuthAlgorithm.SHARED);
+
+ // Set up mock to allow the new value to be read back into the config
+ String allowedAuthAlgorithmsString = makeString(
+ updateAllowedAuthAlgorithmsConfig.allowedAuthAlgorithms,
+ WifiConfiguration.AuthAlgorithm.strings);
+ when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId,
+ AuthAlgorithm.varName)).thenReturn(allowedAuthAlgorithmsString);
+
+ switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG);
+ mWifiConfigManager.addOrUpdateNetwork(updateAllowedAuthAlgorithmsConfig,
+ BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+
+ checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+ switchUser(originalUserId);
+ }
+
+ /**
+ * Verifies that hasEverConnected is cleared when a network config allowedPairwiseCiphers is
+ * updated.
+ */
+ @Test
+ public void testUpdateAllowedPairwiseCiphersChanged() throws Exception {
+ final int originalUserId = mWifiConfigManager.getCurrentUserId();
+
+ testUpdateConfigToHasEverConnectedTrue();
+
+ WifiConfiguration updateAllowedPairwiseCiphersConfig = new WifiConfiguration();
+ updateAllowedPairwiseCiphersConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId;
+ updateAllowedPairwiseCiphersConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID;
+ updateAllowedPairwiseCiphersConfig.allowedPairwiseCiphers.set(
+ WifiConfiguration.PairwiseCipher.CCMP);
+
+ // Set up mock to allow the new value to be read back into the config
+ String allowedPairwiseCiphersString = makeString(
+ updateAllowedPairwiseCiphersConfig.allowedPairwiseCiphers,
+ WifiConfiguration.PairwiseCipher.strings);
+ when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId,
+ PairwiseCipher.varName)).thenReturn(allowedPairwiseCiphersString);
+
+ switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG);
+ mWifiConfigManager.addOrUpdateNetwork(updateAllowedPairwiseCiphersConfig,
+ BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+
+ checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+ switchUser(originalUserId);
+ }
+
+ /**
+ * Verifies that hasEverConnected is cleared when a network config allowedGroupCiphers is
+ * updated.
+ */
+ @Test
+ public void testUpdateAllowedGroupCiphersChanged() throws Exception {
+ final int originalUserId = mWifiConfigManager.getCurrentUserId();
+
+ testUpdateConfigToHasEverConnectedTrue();
+
+ WifiConfiguration updateAllowedGroupCiphersConfig = new WifiConfiguration();
+ updateAllowedGroupCiphersConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId;
+ updateAllowedGroupCiphersConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID;
+ updateAllowedGroupCiphersConfig.allowedGroupCiphers.set(
+ WifiConfiguration.GroupCipher.CCMP);
+
+ // Set up mock to allow the new value to be read back into the config
+ String allowedGroupCiphersString = makeString(
+ updateAllowedGroupCiphersConfig.allowedGroupCiphers,
+ WifiConfiguration.GroupCipher.strings);
+ when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId,
+ GroupCipher.varName)).thenReturn(allowedGroupCiphersString);
+
+ switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG);
+ mWifiConfigManager.addOrUpdateNetwork(updateAllowedGroupCiphersConfig,
+ BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+
+ checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+ switchUser(originalUserId);
+ }
+
+ /**
+ * Verifies that hasEverConnected is cleared when a network config wepKeys is
+ * updated.
+ */
+ @Test
+ public void testUpdateWepKeysChanged() throws Exception {
+ final int originalUserId = mWifiConfigManager.getCurrentUserId();
+
+ testUpdateConfigToHasEverConnectedTrue();
+
+ String tempKey = "hereisakey";
+ WifiConfiguration updateWepKeysConfig = new WifiConfiguration();
+ updateWepKeysConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId;
+ updateWepKeysConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID;
+ updateWepKeysConfig.wepKeys = new String[] {tempKey};
+
+ // Set up mock to allow the new value to be read back into the config
+ when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId,
+ WifiConfiguration.wepKeyVarNames[0])).thenReturn(tempKey);
+
+ switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG);
+ mWifiConfigManager.addOrUpdateNetwork(updateWepKeysConfig,
+ BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+
+ checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+ switchUser(originalUserId);
+ }
+
+ /**
+ * Verifies that hasEverConnected is cleared when a network config hiddenSSID is
+ * updated.
+ */
+ @Test
+ public void testUpdateHiddenSSIDChanged() throws Exception {
+ final int originalUserId = mWifiConfigManager.getCurrentUserId();
+
+ testUpdateConfigToHasEverConnectedTrue();
+
+ WifiConfiguration updateHiddenSSIDConfig = new WifiConfiguration();
+ updateHiddenSSIDConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId;
+ updateHiddenSSIDConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID;
+ updateHiddenSSIDConfig.hiddenSSID = true;
+
+ // Set up mock to allow the new value to be read back into the config
+ when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId,
+ WifiConfiguration.hiddenSSIDVarName)).thenReturn("1");
+
+ switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG);
+ mWifiConfigManager.addOrUpdateNetwork(updateHiddenSSIDConfig,
+ BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+
+ checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+ switchUser(originalUserId);
+ }
+
+ /**
+ * Verifies that hasEverConnected is cleared when a network config pmfVarName is
+ * updated.
+ */
+ @Test
+ public void testUpdateRequirePMFChanged() throws Exception {
+ final int originalUserId = mWifiConfigManager.getCurrentUserId();
+
+ testUpdateConfigToHasEverConnectedTrue();
+
+ WifiConfiguration updateRequirePMFConfig = new WifiConfiguration();
+ updateRequirePMFConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId;
+ updateRequirePMFConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID;
+ updateRequirePMFConfig.requirePMF = true;
+
+ // Set up mock to allow the new value to be read back into the config
+ // TODO: please see b/28088226 - this test is implemented as if WifiConfigStore correctly
+ // read back the boolean value. When fixed, uncomment the following line and the
+ // checkHasEverConnectedFalse below.
+ //when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId,
+ // WifiConfiguration.pmfVarName)).thenReturn("2");
+
+ switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG);
+ mWifiConfigManager.addOrUpdateNetwork(updateRequirePMFConfig,
+ BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+
+ //checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+ checkHasEverConnectedTrue(BASE_HAS_EVER_CONNECTED_CONFIG.networkId);
+ switchUser(originalUserId);
+ }
+
+ /**
+ * Verify WifiEnterpriseConfig changes are detected in WifiConfigManager.
+ */
+ @Test
+ public void testEnterpriseConfigAdded() {
+ EnterpriseConfig eapConfig = new EnterpriseConfig(Eap.TTLS)
+ .setPhase2(Phase2.MSCHAPV2)
+ .setIdentity("username", "password")
+ .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0});
+
+ assertTrue(mWifiConfigManager.wasEnterpriseConfigChange(null, eapConfig.enterpriseConfig));
+ }
+
+ /**
+ * Verify WifiEnterpriseConfig eap change is detected.
+ */
+ @Test
+ public void testEnterpriseConfigEapChangeDetected() {
+ EnterpriseConfig eapConfig = new EnterpriseConfig(Eap.TTLS);
+ EnterpriseConfig peapConfig = new EnterpriseConfig(Eap.PEAP);
+
+ assertTrue(mWifiConfigManager.wasEnterpriseConfigChange(eapConfig.enterpriseConfig,
+ peapConfig.enterpriseConfig));
+ }
+
+ /**
+ * Verify WifiEnterpriseConfig phase2 method change is detected.
+ */
+ @Test
+ public void testEnterpriseConfigPhase2ChangeDetected() {
+ EnterpriseConfig eapConfig = new EnterpriseConfig(Eap.TTLS).setPhase2(Phase2.MSCHAPV2);
+ EnterpriseConfig papConfig = new EnterpriseConfig(Eap.TTLS).setPhase2(Phase2.PAP);
+
+ assertTrue(mWifiConfigManager.wasEnterpriseConfigChange(eapConfig.enterpriseConfig,
+ papConfig.enterpriseConfig));
+ }
+
+ /**
+ * Verify WifiEnterpriseConfig added Certificate is detected.
+ */
+ @Test
+ public void testCaCertificateAddedDetected() {
+ EnterpriseConfig eapConfigNoCerts = new EnterpriseConfig(Eap.TTLS)
+ .setPhase2(Phase2.MSCHAPV2)
+ .setIdentity("username", "password");
+
+ EnterpriseConfig eapConfig1Cert = new EnterpriseConfig(Eap.TTLS)
+ .setPhase2(Phase2.MSCHAPV2)
+ .setIdentity("username", "password")
+ .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0});
+
+ assertTrue(mWifiConfigManager.wasEnterpriseConfigChange(eapConfigNoCerts.enterpriseConfig,
+ eapConfig1Cert.enterpriseConfig));
+ }
+
+ /**
+ * Verify WifiEnterpriseConfig Certificate change is detected.
+ */
+ @Test
+ public void testDifferentCaCertificateDetected() {
+ EnterpriseConfig eapConfig = new EnterpriseConfig(Eap.TTLS)
+ .setPhase2(Phase2.MSCHAPV2)
+ .setIdentity("username", "password")
+ .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0});
+
+ EnterpriseConfig eapConfigNewCert = new EnterpriseConfig(Eap.TTLS)
+ .setPhase2(Phase2.MSCHAPV2)
+ .setIdentity("username", "password")
+ .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT1});
+
+ assertTrue(mWifiConfigManager.wasEnterpriseConfigChange(eapConfig.enterpriseConfig,
+ eapConfigNewCert.enterpriseConfig));
+ }
+
+ /**
+ * Verify WifiEnterpriseConfig added Certificate changes are detected.
+ */
+ @Test
+ public void testCaCertificateChangesDetected() {
+ EnterpriseConfig eapConfig = new EnterpriseConfig(Eap.TTLS)
+ .setPhase2(Phase2.MSCHAPV2)
+ .setIdentity("username", "password")
+ .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0});
+
+ EnterpriseConfig eapConfigAddedCert = new EnterpriseConfig(Eap.TTLS)
+ .setPhase2(Phase2.MSCHAPV2)
+ .setIdentity("username", "password")
+ .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0, FakeKeys.CA_CERT1});
+
+ assertTrue(mWifiConfigManager.wasEnterpriseConfigChange(eapConfig.enterpriseConfig,
+ eapConfigAddedCert.enterpriseConfig));
+ }
+
+ /**
+ * Verify that WifiEnterpriseConfig does not detect changes for identical configs.
+ */
+ @Test
+ public void testWifiEnterpriseConfigNoChanges() {
+ EnterpriseConfig eapConfig = new EnterpriseConfig(Eap.TTLS)
+ .setPhase2(Phase2.MSCHAPV2)
+ .setIdentity("username", "password")
+ .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0, FakeKeys.CA_CERT1});
+
+ // Just to be clear that check is not against the same object
+ EnterpriseConfig eapConfigSame = new EnterpriseConfig(Eap.TTLS)
+ .setPhase2(Phase2.MSCHAPV2)
+ .setIdentity("username", "password")
+ .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0, FakeKeys.CA_CERT1});
+
+ assertFalse(mWifiConfigManager.wasEnterpriseConfigChange(eapConfig.enterpriseConfig,
+ eapConfigSame.enterpriseConfig));
+ }
+
+
+ private void checkHasEverConnectedTrue(int networkId) {
+ WifiConfiguration checkConfig = mWifiConfigManager.getWifiConfiguration(networkId);
+ assertTrue("hasEverConnected expected to be true.",
+ checkConfig.getNetworkSelectionStatus().getHasEverConnected());
+ }
+
+ private void checkHasEverConnectedFalse(int networkId) {
+ WifiConfiguration checkConfig = mWifiConfigManager.getWifiConfiguration(networkId);
+ assertFalse("Updating credentials network config should clear hasEverConnected.",
+ checkConfig.getNetworkSelectionStatus().getHasEverConnected());
+ }
+
+ /**
+ * Helper function to translate from WifiConfiguration BitSet to String.
+ */
+ private static String makeString(BitSet set, String[] strings) {
+ StringBuffer buf = new StringBuffer();
+ int nextSetBit = -1;
+
+ /* Make sure all set bits are in [0, strings.length) to avoid
+ * going out of bounds on strings. (Shouldn't happen, but...) */
+ set = set.get(0, strings.length);
+
+ while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1) {
+ buf.append(strings[nextSetBit].replace('_', '-')).append(' ');
+ }
+
+ // remove trailing space
+ if (set.cardinality() > 0) {
+ buf.setLength(buf.length() - 1);
+ }
+
+ return buf.toString();
+ }
+
+
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
index c16a416cc..24d6a81cc 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
@@ -113,6 +113,7 @@ public class WifiStateMachineTest {
(ActivityManager.isLowRamDeviceStatic()
? WifiStateMachine.NUM_LOG_RECS_VERBOSE_LOW_MEMORY
: WifiStateMachine.NUM_LOG_RECS_VERBOSE);
+ private static final String DEFAULT_TEST_SSID = "\"GoogleGuest\"";
private long mBinderToken;
@@ -727,6 +728,24 @@ public class WifiStateMachineTest {
}
/**
+ * Helper method to retrieve WifiConfiguration by SSID.
+ *
+ * Returns the associated WifiConfiguration if it is found, null otherwise.
+ */
+ private WifiConfiguration getWifiConfigurationForNetwork(String ssid) {
+ mLooper.startAutoDispatch();
+ List<WifiConfiguration> configs = mWsm.syncGetConfiguredNetworks(-1, mWsmAsyncChannel);
+ mLooper.stopAutoDispatch();
+
+ for (WifiConfiguration checkConfig : configs) {
+ if (checkConfig.SSID.equals(ssid)) {
+ return checkConfig;
+ }
+ }
+ return null;
+ }
+
+ /**
* Verifies that the current foreground user is allowed to forget a network.
*/
@Test
@@ -923,6 +942,50 @@ public class WifiStateMachineTest {
assertEquals("DisconnectedState", getCurrentState().getName());
}
+ /**
+ * WifiConfigurations default to HasEverConnected to false, creating and adding a config should
+ * not update this value to true.
+ *
+ * Test: Successfully add a network. Check the config and verify
+ * WifiConfiguration.getHasEverConnected() is false.
+ */
+ @Test
+ public void addNetworkDoesNotSetHasEverConnectedTrue() throws Exception {
+ addNetworkAndVerifySuccess();
+
+ WifiConfiguration checkConfig = getWifiConfigurationForNetwork(DEFAULT_TEST_SSID);
+ assertFalse(checkConfig.getNetworkSelectionStatus().getHasEverConnected());
+ }
+
+ /**
+ * Successfully connecting to a network will set WifiConfiguration's value of HasEverConnected
+ * to true.
+ *
+ * Test: Successfully create and connect to a network. Check the config and verify
+ * WifiConfiguration.getHasEverConnected() is true.
+ */
+ @Test
+ public void setHasEverConnectedTrueOnConnect() throws Exception {
+ connect();
+
+ WifiConfiguration checkConfig = getWifiConfigurationForNetwork(DEFAULT_TEST_SSID);
+ assertTrue(checkConfig.getNetworkSelectionStatus().getHasEverConnected());
+ }
+
+ /**
+ * Fail network connection attempt and verify HasEverConnected remains false.
+ *
+ * Test: Successfully create a network but fail when connecting. Check the config and verify
+ * WifiConfiguration.getHasEverConnected() is false.
+ */
+ @Test
+ public void connectionFailureDoesNotSetHasEverConnectedTrue() throws Exception {
+ testDhcpFailure();
+
+ WifiConfiguration checkConfig = getWifiConfigurationForNetwork(DEFAULT_TEST_SSID);
+ assertFalse(checkConfig.getNetworkSelectionStatus().getHasEverConnected());
+ }
+
@Test
public void handleUserSwitch() throws Exception {
assertEquals(UserHandle.USER_SYSTEM, mWifiConfigManager.getCurrentUserId());