diff options
19 files changed, 382 insertions, 211 deletions
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java index 7c8cddae8..48dfc2fd1 100644 --- a/service/java/com/android/server/wifi/WifiConfigManager.java +++ b/service/java/com/android/server/wifi/WifiConfigManager.java @@ -34,7 +34,6 @@ import android.net.wifi.WifiEnterpriseConfig; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.net.wifi.WifiScanner; -import android.os.Process; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; @@ -2666,17 +2665,14 @@ public class WifiConfigManager { // List of network IDs for legacy Passpoint configuration to be removed. List<Integer> legacyPasspointNetId = new ArrayList<>(); for (WifiConfiguration config : mConfiguredNetworks.valuesForAllUsers()) { - // Ignore ephemeral and temporary Passpoint networks. Temporary Passpoint networks - // are created by {@link PasspointNetworkEvaluator} using WIFI_UID. - if (config.ephemeral || (config.isPasspoint() - && config.creatorUid == Process.WIFI_UID)) { + // Ignore ephemeral networks and non-legacy Passpoint configurations. + if (config.ephemeral || (config.isPasspoint() && !config.isLegacyPasspointConfig)) { continue; } - // Legacy Passpoint configuration represented by WifiConfiguration is created by an - // actual user, so migrate the configurations owned by the current user to + // Migrate the legacy Passpoint configurations owned by the current user to // {@link PasspointManager}. - if (config.isPasspoint() && WifiConfigurationUtil.doesUidBelongToAnyProfile( + if (config.isLegacyPasspointConfig && WifiConfigurationUtil.doesUidBelongToAnyProfile( config.creatorUid, mUserManager.getProfiles(mCurrentUserId))) { legacyPasspointNetId.add(config.networkId); // Migrate the legacy Passpoint configuration and add it to PasspointManager. diff --git a/service/java/com/android/server/wifi/WifiConfigStoreLegacy.java b/service/java/com/android/server/wifi/WifiConfigStoreLegacy.java index e7a7335d7..42a91de67 100644 --- a/service/java/com/android/server/wifi/WifiConfigStoreLegacy.java +++ b/service/java/com/android/server/wifi/WifiConfigStoreLegacy.java @@ -226,6 +226,7 @@ public class WifiConfigStoreLegacy { // Update the missing Passpoint configuration fields to this WifiConfiguration. LegacyPasspointConfig passpointConfig = passpointConfigMap.get(fqdn); + wifiConfig.isLegacyPasspointConfig = true; wifiConfig.FQDN = fqdn; wifiConfig.providerFriendlyName = passpointConfig.mFriendlyName; if (passpointConfig.mRoamingConsortiumOis != null) { diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index a5dc9375f..2f86743f2 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -1836,7 +1836,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss public WifiConfiguration syncGetMatchingWifiConfig(ScanResult scanResult, AsyncChannel channel) { Message resultMsg = channel.sendMessageSynchronously(CMD_GET_MATCHING_CONFIG, scanResult); - return (WifiConfiguration) resultMsg.obj; + WifiConfiguration config = (WifiConfiguration) resultMsg.obj; + resultMsg.recycle(); + return config; } /** @@ -4952,8 +4954,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss } break; case CMD_GET_MATCHING_CONFIG: - // TODO(b/31065385) - replyToMessage(message, message.what, null); + replyToMessage(message, message.what, + mPasspointManager.getMatchingWifiConfig((ScanResult) message.obj)); break; case CMD_RECONNECT: mWifiConnectivityManager.forceConnectivityScan(); diff --git a/service/java/com/android/server/wifi/hotspot2/ANQPRequestManager.java b/service/java/com/android/server/wifi/hotspot2/ANQPRequestManager.java index fd756c3a2..dfdf4ad16 100644 --- a/service/java/com/android/server/wifi/hotspot2/ANQPRequestManager.java +++ b/service/java/com/android/server/wifi/hotspot2/ANQPRequestManager.java @@ -20,7 +20,6 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.server.wifi.Clock; -import com.android.server.wifi.ScanDetail; import com.android.server.wifi.hotspot2.anqp.Constants; import java.util.ArrayList; @@ -43,7 +42,7 @@ public class ANQPRequestManager { /** * List of pending ANQP request associated with an AP (BSSID). */ - private final Map<Long, ScanDetail> mPendingQueries; + private final Map<Long, ANQPNetworkKey> mPendingQueries; /** * List of hold off time information associated with APs specified by their BSSID. @@ -109,14 +108,14 @@ public class ANQPRequestManager { * supported Hotspot 2.0 release version). * * @param bssid The BSSID of the AP - * @param scanDetail The ScanDetail associated with this request + * @param anqpNetworkKey The unique network key associated with this request * @param rcOIs Flag indicating the inclusion of roaming consortium OIs. When set to true, * Roaming Consortium ANQP element will be requested * @param hsReleaseR2 Flag indicating the support of Hotspot 2.0 Release 2. When set to true, * the Release 2 ANQP elements {@link #R2_ANQP_BASE_SET} will be requested * @return true if a request was sent successfully */ - public boolean requestANQPElements(long bssid, ScanDetail scanDetail, boolean rcOIs, + public boolean requestANQPElements(long bssid, ANQPNetworkKey anqpNetworkKey, boolean rcOIs, boolean hsReleaseR2) { // Check if we are allow to send the request now. if (!canSendRequestNow(bssid)) { @@ -132,7 +131,7 @@ public class ANQPRequestManager { // the given AP. updateHoldOffInfo(bssid); - mPendingQueries.put(bssid, scanDetail); + mPendingQueries.put(bssid, anqpNetworkKey); return true; } @@ -141,9 +140,9 @@ public class ANQPRequestManager { * * @param bssid The BSSID of the AP * @param success Flag indicating the result of the query - * @return {@link ScanDetail} associated with the completed request + * @return {@link ANQPNetworkKey} associated with the completed request */ - public ScanDetail onRequestCompleted(long bssid, boolean success) { + public ANQPNetworkKey onRequestCompleted(long bssid, boolean success) { if (success) { // Query succeeded. No need to hold off request to the given AP. mHoldOffInfo.remove(bssid); diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java index ff8b50f77..c3acd39c3 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java @@ -29,6 +29,7 @@ import static android.net.wifi.WifiManager.EXTRA_URL; import android.content.Context; import android.content.Intent; import android.net.wifi.IconInfo; +import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiEnterpriseConfig; import android.net.wifi.hotspot2.PasspointConfiguration; @@ -39,13 +40,14 @@ import android.util.Pair; import com.android.server.wifi.Clock; import com.android.server.wifi.SIMAccessor; -import com.android.server.wifi.ScanDetail; import com.android.server.wifi.WifiConfigManager; import com.android.server.wifi.WifiConfigStore; import com.android.server.wifi.WifiKeyStore; import com.android.server.wifi.WifiNative; import com.android.server.wifi.hotspot2.anqp.ANQPElement; import com.android.server.wifi.hotspot2.anqp.Constants; +import com.android.server.wifi.util.InformationElementUtil; +import com.android.server.wifi.util.ScanResultUtil; import java.util.ArrayList; import java.util.HashMap; @@ -103,23 +105,16 @@ public class PasspointManager { public void onANQPResponse(long bssid, Map<Constants.ANQPElementType, ANQPElement> anqpElements) { // Notify request manager for the completion of a request. - ScanDetail scanDetail = + ANQPNetworkKey anqpKey = mAnqpRequestManager.onRequestCompleted(bssid, anqpElements != null); - if (anqpElements == null || scanDetail == null) { + if (anqpElements == null || anqpKey == null) { // Query failed or the request wasn't originated from us (not tracked by the // request manager). Nothing to be done. return; } // Add new entry to the cache. - NetworkDetail networkDetail = scanDetail.getNetworkDetail(); - ANQPNetworkKey anqpKey = ANQPNetworkKey.buildKey(networkDetail.getSSID(), - networkDetail.getBSSID(), networkDetail.getHESSID(), - networkDetail.getAnqpDomainID()); mAnqpCache.addEntry(anqpKey, anqpElements); - - // Update ANQP elements in the ScanDetail. - scanDetail.propagateANQPInfo(anqpElements); } @Override @@ -281,44 +276,57 @@ public class PasspointManager { } /** - * Find the providers that can provide service through the given AP, which means the - * providers contained credential to authenticate with the given AP. + * Find the best provider that can provide service through the given AP, which means the + * provider contained credential to authenticate with the given AP. + * + * Here is the current precedence of the matching rule in descending order: + * 1. Home Provider + * 2. Roaming Provider * - * An empty list will returned in the case when no match is found. + * A {code null} will be returned if no matching is found. * - * @param scanDetail The detail information of the AP - * @return List of {@link PasspointProvider} + * @param scanResult The scan result associated with the AP + * @return A pair of {@link PasspointProvider} and match status. */ - public List<Pair<PasspointProvider, PasspointMatch>> matchProvider(ScanDetail scanDetail) { + public Pair<PasspointProvider, PasspointMatch> matchProvider(ScanResult scanResult) { // Nothing to be done if no Passpoint provider is installed. if (mProviders.isEmpty()) { - return new ArrayList<Pair<PasspointProvider, PasspointMatch>>(); + return null; } + // Retrieve the relevant information elements, mainly Roaming Consortium IE and Hotspot 2.0 + // Vendor Specific IE. + InformationElementUtil.RoamingConsortium roamingConsortium = + InformationElementUtil.getRoamingConsortiumIE(scanResult.informationElements); + InformationElementUtil.Vsa vsa = InformationElementUtil.getHS2VendorSpecificIE( + scanResult.informationElements); + // Lookup ANQP data in the cache. - NetworkDetail networkDetail = scanDetail.getNetworkDetail(); - ANQPNetworkKey anqpKey = ANQPNetworkKey.buildKey(networkDetail.getSSID(), - networkDetail.getBSSID(), networkDetail.getHESSID(), - networkDetail.getAnqpDomainID()); + long bssid = Utils.parseMac(scanResult.BSSID); + ANQPNetworkKey anqpKey = ANQPNetworkKey.buildKey(scanResult.SSID, bssid, scanResult.hessid, + vsa.anqpDomainID); ANQPData anqpEntry = mAnqpCache.getEntry(anqpKey); if (anqpEntry == null) { - mAnqpRequestManager.requestANQPElements(networkDetail.getBSSID(), scanDetail, - networkDetail.getAnqpOICount() > 0, - networkDetail.getHSRelease() == NetworkDetail.HSRelease.R2); - return new ArrayList<Pair<PasspointProvider, PasspointMatch>>(); + mAnqpRequestManager.requestANQPElements(bssid, anqpKey, + roamingConsortium.anqpOICount > 0, + vsa.hsRelease == NetworkDetail.HSRelease.R2); + return null; } - List<Pair<PasspointProvider, PasspointMatch>> results = new ArrayList<>(); + Pair<PasspointProvider, PasspointMatch> bestMatch = null; for (Map.Entry<String, PasspointProvider> entry : mProviders.entrySet()) { PasspointProvider provider = entry.getValue(); PasspointMatch matchStatus = provider.match(anqpEntry.getElements()); - if (matchStatus == PasspointMatch.HomeProvider - || matchStatus == PasspointMatch.RoamingProvider) { - results.add(new Pair<PasspointProvider, PasspointMatch>(provider, matchStatus)); + if (matchStatus == PasspointMatch.HomeProvider) { + bestMatch = Pair.create(provider, matchStatus); + break; + } + if (matchStatus == PasspointMatch.RoamingProvider && bestMatch == null) { + bestMatch = Pair.create(provider, matchStatus); } } - return results; + return bestMatch; } /** @@ -383,6 +391,51 @@ public class PasspointManager { } /** + * Lookup the ANQP elements associated with the given AP from the cache. An empty map + * will be returned if no match found in the cache. + * + * @param scanResult The scan result associated with the AP + * @return Map of ANQP elements + */ + public Map<Constants.ANQPElementType, ANQPElement> getANQPElements(ScanResult scanResult) { + // Retrieve the Hotspot 2.0 Vendor Specific IE. + InformationElementUtil.Vsa vsa = + InformationElementUtil.getHS2VendorSpecificIE(scanResult.informationElements); + + // Lookup ANQP data in the cache. + long bssid = Utils.parseMac(scanResult.BSSID); + ANQPData anqpEntry = mAnqpCache.getEntry(ANQPNetworkKey.buildKey( + scanResult.SSID, bssid, scanResult.hessid, vsa.anqpDomainID)); + if (anqpEntry != null) { + return anqpEntry.getElements(); + } + return new HashMap<Constants.ANQPElementType, ANQPElement>(); + } + + /** + * Match the given WiFi AP to an installed Passpoint provider. A {@link WifiConfiguration} + * will be generated and returned if a match is found. The returned {@link WifiConfiguration} + * will contained all the necessary credentials for connecting to the given WiFi AP. + * + * A {code null} will be returned if no matching provider is found. + * + * @param scanResult The scan result of the given AP + * @return {@link WifiConfiguration} + */ + public WifiConfiguration getMatchingWifiConfig(ScanResult scanResult) { + if (scanResult == null) { + return null; + } + Pair<PasspointProvider, PasspointMatch> matchedProvider = matchProvider(scanResult); + if (matchedProvider == null) { + return null; + } + WifiConfiguration config = matchedProvider.first.getWifiConfig(); + config.SSID = ScanResultUtil.createQuotedSSID(scanResult.SSID); + return config; + } + + /** * Add a legacy Passpoint configuration represented by a {@link WifiConfiguration}. * * @param wifiConfig {@link WifiConfiguration} representation of the Passpoint configuration diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java index f08b5de32..740a302cc 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java @@ -62,6 +62,9 @@ public class PasspointNetworkEvaluator implements WifiNetworkSelector.NetworkEva WifiConfiguration currentNetwork, String currentBssid, boolean connected, boolean untrustedNetworkAllowed, List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks) { + // Sweep the ANQP cache to remove any expired ANQP entries. + mPasspointManager.sweepCache(); + // Go through each ScanDetail and find the best provider for each ScanDetail. List<Pair<ScanDetail, Pair<PasspointProvider, PasspointMatch>>> providerList = new ArrayList<>(); @@ -71,12 +74,9 @@ public class PasspointNetworkEvaluator implements WifiNetworkSelector.NetworkEva continue; } - List<Pair<PasspointProvider, PasspointMatch>> matchedProviders = - mPasspointManager.matchProvider(scanDetail); - // Find the best provider for this ScanDetail. Pair<PasspointProvider, PasspointMatch> bestProvider = - findBestProvider(matchedProviders); + mPasspointManager.matchProvider(scanDetail.getScanResult()); if (bestProvider != null) { providerList.add(Pair.create(scanDetail, bestProvider)); } @@ -132,33 +132,6 @@ public class PasspointNetworkEvaluator implements WifiNetworkSelector.NetworkEva } /** - * Given a list of provider associated with a ScanDetail, determine and return the best - * provider from the list. - * - * Currently the only criteria is to prefer home provider over roaming provider. Additional - * criteria will be added when Hotspot 2.0 Release 2 support is added. - * - * A null will be returned if no match is found (providerList is empty). - * - * @param providerList The list of matched providers - * @return Pair of {@link PasspointProvider} with its matching status - */ - private Pair<PasspointProvider, PasspointMatch> findBestProvider( - List<Pair<PasspointProvider, PasspointMatch>> providerList) { - Pair<PasspointProvider, PasspointMatch> bestMatch = null; - for (Pair<PasspointProvider, PasspointMatch> providerMatch : providerList) { - if (providerMatch.second == PasspointMatch.HomeProvider) { - // Home provider found, done. - bestMatch = providerMatch; - break; - } else if (bestMatch == null) { - bestMatch = providerMatch; - } - } - return bestMatch; - } - - /** * Given a list of Passpoint networks (with both provider and scan info), find and return * the one with highest score. The score is calculated using * {@link PasspointNetworkScore#calculateScore}. @@ -181,7 +154,8 @@ public class PasspointNetworkEvaluator implements WifiNetworkSelector.NetworkEva boolean isActiveNetwork = TextUtils.equals(currentNetworkSsid, ScanResultUtil.createQuotedSSID(scanDetail.getSSID())); int score = PasspointNetworkScore.calculateScore(match == PasspointMatch.HomeProvider, - scanDetail, isActiveNetwork); + scanDetail, mPasspointManager.getANQPElements(scanDetail.getScanResult()), + isActiveNetwork); if (score > bestScore) { bestScanDetail = scanDetail; diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkScore.java b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkScore.java index 2dc3789f5..03f2e4c2d 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkScore.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkScore.java @@ -145,7 +145,7 @@ public class PasspointNetworkScore { * @return integer score */ public static int calculateScore(boolean isHomeProvider, ScanDetail scanDetail, - boolean isActiveNetwork) { + Map<ANQPElementType, ANQPElement> anqpElements, boolean isActiveNetwork) { NetworkDetail networkDetail = scanDetail.getNetworkDetail(); int score = 0; if (isHomeProvider) { @@ -158,9 +158,9 @@ public class PasspointNetworkScore { // Adjust score based on the network type. score += NETWORK_TYPE_SCORES.get(networkDetail.getAnt()); - Map<ANQPElementType, ANQPElement> anqp = networkDetail.getANQPElements(); - if (anqp != null) { - HSWanMetricsElement wm = (HSWanMetricsElement) anqp.get(ANQPElementType.HSWANMetrics); + if (anqpElements != null) { + HSWanMetricsElement wm = + (HSWanMetricsElement) anqpElements.get(ANQPElementType.HSWANMetrics); if (wm != null) { if (wm.getStatus() != HSWanMetricsElement.LINK_STATUS_UP || wm.isCapped()) { score -= WAN_PORT_DOWN_OR_CAPPED_PENALTY; @@ -168,7 +168,7 @@ public class PasspointNetworkScore { } IPAddressTypeAvailabilityElement ipa = (IPAddressTypeAvailabilityElement) - anqp.get(ANQPElementType.ANQPIPAddrAvailability); + anqpElements.get(ANQPElementType.ANQPIPAddrAvailability); if (ipa != null) { Integer v4Score = IPV4_SCORES.get(ipa.getV4Availability()); diff --git a/service/java/com/android/server/wifi/util/XmlUtil.java b/service/java/com/android/server/wifi/util/XmlUtil.java index 76b8a3292..42303b009 100644 --- a/service/java/com/android/server/wifi/util/XmlUtil.java +++ b/service/java/com/android/server/wifi/util/XmlUtil.java @@ -336,6 +336,8 @@ public class XmlUtil { public static final String XML_TAG_LAST_UPDATE_UID = "LastUpdateUid"; public static final String XML_TAG_LAST_UPDATE_NAME = "LastUpdateName"; public static final String XML_TAG_LAST_CONNECT_UID = "LastConnectUid"; + public static final String XML_TAG_IS_LEGACY_PASSPOINT_CONFIG = "IsLegacyPasspointConfig"; + public static final String XML_TAG_ROAMING_CONSORTIUM_OIS = "RoamingConsortiumOIs"; /** * Write WepKeys to the XML stream. @@ -448,6 +450,11 @@ public class XmlUtil { XmlUtil.writeNextValue(out, XML_TAG_LAST_UPDATE_UID, configuration.lastUpdateUid); XmlUtil.writeNextValue(out, XML_TAG_LAST_UPDATE_NAME, configuration.lastUpdateName); XmlUtil.writeNextValue(out, XML_TAG_LAST_CONNECT_UID, configuration.lastConnectUid); + XmlUtil.writeNextValue( + out, XML_TAG_IS_LEGACY_PASSPOINT_CONFIG, + configuration.isLegacyPasspointConfig); + XmlUtil.writeNextValue( + out, XML_TAG_ROAMING_CONSORTIUM_OIS, configuration.roamingConsortiumIds); } /** @@ -598,6 +605,12 @@ public class XmlUtil { case XML_TAG_LAST_CONNECT_UID: configuration.lastConnectUid = (int) value; break; + case XML_TAG_IS_LEGACY_PASSPOINT_CONFIG: + configuration.isLegacyPasspointConfig = (boolean) value; + break; + case XML_TAG_ROAMING_CONSORTIUM_OIS: + configuration.roamingConsortiumIds = (long[]) value; + break; default: throw new XmlPullParserException( "Unknown value name found: " + valueName[0]); @@ -949,6 +962,8 @@ public class XmlUtil { public static final String XML_TAG_CA_PATH = "CaPath"; public static final String XML_TAG_EAP_METHOD = "EapMethod"; public static final String XML_TAG_PHASE2_METHOD = "Phase2Method"; + public static final String XML_TAG_PLMN = "PLMN"; + public static final String XML_TAG_REALM = "Realm"; /** * Write the WifiEnterpriseConfig data elements from the provided config to the XML @@ -985,6 +1000,8 @@ public class XmlUtil { enterpriseConfig.getFieldValue(WifiEnterpriseConfig.CA_PATH_KEY)); XmlUtil.writeNextValue(out, XML_TAG_EAP_METHOD, enterpriseConfig.getEapMethod()); XmlUtil.writeNextValue(out, XML_TAG_PHASE2_METHOD, enterpriseConfig.getPhase2Method()); + XmlUtil.writeNextValue(out, XML_TAG_PLMN, enterpriseConfig.getPlmn()); + XmlUtil.writeNextValue(out, XML_TAG_REALM, enterpriseConfig.getRealm()); } /** @@ -1060,6 +1077,12 @@ public class XmlUtil { case XML_TAG_PHASE2_METHOD: enterpriseConfig.setPhase2Method((int) value); break; + case XML_TAG_PLMN: + enterpriseConfig.setPlmn((String) value); + break; + case XML_TAG_REALM: + enterpriseConfig.setRealm((String) value); + break; default: throw new XmlPullParserException( "Unknown value name found: " + valueName[0]); diff --git a/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java b/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java index 7532b7d31..01257c16e 100644 --- a/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java +++ b/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java @@ -83,6 +83,8 @@ public class NetworkListStoreDataTest { + "<int name=\"LastUpdateUid\" value=\"-1\" />\n" + "<null name=\"LastUpdateName\" />\n" + "<int name=\"LastConnectUid\" value=\"0\" />\n" + + "<boolean name=\"IsLegacyPasspointConfig\" value=\"false\" />\n" + + "<long-array name=\"RoamingConsortiumOIs\" num=\"0\" />\n" + "</WifiConfiguration>\n" + "<NetworkStatus>\n" + "<string name=\"SelectionStatus\">NETWORK_SELECTION_ENABLED</string>\n" @@ -131,6 +133,8 @@ public class NetworkListStoreDataTest { + "<int name=\"LastUpdateUid\" value=\"-1\" />\n" + "<null name=\"LastUpdateName\" />\n" + "<int name=\"LastConnectUid\" value=\"0\" />\n" + + "<boolean name=\"IsLegacyPasspointConfig\" value=\"false\" />\n" + + "<long-array name=\"RoamingConsortiumOIs\" num=\"0\" />\n" + "</WifiConfiguration>\n" + "<NetworkStatus>\n" + "<string name=\"SelectionStatus\">NETWORK_SELECTION_ENABLED</string>\n" @@ -158,6 +162,8 @@ public class NetworkListStoreDataTest { + "<string name=\"CaPath\"></string>\n" + "<int name=\"EapMethod\" value=\"2\" />\n" + "<int name=\"Phase2Method\" value=\"0\" />\n" + + "<string name=\"PLMN\"></string>\n" + + "<string name=\"Realm\"></string>\n" + "</WifiEnterpriseConfiguration>\n" + "</Network>\n"; diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java index 5c78d0de3..61c74180e 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java @@ -2113,6 +2113,7 @@ public class WifiConfigManagerTest { final WifiConfiguration passpointConfig = WifiConfigurationTestUtil.createPasspointNetwork(); passpointConfig.creatorUid = UserHandle.getUid(user1, appId); + passpointConfig.isLegacyPasspointConfig = true; // Set up the shared store data to contain one legacy Passpoint configuration. List<WifiConfiguration> sharedNetworks = new ArrayList<WifiConfiguration>() { diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreLegacyTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreLegacyTest.java index d30ad57de..4b4e875a1 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreLegacyTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreLegacyTest.java @@ -142,6 +142,7 @@ public class WifiConfigStoreLegacyTest { WifiConfigStoreLegacy.WifiConfigStoreDataLegacy storeData = mWifiConfigStore.read(); // Update the expected configuration for Passpoint network. + passpointNetwork.isLegacyPasspointConfig = true; passpointNetwork.FQDN = fqdn; passpointNetwork.providerFriendlyName = providerFriendlyName; passpointNetwork.roamingConsortiumIds = roamingConsortiumIds; diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java index 9b5af549f..47efed3c4 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java @@ -99,6 +99,8 @@ public class WifiConfigStoreTest { + "<int name=\"LastUpdateUid\" value=\"-1\" />\n" + "<null name=\"LastUpdateName\" />\n" + "<int name=\"LastConnectUid\" value=\"0\" />\n" + + "<boolean name=\"IsLegacyPasspointConfig\" value=\"false\" />\n" + + "<long-array name=\"RoamingConsortiumOIs\" num=\"0\" />\n" + "</WifiConfiguration>\n" + "<NetworkStatus>\n" + "<string name=\"SelectionStatus\">NETWORK_SELECTION_ENABLED</string>\n" diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java index 6b411dad5..917a64cc9 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java @@ -455,6 +455,7 @@ public class WifiConfigurationTestUtil { assertEquals(expected.lastUpdateName, actual.lastUpdateName); assertEquals(expected.lastConnectUid, actual.lastConnectUid); assertEquals(expected.updateTime, actual.updateTime); + assertEquals(expected.isLegacyPasspointConfig, actual.isLegacyPasspointConfig); assertNetworkSelectionStatusEqualForConfigStore( expected.getNetworkSelectionStatus(), actual.getNetworkSelectionStatus()); assertWifiEnterpriseConfigEqualForConfigStore( diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java index c9bc3d657..4ea233a31 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java @@ -18,6 +18,7 @@ package com.android.server.wifi; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.*; @@ -1229,4 +1230,45 @@ public class WifiStateMachineTest { assertTrue(mWsm.syncGetPasspointConfigs(mWsmAsyncChannel).isEmpty()); mLooper.stopAutoDispatch(); } + + /** + * Verify that syncGetMatchingWifiConfig will redirect calls to {@link PasspointManager} + * with expected {@link WifiConfiguration} being returned when in client mode. + * + * @throws Exception + */ + @Test + public void syncGetMatchingWifiConfigInClientMode() throws Exception { + loadComponentsInStaMode(); + + when(mPasspointManager.getMatchingWifiConfig(any(ScanResult.class))).thenReturn(null); + mLooper.startAutoDispatch(); + assertNull(mWsm.syncGetMatchingWifiConfig(new ScanResult(), mWsmAsyncChannel)); + mLooper.stopAutoDispatch(); + reset(mPasspointManager); + + WifiConfiguration expectedConfig = new WifiConfiguration(); + expectedConfig.SSID = "TestSSID"; + when(mPasspointManager.getMatchingWifiConfig(any(ScanResult.class))) + .thenReturn(expectedConfig); + mLooper.startAutoDispatch(); + WifiConfiguration actualConfig = mWsm.syncGetMatchingWifiConfig(new ScanResult(), + mWsmAsyncChannel); + mLooper.stopAutoDispatch(); + assertEquals(expectedConfig.SSID, actualConfig.SSID); + } + + /** + * Verify that syncGetMatchingWifiConfig will be a no-op and return {@code null} when not in + * client mode. + * + * @throws Exception + */ + @Test + public void syncGetMatchingWifiConfigInNonClientMode() throws Exception { + mLooper.startAutoDispatch(); + assertNull(mWsm.syncGetMatchingWifiConfig(new ScanResult(), mWsmAsyncChannel)); + mLooper.stopAutoDispatch(); + verify(mPasspointManager, never()).getMatchingWifiConfig(any(ScanResult.class)); + } } diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPRequestManagerTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPRequestManagerTest.java index 08b37deb9..022d22dae 100644 --- a/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPRequestManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPRequestManagerTest.java @@ -16,11 +16,11 @@ package com.android.server.wifi.hotspot2; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.anyLong; import static org.mockito.Mockito.anyObject; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; @@ -30,7 +30,6 @@ import static org.mockito.MockitoAnnotations.initMocks; import android.test.suitebuilder.annotation.SmallTest; import com.android.server.wifi.Clock; -import com.android.server.wifi.ScanDetail; import com.android.server.wifi.hotspot2.anqp.Constants; import org.junit.Before; @@ -46,7 +45,8 @@ import java.util.List; @SmallTest public class ANQPRequestManagerTest { private static final long TEST_BSSID = 0x123456L; - private static final ScanDetail TEST_SCAN_DETAIL = mock(ScanDetail.class); + private static final ANQPNetworkKey TEST_ANQP_KEY = + new ANQPNetworkKey("TestSSID", TEST_BSSID, 0, 0); private static final List<Constants.ANQPElementType> R1_ANQP_WITHOUT_RC = Arrays.asList( Constants.ANQPElementType.ANQPVenueName, @@ -107,7 +107,7 @@ public class ANQPRequestManagerTest { @Test public void requestR1ANQPElementsWithoutRC() throws Exception { when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); - assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); } /** @@ -120,7 +120,7 @@ public class ANQPRequestManagerTest { @Test public void requestR1ANQPElementsWithRC() throws Exception { when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITH_RC)).thenReturn(true); - assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, true, false)); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, true, false)); } /** @@ -133,7 +133,7 @@ public class ANQPRequestManagerTest { @Test public void requestR1R2ANQPElementsWithoutRC() throws Exception { when(mHandler.requestANQP(TEST_BSSID, R1R2_ANQP_WITHOUT_RC)).thenReturn(true); - assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, true)); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, true)); } /** @@ -146,7 +146,7 @@ public class ANQPRequestManagerTest { @Test public void requestR1R2ANQPElementsWithRC() throws Exception { when(mHandler.requestANQP(TEST_BSSID, R1R2_ANQP_WITH_RC)).thenReturn(true); - assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, true, true)); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, true, true)); } /** @@ -161,13 +161,13 @@ public class ANQPRequestManagerTest { long startTime = 0; when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime); - assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); reset(mHandler); // Attempt another request will fail while one is still pending and hold off time is not up // yet. when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime + 1); - assertFalse(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + assertFalse(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); verify(mHandler, never()).requestANQP(anyLong(), anyObject()); reset(mHandler); @@ -175,7 +175,7 @@ public class ANQPRequestManagerTest { when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); when(mClock.getElapsedSinceBootMillis()) .thenReturn(startTime + ANQPRequestManager.BASE_HOLDOFF_TIME_MILLISECONDS); - assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); } /** @@ -190,13 +190,13 @@ public class ANQPRequestManagerTest { long startTime = 0; when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(false); when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime); - assertFalse(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + assertFalse(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); reset(mHandler); // Verify that new request is not being held off after previous send failure. when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime); - assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); } /** @@ -211,15 +211,16 @@ public class ANQPRequestManagerTest { long startTime = 0; when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime); - assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); reset(mHandler); - // Request completed with success. - mManager.onRequestCompleted(TEST_BSSID, true); + // Request completed with success. Verify that the key associated with the request + // is returned. + assertEquals(TEST_ANQP_KEY, mManager.onRequestCompleted(TEST_BSSID, true)); when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime + 1); - assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); } /** @@ -235,22 +236,23 @@ public class ANQPRequestManagerTest { long startTime = 0; when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime); - assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); reset(mHandler); - // Request completed with failure. - mManager.onRequestCompleted(TEST_BSSID, false); + // Request completed with failure. Verify that the key associated with the request + // is returned + assertEquals(TEST_ANQP_KEY, mManager.onRequestCompleted(TEST_BSSID, false)); // Attempt another request will fail since the hold off time is not up yet. when(mClock.getElapsedSinceBootMillis()).thenReturn(startTime + 1); - assertFalse(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + assertFalse(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); verify(mHandler, never()).requestANQP(anyLong(), anyObject()); // Attempt another request will succeed after the hold off time is up. when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); when(mClock.getElapsedSinceBootMillis()) .thenReturn(startTime + ANQPRequestManager.BASE_HOLDOFF_TIME_MILLISECONDS); - assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); } /** @@ -266,7 +268,7 @@ public class ANQPRequestManagerTest { // Initial request. when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTime); - assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); reset(mHandler); // Sending the request with the hold off time based on the current hold off count. @@ -276,14 +278,14 @@ public class ANQPRequestManagerTest { // Request will fail before the hold off time is up. when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTime); - assertFalse(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + assertFalse(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); verify(mHandler, never()).requestANQP(anyLong(), anyObject()); // Request will succeed when the hold off time is up. currentTime += 1; when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTime); - assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); reset(mHandler); } @@ -292,13 +294,13 @@ public class ANQPRequestManagerTest { * (1 << ANQPRequestManager.MAX_HOLDOFF_COUNT) - 1); when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTime); - assertFalse(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + assertFalse(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); verify(mHandler, never()).requestANQP(anyLong(), anyObject()); currentTime += 1; when(mHandler.requestANQP(TEST_BSSID, R1_ANQP_WITHOUT_RC)).thenReturn(true); when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTime); - assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_SCAN_DETAIL, false, false)); + assertTrue(mManager.requestANQPElements(TEST_BSSID, TEST_ANQP_KEY, false, false)); reset(mHandler); } } 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 e424b4dbe..bdaf733c1 100644 --- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java @@ -28,6 +28,7 @@ import static android.net.wifi.WifiManager.EXTRA_URL; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; @@ -45,6 +46,7 @@ import android.content.Context; import android.content.Intent; import android.net.wifi.EAPConstants; import android.net.wifi.IconInfo; +import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiEnterpriseConfig; import android.net.wifi.hotspot2.PasspointConfiguration; @@ -59,7 +61,6 @@ import com.android.server.wifi.Clock; import com.android.server.wifi.FakeKeys; import com.android.server.wifi.IMSIParameter; import com.android.server.wifi.SIMAccessor; -import com.android.server.wifi.ScanDetail; import com.android.server.wifi.WifiConfigManager; import com.android.server.wifi.WifiConfigStore; import com.android.server.wifi.WifiKeyStore; @@ -67,6 +68,7 @@ import com.android.server.wifi.WifiNative; import com.android.server.wifi.hotspot2.anqp.ANQPElement; import com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType; import com.android.server.wifi.hotspot2.anqp.DomainNameElement; +import com.android.server.wifi.util.ScanResultUtil; import org.junit.Before; import org.junit.Test; @@ -94,9 +96,12 @@ public class PasspointManagerTest { private static final IMSIParameter TEST_IMSI_PARAM = IMSIParameter.build(TEST_IMSI); private static final String TEST_SSID = "TestSSID"; - private static final long TEST_BSSID = 0x1234L; + private static final long TEST_BSSID = 0x112233445566L; + private static final String TEST_BSSID_STRING = "11:22:33:44:55:66"; private static final long TEST_HESSID = 0x5678L; - private static final int TEST_ANQP_DOMAIN_ID = 1; + private static final int TEST_ANQP_DOMAIN_ID = 0; + private static final ANQPNetworkKey TEST_ANQP_KEY = ANQPNetworkKey.buildKey( + TEST_SSID, TEST_BSSID, TEST_HESSID, TEST_ANQP_DOMAIN_ID); @Mock Context mContext; @Mock WifiNative mWifiNative; @@ -239,20 +244,16 @@ public class PasspointManagerTest { } /** - * Helper function for creating a mock ScanDetail. + * Helper function for creating a ScanResult for testing. * - * @return {@link ScanDetail} + * @return {@link ScanResult} */ - private ScanDetail createMockScanDetail() { - NetworkDetail networkDetail = mock(NetworkDetail.class); - when(networkDetail.getSSID()).thenReturn(TEST_SSID); - when(networkDetail.getBSSID()).thenReturn(TEST_BSSID); - when(networkDetail.getHESSID()).thenReturn(TEST_HESSID); - when(networkDetail.getAnqpDomainID()).thenReturn(TEST_ANQP_DOMAIN_ID); - - ScanDetail scanDetail = mock(ScanDetail.class); - when(scanDetail.getNetworkDetail()).thenReturn(networkDetail); - return scanDetail; + private ScanResult createTestScanResult() { + ScanResult scanResult = new ScanResult(); + scanResult.SSID = TEST_SSID; + scanResult.BSSID = TEST_BSSID_STRING; + scanResult.hessid = TEST_HESSID; + return scanResult; } /** @@ -267,13 +268,9 @@ public class PasspointManagerTest { anqpElementMap.put(ANQPElementType.ANQPDomName, new DomainNameElement(Arrays.asList(new String[] {"test.com"}))); - ScanDetail scanDetail = createMockScanDetail(); - ANQPNetworkKey anqpKey = ANQPNetworkKey.buildKey(TEST_SSID, TEST_BSSID, TEST_HESSID, - TEST_ANQP_DOMAIN_ID); - when(mAnqpRequestManager.onRequestCompleted(TEST_BSSID, true)).thenReturn(scanDetail); + when(mAnqpRequestManager.onRequestCompleted(TEST_BSSID, true)).thenReturn(TEST_ANQP_KEY); mCallbacks.onANQPResponse(TEST_BSSID, anqpElementMap); - verify(mAnqpCache).addEntry(anqpKey, anqpElementMap); - verify(scanDetail).propagateANQPInfo(anqpElementMap); + verify(mAnqpCache).addEntry(TEST_ANQP_KEY, anqpElementMap); } /** @@ -300,11 +297,7 @@ public class PasspointManagerTest { */ @Test public void anqpResponseFailure() throws Exception { - ANQPNetworkKey anqpKey = ANQPNetworkKey.buildKey(TEST_SSID, TEST_BSSID, TEST_HESSID, - TEST_ANQP_DOMAIN_ID); - - ScanDetail scanDetail = createMockScanDetail(); - when(mAnqpRequestManager.onRequestCompleted(TEST_BSSID, false)).thenReturn(scanDetail); + when(mAnqpRequestManager.onRequestCompleted(TEST_BSSID, false)).thenReturn(TEST_ANQP_KEY); mCallbacks.onANQPResponse(TEST_BSSID, null); verify(mAnqpCache, never()).addEntry(any(ANQPNetworkKey.class), anyMap()); @@ -561,19 +554,17 @@ public class PasspointManagerTest { } /** - * Verify that an empty list will be returned when no providers are installed. + * Verify that a {code null} will be returned when no providers are installed. * * @throws Exception */ @Test public void matchProviderWithNoProvidersInstalled() throws Exception { - List<Pair<PasspointProvider, PasspointMatch>> result = - mManager.matchProvider(createMockScanDetail()); - assertTrue(result.isEmpty()); + assertNull(mManager.matchProvider(createTestScanResult())); } /** - * Verify that an empty list will be returned when ANQP entry doesn't exist in the cache. + * Verify that a {code null} be returned when ANQP entry doesn't exist in the cache. * * @throws Exception */ @@ -581,20 +572,15 @@ public class PasspointManagerTest { public void matchProviderWithAnqpCacheMissed() throws Exception { addTestProvider(); - ANQPNetworkKey anqpKey = ANQPNetworkKey.buildKey(TEST_SSID, TEST_BSSID, TEST_HESSID, - TEST_ANQP_DOMAIN_ID); - when(mAnqpCache.getEntry(anqpKey)).thenReturn(null); - List<Pair<PasspointProvider, PasspointMatch>> result = - mManager.matchProvider(createMockScanDetail()); + when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(null); + assertNull(mManager.matchProvider(createTestScanResult())); // Verify that a request for ANQP elements is initiated. - verify(mAnqpRequestManager).requestANQPElements(eq(TEST_BSSID), any(ScanDetail.class), + verify(mAnqpRequestManager).requestANQPElements(eq(TEST_BSSID), any(ANQPNetworkKey.class), anyBoolean(), anyBoolean()); - assertTrue(result.isEmpty()); } /** - * Verify that the returned list will contained an expected provider when a HomeProvider - * is matched. + * Verify that the expected provider will be returned when a HomeProvider is matched. * * @throws Exception */ @@ -602,20 +588,17 @@ public class PasspointManagerTest { public void matchProviderAsHomeProvider() throws Exception { PasspointProvider provider = addTestProvider(); ANQPData entry = new ANQPData(mClock, null); - ANQPNetworkKey anqpKey = ANQPNetworkKey.buildKey(TEST_SSID, TEST_BSSID, TEST_HESSID, - TEST_ANQP_DOMAIN_ID); - when(mAnqpCache.getEntry(anqpKey)).thenReturn(entry); + when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); when(provider.match(anyMap())).thenReturn(PasspointMatch.HomeProvider); - List<Pair<PasspointProvider, PasspointMatch>> result = - mManager.matchProvider(createMockScanDetail()); - assertEquals(1, result.size()); - assertEquals(PasspointMatch.HomeProvider, result.get(0).second); + Pair<PasspointProvider, PasspointMatch> result = + mManager.matchProvider(createTestScanResult()); + assertEquals(PasspointMatch.HomeProvider, result.second); + assertEquals(TEST_FQDN, result.first.getConfig().getHomeSp().getFqdn()); } /** - * Verify that the returned list will contained an expected provider when a RoamingProvider - * is matched. + * Verify that the expected provider will be returned when a RoamingProvider is matched. * * @throws Exception */ @@ -623,20 +606,17 @@ public class PasspointManagerTest { public void matchProviderAsRoamingProvider() throws Exception { PasspointProvider provider = addTestProvider(); ANQPData entry = new ANQPData(mClock, null); - ANQPNetworkKey anqpKey = ANQPNetworkKey.buildKey(TEST_SSID, TEST_BSSID, TEST_HESSID, - TEST_ANQP_DOMAIN_ID); - when(mAnqpCache.getEntry(anqpKey)).thenReturn(entry); + when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); when(provider.match(anyMap())).thenReturn(PasspointMatch.RoamingProvider); - List<Pair<PasspointProvider, PasspointMatch>> result = - mManager.matchProvider(createMockScanDetail()); - assertEquals(1, result.size()); - assertEquals(PasspointMatch.RoamingProvider, result.get(0).second); - assertEquals(TEST_FQDN, provider.getConfig().getHomeSp().getFqdn()); + Pair<PasspointProvider, PasspointMatch> result = + mManager.matchProvider(createTestScanResult()); + assertEquals(PasspointMatch.RoamingProvider, result.second); + assertEquals(TEST_FQDN, result.first.getConfig().getHomeSp().getFqdn()); } /** - * Verify that an empty list will be returned when there is no matching provider. + * Verify that a {code null} will be returned when there is no matching provider. * * @throws Exception */ @@ -644,14 +624,10 @@ public class PasspointManagerTest { public void matchProviderWithNoMatch() throws Exception { PasspointProvider provider = addTestProvider(); ANQPData entry = new ANQPData(mClock, null); - ANQPNetworkKey anqpKey = ANQPNetworkKey.buildKey(TEST_SSID, TEST_BSSID, TEST_HESSID, - TEST_ANQP_DOMAIN_ID); - when(mAnqpCache.getEntry(anqpKey)).thenReturn(entry); + when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); when(provider.match(anyMap())).thenReturn(PasspointMatch.None); - List<Pair<PasspointProvider, PasspointMatch>> result = - mManager.matchProvider(createMockScanDetail()); - assertEquals(0, result.size()); + assertNull(mManager.matchProvider(createTestScanResult())); } /** @@ -666,6 +642,98 @@ public class PasspointManagerTest { } /** + * Verify that an empty map will be returned if ANQP elements are not cached for the given AP. + * + * @throws Exception + */ + @Test + public void getANQPElementsWithNoMatchFound() throws Exception { + when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(null); + assertTrue(mManager.getANQPElements(createTestScanResult()).isEmpty()); + } + + /** + * Verify that an expected ANQP elements will be returned if ANQP elements are cached for the + * given AP. + * + * @throws Exception + */ + @Test + public void getANQPElementsWithMatchFound() throws Exception { + Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); + anqpElementMap.put(ANQPElementType.ANQPDomName, + new DomainNameElement(Arrays.asList(new String[] {"test.com"}))); + ANQPData entry = new ANQPData(mClock, anqpElementMap); + + when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); + assertEquals(anqpElementMap, mManager.getANQPElements(createTestScanResult())); + } + + /** + * Verify that an expected {@link WifiConfiguration} will be returned when a {@link ScanResult} + * is matched to a home provider. + * + * @throws Exception + */ + @Test + public void getMatchingWifiConfigForHomeProviderAP() throws Exception { + PasspointProvider provider = addTestProvider(); + ANQPData entry = new ANQPData(mClock, null); + + when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); + when(provider.match(anyMap())).thenReturn(PasspointMatch.HomeProvider); + when(provider.getWifiConfig()).thenReturn(new WifiConfiguration()); + WifiConfiguration config = mManager.getMatchingWifiConfig(createTestScanResult()); + assertEquals(ScanResultUtil.createQuotedSSID(TEST_SSID), config.SSID); + } + + /** + * Verify that an expected {@link WifiConfiguration} will be returned when a {@link ScanResult} + * is matched to a roaming provider. + * + * @throws Exception + */ + @Test + public void getMatchingWifiConfigForRoamingProviderAP() throws Exception { + PasspointProvider provider = addTestProvider(); + ANQPData entry = new ANQPData(mClock, null); + + when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); + when(provider.match(anyMap())).thenReturn(PasspointMatch.RoamingProvider); + when(provider.getWifiConfig()).thenReturn(new WifiConfiguration()); + WifiConfiguration config = mManager.getMatchingWifiConfig(createTestScanResult()); + assertEquals(ScanResultUtil.createQuotedSSID(TEST_SSID), config.SSID); + } + + /** + * Verify that a {code null} will be returned when a {@link ScanResult} doesn't match any + * provider. + * + * @throws Exception + */ + @Test + public void getMatchingWifiConfigWithNoMatchingProvider() throws Exception { + PasspointProvider provider = addTestProvider(); + ANQPData entry = new ANQPData(mClock, null); + + when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry); + when(provider.match(anyMap())).thenReturn(PasspointMatch.None); + assertNull(mManager.getMatchingWifiConfig(createTestScanResult())); + verify(provider, never()).getWifiConfig(); + } + + /** + * Verify that a {@code null} will returned when trying to get a matching + * {@link WifiConfiguration} a {@code null} {@link ScanResult}. + * + * @throws Exception + */ + @Test + public void getMatchingWifiConfigWithNullScanResult() throws Exception { + assertNull(mManager.getMatchingWifiConfig(null)); + } + + /** * Verify that the provider list maintained by the PasspointManager after the list is updated * in the data source. * diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkEvaluatorTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkEvaluatorTest.java index 616e2161a..c4527adc4 100644 --- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkEvaluatorTest.java +++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkEvaluatorTest.java @@ -128,8 +128,7 @@ public class PasspointNetworkEvaluatorTest { List<ScanDetail> scanDetails = Arrays.asList(new ScanDetail[] { generateScanDetail(TEST_SSID1), generateScanDetail(TEST_SSID2)}); List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>(); - List<Pair<PasspointProvider, PasspointMatch>> matchedProviders = new ArrayList<>(); - when(mPasspointManager.matchProvider(any(ScanDetail.class))).thenReturn(matchedProviders); + when(mPasspointManager.matchProvider(any(ScanResult.class))).thenReturn(null); assertEquals(null, mEvaluator.evaluateNetworks( scanDetails, null, null, false, false, connectableNetworks)); assertTrue(connectableNetworks.isEmpty()); @@ -154,35 +153,30 @@ public class PasspointNetworkEvaluatorTest { scanDetails, null, null, false, false, connectableNetworks)); assertTrue(connectableNetworks.isEmpty()); // Verify that no provider matching is performed. - verify(mPasspointManager, never()).matchProvider(any(ScanDetail.class)); + verify(mPasspointManager, never()).matchProvider(any(ScanResult.class)); } /** - * Verify that when both home provider and roaming provider is found for the same network, - * home provider is preferred. + * Verify that when a network matches a home provider is found, the correct network + * information (WifiConfiguration) is setup and returned. * * @throws Exception */ @Test - public void evaluateScansWithNetworkMatchingHomeAndRoamingProvider() throws Exception { + public void evaluateScansWithNetworkMatchingHomeProvider() throws Exception { List<ScanDetail> scanDetails = Arrays.asList(new ScanDetail[] { generateScanDetail(TEST_SSID1), generateScanDetail(TEST_SSID2)}); // Setup matching providers for ScanDetail with TEST_SSID1. Pair<PasspointProvider, PasspointMatch> homeProvider = Pair.create( TEST_PROVIDER1, PasspointMatch.HomeProvider); - Pair<PasspointProvider, PasspointMatch> roamingProvider = Pair.create( - TEST_PROVIDER2, PasspointMatch.RoamingProvider); - List<Pair<PasspointProvider, PasspointMatch>> matchedProviders = new ArrayList<>(); - matchedProviders.add(homeProvider); - matchedProviders.add(roamingProvider); List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>(); - // Return matchedProviders for the first ScanDetail (TEST_SSID1) and an empty list for + // Return homeProvider for the first ScanDetail (TEST_SSID1) and a null (no match) for // for the second (TEST_SSID2); - when(mPasspointManager.matchProvider(any(ScanDetail.class))).thenReturn(matchedProviders) - .thenReturn(new ArrayList<Pair<PasspointProvider, PasspointMatch>>()); + when(mPasspointManager.matchProvider(any(ScanResult.class))).thenReturn(homeProvider) + .thenReturn(null); when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt())) .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID)); when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(TEST_CONFIG1); @@ -217,15 +211,13 @@ public class PasspointNetworkEvaluatorTest { // Setup matching providers for ScanDetail with TEST_SSID1. Pair<PasspointProvider, PasspointMatch> roamingProvider = Pair.create( TEST_PROVIDER1, PasspointMatch.RoamingProvider); - List<Pair<PasspointProvider, PasspointMatch>> matchedProviders = new ArrayList<>(); - matchedProviders.add(roamingProvider); List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>(); - // Return matchedProviders for the first ScanDetail (TEST_SSID1) and an empty list for + // Return roamingProvider for the first ScanDetail (TEST_SSID1) and a null (no match) for // for the second (TEST_SSID2); - when(mPasspointManager.matchProvider(any(ScanDetail.class))).thenReturn(matchedProviders) - .thenReturn(new ArrayList<Pair<PasspointProvider, PasspointMatch>>()); + when(mPasspointManager.matchProvider(any(ScanResult.class))).thenReturn(roamingProvider) + .thenReturn(null); when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt())) .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID)); when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(TEST_CONFIG1); @@ -262,17 +254,13 @@ public class PasspointNetworkEvaluatorTest { TEST_PROVIDER1, PasspointMatch.HomeProvider); Pair<PasspointProvider, PasspointMatch> roamingProvider = Pair.create( TEST_PROVIDER2, PasspointMatch.RoamingProvider); - List<Pair<PasspointProvider, PasspointMatch>> providerForScanDetail1 = new ArrayList<>(); - providerForScanDetail1.add(homeProvider); - List<Pair<PasspointProvider, PasspointMatch>> providerForScanDetail2 = new ArrayList<>(); - providerForScanDetail2.add(roamingProvider); List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>(); - // Return providerForScanDetail1 for the first ScanDetail (TEST_SSID1) and - // providerForScanDetail2 for the second (TEST_SSID2); - when(mPasspointManager.matchProvider(any(ScanDetail.class))) - .thenReturn(providerForScanDetail1).thenReturn(providerForScanDetail2); + // Return homeProvider for the first ScanDetail (TEST_SSID1) and + // roamingProvider for the second (TEST_SSID2); + when(mPasspointManager.matchProvider(any(ScanResult.class))) + .thenReturn(homeProvider).thenReturn(roamingProvider); when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt())) .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID)); when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(TEST_CONFIG1); @@ -307,8 +295,6 @@ public class PasspointNetworkEvaluatorTest { // Setup matching providers for both ScanDetail. Pair<PasspointProvider, PasspointMatch> homeProvider = Pair.create( TEST_PROVIDER1, PasspointMatch.HomeProvider); - List<Pair<PasspointProvider, PasspointMatch>> matchedProviders = new ArrayList<>(); - matchedProviders.add(homeProvider); // Setup currently connected network WifiConfiguration currentNetwork = new WifiConfiguration(); @@ -318,8 +304,8 @@ public class PasspointNetworkEvaluatorTest { // Returning the same matching provider for both ScanDetail. List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>(); - when(mPasspointManager.matchProvider(any(ScanDetail.class))) - .thenReturn(matchedProviders).thenReturn(matchedProviders); + when(mPasspointManager.matchProvider(any(ScanResult.class))) + .thenReturn(homeProvider).thenReturn(homeProvider); WifiConfiguration config = mEvaluator.evaluateNetworks(scanDetails, currentNetwork, currentBssid, true, false, connectableNetworks); assertEquals(1, connectableNetworks.size()); diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkScoreTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkScoreTest.java index cca321233..10c50f5d3 100644 --- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkScoreTest.java +++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkScoreTest.java @@ -309,11 +309,10 @@ public class PasspointNetworkScoreTest { * @param rssiLevel RSSI level of the network * @param internetAccess Flag indicating if the network provides Internet access * @param networkType The type of the network - * @param anqpElements The list of ANQP elements * @return {@link ScanDetail} */ private static ScanDetail generateScanDetail(int rssiLevel, boolean internetAccess, - NetworkDetail.Ant networkType, Map<ANQPElementType, ANQPElement> anqpElements) { + NetworkDetail.Ant networkType) { // Setup ScanResult. ScanResult scanResult = new ScanResult(); scanResult.level = -60; @@ -322,7 +321,6 @@ public class PasspointNetworkScoreTest { NetworkDetail networkDetail = mock(NetworkDetail.class); when(networkDetail.isInternet()).thenReturn(internetAccess); when(networkDetail.getAnt()).thenReturn(networkType); - when(networkDetail.getANQPElements()).thenReturn(anqpElements); // Setup ScanDetail. ScanDetail scanDetail = mock(ScanDetail.class); @@ -341,9 +339,9 @@ public class PasspointNetworkScoreTest { public void calculateScore() throws Exception { for (TestData data : TEST_DATA_LIST) { ScanDetail scanDetail = generateScanDetail(data.rssiLevel, data.internetAccess, - data.networkType, data.anqpElements); + data.networkType); assertEquals(data.expectedScore, PasspointNetworkScore.calculateScore( - data.isHomeProvider, scanDetail, data.isActiveNetwork)); + data.isHomeProvider, scanDetail, data.anqpElements, data.isActiveNetwork)); } } diff --git a/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java b/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java index fdb26e489..d61809882 100644 --- a/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java +++ b/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java @@ -396,6 +396,22 @@ public class XmlUtilTest { deserializeWifiEnterpriseConfig(xmlString.getBytes(StandardCharsets.UTF_8)); } + /** + * Verify that WifiConfiguration representation of a legacy Passpoint configuration is + * serialized & deserialized correctly. + * + *@throws Exception + */ + @Test + public void testLegacyPasspointConfigSerializeDeserialize() throws Exception { + WifiConfiguration config = WifiConfigurationTestUtil.createPasspointNetwork(); + config.isLegacyPasspointConfig = true; + config.roamingConsortiumIds = new long[] {0x12345678}; + config.enterpriseConfig.setPlmn("1234"); + config.enterpriseConfig.setRealm("test.com"); + serializeDeserializeWifiConfigurationForConfigStore(config); + } + private byte[] serializeWifiConfigurationForBackup(WifiConfiguration configuration) throws IOException, XmlPullParserException { final XmlSerializer out = new FastXmlSerializer(); |