summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorPeter Qiu <zqiu@google.com>2016-12-13 14:17:20 -0800
committerPeter Qiu <zqiu@google.com>2017-01-07 19:06:28 -0800
commitd28cfdde236d3d7c72f0c57ca7f18622b16d421a (patch)
tree99c6e51f183cef0e558e66b3062fa0e591ae377a /service
parente1ea3ef20d6cd94f89e3a9ff7c5c38307dedc6f6 (diff)
hotspot2: Passpoint configuration APIs update
- renamed addPasspointConfiguration to addOrUpdatePasspointConfiguration to match the implementation of the API - updated PasspointManager to update passpoint provider using exact FQDN string matching instead of base domain matching, to avoid unnecessary complexities. - updated getPasspointConfigurations to return an empty list instead of a null when no configuration is installled - updated PasspointManager to use a 64-bit counter for assigning provider IDs instead of using the wall clock to avoid possible ID conflicts. The use of an unique provider ID is necessary to avoid leaving keys and certificates in a bad state when failing to install keys and certificates on the update operation. Bug: 33587910 Test: frameworks/opt/net/wifi/tests/wifitests/runtests.sh Change-Id: Iee304fe742085ec91d8d448e0939201d293ab7e5
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/WifiServiceImpl.java10
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointManager.java93
2 files changed, 36 insertions, 67 deletions
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 27605e9bb..ff8c0b99a 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -1020,15 +1020,15 @@ public class WifiServiceImpl extends IWifiManager.Stub {
}
/**
- * Add a Passpoint configuration.
+ * Add or update a Passpoint configuration.
*
* @param config The Passpoint configuration to be added
* @return true on success or false on failure
*/
@Override
- public boolean addPasspointConfiguration(PasspointConfiguration config) {
+ public boolean addOrUpdatePasspointConfiguration(PasspointConfiguration config) {
enforceChangePermission();
- return mPasspointManager.addProvider(config);
+ return mPasspointManager.addOrUpdateProvider(config);
}
/**
@@ -1046,7 +1046,9 @@ public class WifiServiceImpl extends IWifiManager.Stub {
/**
* Return the list of the installed Passpoint configurations.
*
- * @return A list of {@link PasspointConfiguration} or null
+ * An empty list will be returned when no configuration is installed.
+ *
+ * @return A list of {@link PasspointConfiguration}
*/
@Override
public List<PasspointConfiguration> getPasspointConfigurations() {
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java
index d0ced7b00..31a0b5ef6 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java
@@ -31,7 +31,6 @@ import android.content.Context;
import android.content.Intent;
import android.net.wifi.hotspot2.PasspointConfiguration;
import android.os.UserHandle;
-import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
@@ -47,12 +46,24 @@ import com.android.server.wifi.hotspot2.anqp.Constants;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
- * Responsible for managing passpoint networks.
+ * This class provides the APIs to manage Passpoint provider configurations.
+ * It deals with the following:
+ * - Maintaining a list of configured Passpoint providers for provider matching.
+ * - Persisting the providers configurations to store when required.
+ * - matching Passpoint providers based on the scan results
+ * - Supporting WifiManager Public API calls:
+ * > addOrUpdatePasspointConfiguration()
+ * > removePasspointConfiguration()
+ * > getPasspointConfigurations()
+ *
+ * The provider matching requires obtaining additional information from the AP (ANQP elements).
+ * The ANQP elements will be cached using {@link AnqpCache} to avoid unnecessary requests.
+ *
+ * NOTE: These API's are not thread safe and should only be used from WifiStateMachine thread.
*/
public class PasspointManager {
private static final String TAG = "PasspointManager";
@@ -60,12 +71,14 @@ public class PasspointManager {
private final PasspointEventHandler mHandler;
private final SIMAccessor mSimAccessor;
private final WifiKeyStore mKeyStore;
- private final Clock mClock;
private final PasspointObjectFactory mObjectFactory;
private final Map<String, PasspointProvider> mProviders;
private final AnqpCache mAnqpCache;
private final Map<Long, ANQPNetworkKey> mPendingAnqpQueries;
+ // Counter used for assigning unique identifier to a provider.
+ private long mProviderID;
+
private class CallbackHandler implements PasspointEventHandler.Callbacks {
private final Context mContext;
CallbackHandler(Context context) {
@@ -133,26 +146,26 @@ public class PasspointManager {
mHandler = objectFactory.makePasspointEventHandler(wifiNative,
new CallbackHandler(context));
mKeyStore = keyStore;
- mClock = clock;
mSimAccessor = simAccessor;
mObjectFactory = objectFactory;
mProviders = new HashMap<>();
mAnqpCache = objectFactory.makeAnqpCache(clock);
mPendingAnqpQueries = new HashMap<>();
+ mProviderID = 0;
// TODO(zqiu): load providers from the persistent storage.
}
/**
- * Add or install a Passpoint provider with the given configuration.
+ * Add or update a Passpoint provider with the given configuration.
*
* Each provider is uniquely identified by its FQDN (Fully Qualified Domain Name).
- * In the case when there is an existing configuration with the same base
- * domain, a provider with the new configuration will replace the existing provider.
+ * In the case when there is an existing configuration with the same FQDN
+ * a provider with the new configuration will replace the existing provider.
*
* @param config Configuration of the Passpoint provider to be added
* @return true if provider is added, false otherwise
*/
- public boolean addProvider(PasspointConfiguration config) {
+ public boolean addOrUpdateProvider(PasspointConfiguration config) {
if (config == null) {
Log.e(TAG, "Configuration not provided");
return false;
@@ -177,20 +190,17 @@ public class PasspointManager {
// Create a provider and install the necessary certificates and keys.
PasspointProvider newProvider = mObjectFactory.makePasspointProvider(
- config, mKeyStore, mClock.getWallClockMillis());
+ config, mKeyStore, mProviderID++);
if (!newProvider.installCertsAndKeys()) {
Log.e(TAG, "Failed to install certificates and keys to keystore");
return false;
}
- // Detect existing configuration in the same base domain.
- PasspointProvider existingProvider = findProviderInSameBaseDomain(config.homeSp.fqdn);
- if (existingProvider != null) {
- Log.d(TAG, "Replacing configuration for " + existingProvider.getConfig().homeSp.fqdn
- + " with " + config.homeSp.fqdn);
- existingProvider.uninstallCertsAndKeys();
- mProviders.remove(existingProvider.getConfig().homeSp.fqdn);
+ // Remove existing provider with the same FQDN.
+ if (mProviders.containsKey(config.homeSp.fqdn)) {
+ Log.d(TAG, "Replacing configuration for " + config.homeSp.fqdn);
+ removeProvider(config.homeSp.fqdn);
}
mProviders.put(config.homeSp.fqdn, newProvider);
@@ -220,13 +230,11 @@ public class PasspointManager {
/**
* Return the installed Passpoint provider configurations.
*
- * @return A list of {@link PasspointConfiguration} or null if none is installed
+ * An empty list will be returned when no provider is installed.
+ *
+ * @return A list of {@link PasspointConfiguration}
*/
public List<PasspointConfiguration> getProviderConfigs() {
- if (mProviders.size() == 0) {
- return null;
- }
-
List<PasspointConfiguration> configs = new ArrayList<>();
for (Map.Entry<String, PasspointProvider> entry : mProviders.entrySet()) {
configs.add(entry.getValue().getConfig());
@@ -317,45 +325,4 @@ public class PasspointManager {
public boolean queryPasspointIcon(long bssid, String fileName) {
return mHandler.requestIcon(bssid, fileName);
}
-
- /**
- * Find a provider that have FQDN in the same base domain as the given domain.
- *
- * @param domain The domain to be compared
- * @return {@link PasspointProvider} if a match is found, null otherwise
- */
- private PasspointProvider findProviderInSameBaseDomain(String domain) {
- for (Map.Entry<String, PasspointProvider> entry : mProviders.entrySet()) {
- if (isSameBaseDomain(entry.getKey(), domain)) {
- return entry.getValue();
- }
- }
- return null;
- }
-
- /**
- * Check if one domain is the base domain for the other. For example, "test1.test.com"
- * and "test.com" should return true.
- *
- * @param domain1 First domain to be compared
- * @param domain2 Second domain to be compared
- * @return true if one domain is a base domain for the other, false otherwise.
- */
- private static boolean isSameBaseDomain(String domain1, String domain2) {
- if (domain1 == null || domain2 == null) {
- return false;
- }
-
- List<String> labelList1 = Utils.splitDomain(domain1);
- List<String> labelList2 = Utils.splitDomain(domain2);
- Iterator<String> l1 = labelList1.iterator();
- Iterator<String> l2 = labelList2.iterator();
-
- while (l1.hasNext() && l2.hasNext()) {
- if (!TextUtils.equals(l1.next(), l2.next())) {
- return false;
- }
- }
- return true;
- }
}