From 26b97ef6a6d8e755e7db541afa84aacd807599d7 Mon Sep 17 00:00:00 2001 From: Peter Qiu Date: Thu, 22 Jun 2017 14:49:02 -0700 Subject: WifiMetrics: add support for Passpoint related metrics The support for tracking number of Passpoint providers that provided successful network connection will be added in the upcoming CL. Bug: 36358031 Test: frameworks/wifi/tests/wifitests/runtests.sh Change-Id: Id0dc3bc6a3d30785c883b8a478be9b23911d3747 --- .../java/com/android/server/wifi/WifiInjector.java | 3 +- .../java/com/android/server/wifi/WifiMetrics.java | 59 ++++++++++++++++++++++ .../com/android/server/wifi/WifiStateMachine.java | 1 + .../server/wifi/hotspot2/PasspointManager.java | 10 +++- 4 files changed, 71 insertions(+), 2 deletions(-) (limited to 'service') diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java index c4be62570..0b0c38002 100644 --- a/service/java/com/android/server/wifi/WifiInjector.java +++ b/service/java/com/android/server/wifi/WifiInjector.java @@ -216,7 +216,8 @@ public class WifiInjector { mWifiNetworkScoreCache); mSimAccessor = new SIMAccessor(mContext); mPasspointManager = new PasspointManager(mContext, mWifiNative, mWifiKeyStore, mClock, - mSimAccessor, new PasspointObjectFactory(), mWifiConfigManager, mWifiConfigStore); + mSimAccessor, new PasspointObjectFactory(), mWifiConfigManager, mWifiConfigStore, + mWifiMetrics); mPasspointNetworkEvaluator = new PasspointNetworkEvaluator( mPasspointManager, mWifiConfigManager, mConnectivityLocalLog); // mWifiStateMachine has an implicit dependency on mJavaRuntime due to WifiDiagnostics. diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java index 0caf79e79..1128d3c77 100644 --- a/service/java/com/android/server/wifi/WifiMetrics.java +++ b/service/java/com/android/server/wifi/WifiMetrics.java @@ -1025,6 +1025,41 @@ public class WifiMetrics { } } + /** + * Increment number of times Passpoint provider being installed. + */ + public void incrementNumPasspointProviderInstallation() { + synchronized (mLock) { + mWifiLogProto.numPasspointProviderInstallation++; + } + } + + /** + * Increment number of times Passpoint provider is installed successfully. + */ + public void incrementNumPasspointProviderInstallSuccess() { + synchronized (mLock) { + mWifiLogProto.numPasspointProviderInstallSuccess++; + } + } + + /** + * Increment number of times Passpoint provider being uninstalled. + */ + public void incrementNumPasspointProviderUninstallation() { + synchronized (mLock) { + mWifiLogProto.numPasspointProviderUninstallation++; + } + } + + /** + * Increment number of times Passpoint provider is uninstalled successfully. + */ + public void incrementNumPasspointProviderUninstallSuccess() { + synchronized (mLock) { + mWifiLogProto.numPasspointProviderUninstallSuccess++; + } + } public static final String PROTO_DUMP_ARG = "wifiMetricsProto"; public static final String CLEAN_DUMP_ARG = "clean"; @@ -1228,6 +1263,19 @@ public class WifiMetrics { pw.println(staEventToString(event)); } + pw.println("mWifiLogProto.numPasspointProviders=" + + mWifiLogProto.numPasspointProviders); + pw.println("mWifiLogProto.numPasspointProviderInstallation=" + + mWifiLogProto.numPasspointProviderInstallation); + pw.println("mWifiLogProto.numPasspointProviderInstallSuccess=" + + mWifiLogProto.numPasspointProviderInstallSuccess); + pw.println("mWifiLogProto.numPasspointProviderUninstallation=" + + mWifiLogProto.numPasspointProviderUninstallation); + pw.println("mWifiLogProto.numPasspointProviderUninstallSuccess=" + + mWifiLogProto.numPasspointProviderUninstallSuccess); + pw.println("mWifiLogProto.numPasspointProvidersSuccessfullyConnected=" + + mWifiLogProto.numPasspointProvidersSuccessfullyConnected); + pw.println("mWifiAwareMetrics:"); mWifiAwareMetrics.dump(fd, pw, args); } @@ -1272,6 +1320,17 @@ public class WifiMetrics { } } + /** + * Update number of saved Passpoint profiles. + * + * @param numSavedProfiles The number of saved Passpoint profiles + */ + public void updateSavedPasspointProfiles(int numSavedProfiles) { + synchronized (mLock) { + mWifiLogProto.numPasspointProviders = numSavedProfiles; + } + } + /** * append the separate ConnectionEvent, SystemStateEntry and ScanReturnCode collections to their * respective lists within mWifiLogProto diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 0fb61df17..688a53cb8 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -6985,6 +6985,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss */ public void updateWifiMetrics() { mWifiMetrics.updateSavedNetworks(mWifiConfigManager.getSavedNetworks()); + mWifiMetrics.updateSavedPasspointProfiles(mPasspointManager.getProviderConfigs().size()); } /** diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java index 3695ba35f..dad622136 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java @@ -45,6 +45,7 @@ import com.android.server.wifi.SIMAccessor; import com.android.server.wifi.WifiConfigManager; import com.android.server.wifi.WifiConfigStore; import com.android.server.wifi.WifiKeyStore; +import com.android.server.wifi.WifiMetrics; import com.android.server.wifi.WifiNative; import com.android.server.wifi.hotspot2.anqp.ANQPElement; import com.android.server.wifi.hotspot2.anqp.Constants; @@ -97,6 +98,7 @@ public class PasspointManager { private final ANQPRequestManager mAnqpRequestManager; private final WifiConfigManager mWifiConfigManager; private final CertificateVerifier mCertVerifier; + private final WifiMetrics mWifiMetrics; // Counter used for assigning unique identifier to each provider. private long mProviderIndex; @@ -194,7 +196,8 @@ public class PasspointManager { public PasspointManager(Context context, WifiNative wifiNative, WifiKeyStore keyStore, Clock clock, SIMAccessor simAccessor, PasspointObjectFactory objectFactory, - WifiConfigManager wifiConfigManager, WifiConfigStore wifiConfigStore) { + WifiConfigManager wifiConfigManager, WifiConfigStore wifiConfigStore, + WifiMetrics wifiMetrics) { mHandler = objectFactory.makePasspointEventHandler(wifiNative, new CallbackHandler(context)); mKeyStore = keyStore; @@ -205,6 +208,7 @@ public class PasspointManager { mAnqpRequestManager = objectFactory.makeANQPRequestManager(mHandler, clock); mCertVerifier = objectFactory.makeCertificateVerifier(); mWifiConfigManager = wifiConfigManager; + mWifiMetrics = wifiMetrics; mProviderIndex = 0; wifiConfigStore.registerStoreData(objectFactory.makePasspointConfigStoreData( mKeyStore, mSimAccessor, new DataSourceHandler())); @@ -222,6 +226,7 @@ public class PasspointManager { * @return true if provider is added, false otherwise */ public boolean addOrUpdateProvider(PasspointConfiguration config, int uid) { + mWifiMetrics.incrementNumPasspointProviderInstallation(); if (config == null) { Log.e(TAG, "Configuration not provided"); return false; @@ -266,6 +271,7 @@ public class PasspointManager { mWifiConfigManager.saveToStore(true /* forceWrite */); Log.d(TAG, "Added/updated Passpoint configuration: " + config.getHomeSp().getFqdn() + " by " + uid); + mWifiMetrics.incrementNumPasspointProviderInstallSuccess(); return true; } @@ -276,6 +282,7 @@ public class PasspointManager { * @return true if a provider is removed, false otherwise */ public boolean removeProvider(String fqdn) { + mWifiMetrics.incrementNumPasspointProviderUninstallation(); if (!mProviders.containsKey(fqdn)) { Log.e(TAG, "Config doesn't exist"); return false; @@ -285,6 +292,7 @@ public class PasspointManager { mProviders.remove(fqdn); mWifiConfigManager.saveToStore(true /* forceWrite */); Log.d(TAG, "Removed Passpoint configuration: " + fqdn); + mWifiMetrics.incrementNumPasspointProviderUninstallSuccess(); return true; } -- cgit v1.2.3 From 49357a30edf5786c8db4bad6f5dbe62545751cc6 Mon Sep 17 00:00:00 2001 From: Peter Qiu Date: Thu, 22 Jun 2017 15:48:19 -0700 Subject: 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 --- .../java/com/android/server/wifi/WifiMetrics.java | 7 ++-- .../com/android/server/wifi/WifiStateMachine.java | 8 ++++- .../wifi/hotspot2/PasspointConfigStoreData.java | 9 +++++- .../server/wifi/hotspot2/PasspointManager.java | 37 +++++++++++++++++++++- .../server/wifi/hotspot2/PasspointProvider.java | 16 ++++++++-- 5 files changed, 70 insertions(+), 7 deletions(-) (limited to 'service') 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 @@ -535,6 +535,41 @@ public class PasspointManager { return providers; } + /** + * 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 entry : mProviders.entrySet()) { + if (entry.getValue().getHasEverConnected()) { + numConnectedProviders++; + } + } + mWifiMetrics.updateSavedPasspointProfiles(numProviders, numConnectedProviders); + } + /** * Dump the current state of PasspointManager to the provided output stream. * @@ -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 -- cgit v1.2.3