summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Qiu <zqiu@google.com>2017-06-22 15:48:19 -0700
committerPeter Qiu <zqiu@google.com>2017-07-11 13:57:53 -0700
commit49357a30edf5786c8db4bad6f5dbe62545751cc6 (patch)
tree201d9fef949592bac0af6bdaa47c6b509daabc5b
parent26b97ef6a6d8e755e7db541afa84aacd807599d7 (diff)
hotspot2: track number of providers that connected successfully
Add boolean field "hasEverConnected" to PasspointProvider to indicate if the given provider had ever provided a successful network connection. The added field is persisted to the config file. Update the associated metric for the given provider after it was used to successfully connect for the first time. Note that PasspointManager#onPasspointNetworkConnected can be expanded in the future to keep track of connected SSIDs for a given Passpoint provider, as an additional input to the network selection algorithm. Bug: 36358031 Test: frameworks/opt/net/wifi/tests/wifitests/runtests.sh Test: manually verify the provider's "hasEverConnected" is set to true in the config file after a success connection Change-Id: I6ef4ec801f78f34ff2ca9df97ab06188e1cc0324
-rw-r--r--service/java/com/android/server/wifi/WifiMetrics.java7
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachine.java8
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointConfigStoreData.java9
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointManager.java37
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointProvider.java16
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java5
-rw-r--r--tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigStoreDataTest.java3
-rw-r--r--tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java58
-rw-r--r--tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java23
9 files changed, 157 insertions, 9 deletions
diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java
index 1128d3c77..d317f8386 100644
--- a/service/java/com/android/server/wifi/WifiMetrics.java
+++ b/service/java/com/android/server/wifi/WifiMetrics.java
@@ -1321,13 +1321,16 @@ public class WifiMetrics {
}
/**
- * Update number of saved Passpoint profiles.
+ * Update metrics for saved Passpoint profiles.
*
* @param numSavedProfiles The number of saved Passpoint profiles
+ * @param numConnectedProfiles The number of saved Passpoint profiles that have ever resulted
+ * in a successful network connection
*/
- public void updateSavedPasspointProfiles(int numSavedProfiles) {
+ public void updateSavedPasspointProfiles(int numSavedProfiles, int numConnectedProfiles) {
synchronized (mLock) {
mWifiLogProto.numPasspointProviders = numSavedProfiles;
+ mWifiLogProto.numPasspointProvidersSuccessfullyConnected = numConnectedProfiles;
}
}
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 688a53cb8..6fd16e37b 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -4709,6 +4709,12 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
mWifiConfigManager.updateNetworkAfterConnect(mLastNetworkId);
// On connect, reset wifiScoreReport
mWifiScoreReport.reset();
+
+ // Notify PasspointManager of Passpoint network connected event.
+ WifiConfiguration currentNetwork = getCurrentWifiConfiguration();
+ if (currentNetwork.isPasspoint()) {
+ mPasspointManager.onPasspointNetworkConnected(currentNetwork.FQDN);
+ }
}
}
@@ -6985,7 +6991,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
*/
public void updateWifiMetrics() {
mWifiMetrics.updateSavedNetworks(mWifiConfigManager.getSavedNetworks());
- mWifiMetrics.updateSavedPasspointProfiles(mPasspointManager.getProviderConfigs().size());
+ mPasspointManager.updateMetrics();
}
/**
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointConfigStoreData.java b/service/java/com/android/server/wifi/hotspot2/PasspointConfigStoreData.java
index 74a4760b4..38401d2ca 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointConfigStoreData.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointConfigStoreData.java
@@ -66,6 +66,7 @@ public class PasspointConfigStoreData implements WifiConfigStore.StoreData {
private static final String XML_TAG_CLIENT_PRIVATE_KEY_ALIAS = "ClientPrivateKeyAlias";
private static final String XML_TAG_PROVIDER_INDEX = "ProviderIndex";
+ private static final String XML_TAG_HAS_EVER_CONNECTED = "HasEverConnected";
private final WifiKeyStore mKeyStore;
private final SIMAccessor mSimAccessor;
@@ -211,6 +212,7 @@ public class PasspointConfigStoreData implements WifiConfigStore.StoreData {
provider.getClientCertificateAlias());
XmlUtil.writeNextValue(out, XML_TAG_CLIENT_PRIVATE_KEY_ALIAS,
provider.getClientPrivateKeyAlias());
+ XmlUtil.writeNextValue(out, XML_TAG_HAS_EVER_CONNECTED, provider.getHasEverConnected());
if (provider.getConfig() != null) {
XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_PASSPOINT_CONFIGURATION);
PasspointXmlUtils.serializePasspointConfiguration(out, provider.getConfig());
@@ -304,6 +306,7 @@ public class PasspointConfigStoreData implements WifiConfigStore.StoreData {
String caCertificateAlias = null;
String clientCertificateAlias = null;
String clientPrivateKeyAlias = null;
+ boolean hasEverConnected = false;
PasspointConfiguration config = null;
while (XmlUtils.nextElementWithin(in, outerTagDepth)) {
if (in.getAttributeValue(null, "name") != null) {
@@ -326,6 +329,9 @@ public class PasspointConfigStoreData implements WifiConfigStore.StoreData {
case XML_TAG_CLIENT_PRIVATE_KEY_ALIAS:
clientPrivateKeyAlias = (String) value;
break;
+ case XML_TAG_HAS_EVER_CONNECTED:
+ hasEverConnected = (boolean) value;
+ break;
}
} else {
if (!TextUtils.equals(in.getName(),
@@ -344,7 +350,8 @@ public class PasspointConfigStoreData implements WifiConfigStore.StoreData {
throw new XmlPullParserException("Missing Passpoint configuration");
}
return new PasspointProvider(config, mKeyStore, mSimAccessor, providerId, creatorUid,
- caCertificateAlias, clientCertificateAlias, clientPrivateKeyAlias);
+ caCertificateAlias, clientCertificateAlias, clientPrivateKeyAlias,
+ hasEverConnected);
}
/**
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java
index dad622136..5d79ba40a 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java
@@ -536,6 +536,41 @@ public class PasspointManager {
}
/**
+ * Invoked when a Passpoint network was successfully connected based on the credentials
+ * provided by the given Passpoint provider (specified by its FQDN).
+ *
+ * @param fqdn The FQDN of the Passpoint provider
+ */
+ public void onPasspointNetworkConnected(String fqdn) {
+ PasspointProvider provider = mProviders.get(fqdn);
+ if (provider == null) {
+ Log.e(TAG, "Passpoint network connected without provider: " + fqdn);
+ return;
+ }
+
+ if (!provider.getHasEverConnected()) {
+ // First successful connection using this provider.
+ provider.setHasEverConnected(true);
+ }
+ }
+
+ /**
+ * Update metrics related to installed Passpoint providers, this includes the number of
+ * installed providers and the number of those providers that results in a successful network
+ * connection.
+ */
+ public void updateMetrics() {
+ int numProviders = mProviders.size();
+ int numConnectedProviders = 0;
+ for (Map.Entry<String, PasspointProvider> entry : mProviders.entrySet()) {
+ if (entry.getValue().getHasEverConnected()) {
+ numConnectedProviders++;
+ }
+ }
+ mWifiMetrics.updateSavedPasspointProfiles(numProviders, numConnectedProviders);
+ }
+
+ /**
* Dump the current state of PasspointManager to the provided output stream.
*
* @param pw The output stream to write to
@@ -595,7 +630,7 @@ public class PasspointManager {
mSimAccessor, mProviderIndex++, wifiConfig.creatorUid,
enterpriseConfig.getCaCertificateAlias(),
enterpriseConfig.getClientCertificateAlias(),
- enterpriseConfig.getClientCertificateAlias());
+ enterpriseConfig.getClientCertificateAlias(), false);
mProviders.put(passpointConfig.getHomeSp().getFqdn(), provider);
return true;
}
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java b/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java
index c38098dac..c7943ed81 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java
@@ -87,14 +87,17 @@ public class PasspointProvider {
private final int mEAPMethodID;
private final AuthParam mAuthParam;
+ private boolean mHasEverConnected;
+
public PasspointProvider(PasspointConfiguration config, WifiKeyStore keyStore,
SIMAccessor simAccessor, long providerId, int creatorUid) {
- this(config, keyStore, simAccessor, providerId, creatorUid, null, null, null);
+ this(config, keyStore, simAccessor, providerId, creatorUid, null, null, null, false);
}
public PasspointProvider(PasspointConfiguration config, WifiKeyStore keyStore,
SIMAccessor simAccessor, long providerId, int creatorUid, String caCertificateAlias,
- String clientCertificateAlias, String clientPrivateKeyAlias) {
+ String clientCertificateAlias, String clientPrivateKeyAlias,
+ boolean hasEverConnected) {
// Maintain a copy of the configuration to avoid it being updated by others.
mConfig = new PasspointConfiguration(config);
mKeyStore = keyStore;
@@ -103,6 +106,7 @@ public class PasspointProvider {
mCaCertificateAlias = caCertificateAlias;
mClientCertificateAlias = clientCertificateAlias;
mClientPrivateKeyAlias = clientPrivateKeyAlias;
+ mHasEverConnected = hasEverConnected;
// Setup EAP method and authentication parameter based on the credential.
if (mConfig.getCredential().getUserCredential() != null) {
@@ -150,6 +154,14 @@ public class PasspointProvider {
return mCreatorUid;
}
+ public boolean getHasEverConnected() {
+ return mHasEverConnected;
+ }
+
+ public void setHasEverConnected(boolean hasEverConnected) {
+ mHasEverConnected = hasEverConnected;
+ }
+
/**
* Install certificates and key based on current configuration.
* Note: the certificates and keys in the configuration will get cleared once
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
index e58928bf5..e7216ce4a 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
@@ -295,7 +295,8 @@ public class WifiMetricsTest {
*/
public void setAndIncrementMetrics() throws Exception {
mWifiMetrics.updateSavedNetworks(buildSavedNetworkList());
- mWifiMetrics.updateSavedPasspointProfiles(NUM_PASSPOINT_PROVIDERS);
+ mWifiMetrics.updateSavedPasspointProfiles(NUM_PASSPOINT_PROVIDERS,
+ NUM_PASSPOINT_PROVIDERS_SUCCESSFULLY_CONNECTED);
mWifiMetrics.setIsLocationEnabled(TEST_VAL_IS_LOCATION_ENABLED);
mWifiMetrics.setIsScanningAlwaysEnabled(IS_SCANNING_ALWAYS_ENABLED);
@@ -592,6 +593,8 @@ public class WifiMetricsTest {
mDeserializedWifiMetrics.numPasspointProviderUninstallation);
assertEquals(NUM_PASSPOINT_PROVIDER_UNINSTALL_SUCCESS,
mDeserializedWifiMetrics.numPasspointProviderUninstallSuccess);
+ assertEquals(NUM_PASSPOINT_PROVIDERS_SUCCESSFULLY_CONNECTED,
+ mDeserializedWifiMetrics.numPasspointProvidersSuccessfullyConnected);
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigStoreDataTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigStoreDataTest.java
index 8e808efcf..7e05c3d09 100644
--- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigStoreDataTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigStoreDataTest.java
@@ -60,6 +60,7 @@ public class PasspointConfigStoreDataTest {
private static final String TEST_CLIENT_PRIVATE_KEY_ALIAS = "ClientPrivateKey";
private static final long TEST_PROVIDER_ID = 1;
private static final int TEST_CREATOR_UID = 1234;
+ private static final boolean TEST_HAS_EVER_CONNECTED = true;
@Mock WifiKeyStore mKeyStore;
@Mock SIMAccessor mSimAccessor;
@@ -238,7 +239,7 @@ public class PasspointConfigStoreDataTest {
providerList.add(new PasspointProvider(createFullPasspointConfiguration(),
mKeyStore, mSimAccessor, TEST_PROVIDER_ID, TEST_CREATOR_UID,
TEST_CA_CERTIFICATE_ALIAS, TEST_CLIENT_CERTIFICATE_ALIAS,
- TEST_CLIENT_PRIVATE_KEY_ALIAS));
+ TEST_CLIENT_PRIVATE_KEY_ALIAS, TEST_HAS_EVER_CONNECTED));
// Serialize data for user store.
when(mDataSource.getProviders()).thenReturn(providerList);
diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java
index a8dd831ed..01566c203 100644
--- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java
@@ -1215,4 +1215,62 @@ public class PasspointManagerTest {
assertFalse(PasspointManager.addLegacyPasspointConfig(wifiConfig));
}
+
+ /**
+ * Verify that the provider's "hasEverConnected" flag will be set to true and the associated
+ * metric is updated after the provider was used to successfully connect to a Passpoint
+ * network for the first time.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void providerNetworkConnectedFirstTime() throws Exception {
+ PasspointProvider provider = addTestProvider();
+ when(provider.getHasEverConnected()).thenReturn(false);
+ mManager.onPasspointNetworkConnected(TEST_FQDN);
+ verify(provider).setHasEverConnected(eq(true));
+ }
+
+ /**
+ * Verify that the provider's "hasEverConnected" flag the associated metric is not updated
+ * after the provider was used to successfully connect to a Passpoint network for non-first
+ * time.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void providerNetworkConnectedNotFirstTime() throws Exception {
+ PasspointProvider provider = addTestProvider();
+ when(provider.getHasEverConnected()).thenReturn(true);
+ mManager.onPasspointNetworkConnected(TEST_FQDN);
+ verify(provider, never()).setHasEverConnected(anyBoolean());
+ }
+
+ /**
+ * Verify that the expected Passpoint metrics are updated when
+ * {@link PasspointManager#updateMetrics} is invoked.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void updateMetrics() throws Exception {
+ PasspointProvider provider = addTestProvider();
+
+ // Provider have not provided a successful network connection.
+ int expectedInstalledProviders = 1;
+ int expectedConnectedProviders = 0;
+ when(provider.getHasEverConnected()).thenReturn(false);
+ mManager.updateMetrics();
+ verify(mWifiMetrics).updateSavedPasspointProfiles(
+ eq(expectedInstalledProviders), eq(expectedConnectedProviders));
+ reset(provider);
+ reset(mWifiMetrics);
+
+ // Provider have provided a successful network connection.
+ expectedConnectedProviders = 1;
+ when(provider.getHasEverConnected()).thenReturn(true);
+ mManager.updateMetrics();
+ verify(mWifiMetrics).updateSavedPasspointProfiles(
+ eq(expectedInstalledProviders), eq(expectedConnectedProviders));
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java
index 15f8471e0..9ee9fc6d5 100644
--- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java
@@ -963,4 +963,27 @@ public class PasspointProviderTest {
assertFalse(mProvider.isSimCredential());
}
+
+ /**
+ * Verify that hasEverConnected flag is set correctly using
+ * {@link PasspointProvider#setHasEverConnected}.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void setHasEverConnected() throws Exception {
+ PasspointConfiguration config = new PasspointConfiguration();
+ HomeSp homeSp = new HomeSp();
+ homeSp.setFqdn("test1");
+ config.setHomeSp(homeSp);
+ Credential credential = new Credential();
+ credential.setUserCredential(new Credential.UserCredential());
+ config.setCredential(credential);
+ mProvider = createProvider(config);
+ verifyInstalledConfig(config, true);
+
+ assertFalse(mProvider.getHasEverConnected());
+ mProvider.setHasEverConnected(true);
+ assertTrue(mProvider.getHasEverConnected());
+ }
}