diff options
4 files changed, 414 insertions, 108 deletions
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java index b0bdf1dd8594..328bfb281992 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java @@ -188,6 +188,8 @@ public class AccessPoint implements Comparable<AccessPoint> { static final String KEY_SUBSCRIPTION_EXPIRATION_TIME_IN_MILLIS = "key_subscription_expiration_time_in_millis"; static final String KEY_PASSPOINT_CONFIGURATION_VERSION = "key_passpoint_configuration_version"; + static final String KEY_IS_PSK_SAE_TRANSITION_MODE = "key_is_psk_sae_transition_mode"; + static final String KEY_IS_OWE_TRANSITION_MODE = "key_is_owe_transition_mode"; static final AtomicInteger sLastId = new AtomicInteger(0); /* @@ -202,15 +204,12 @@ public class AccessPoint implements Comparable<AccessPoint> { public static final int SECURITY_OWE = 4; public static final int SECURITY_SAE = 5; public static final int SECURITY_EAP_SUITE_B = 6; - public static final int SECURITY_PSK_SAE_TRANSITION = 7; - public static final int SECURITY_OWE_TRANSITION = 8; - public static final int SECURITY_MAX_VAL = 9; // Has to be the last + public static final int SECURITY_MAX_VAL = 7; // Has to be the last private static final int PSK_UNKNOWN = 0; private static final int PSK_WPA = 1; private static final int PSK_WPA2 = 2; private static final int PSK_WPA_WPA2 = 3; - private static final int PSK_SAE = 4; private static final int EAP_UNKNOWN = 0; private static final int EAP_WPA = 1; // WPA-EAP @@ -274,6 +273,9 @@ public class AccessPoint implements Comparable<AccessPoint> { private String mOsuFailure; private boolean mOsuProvisioningComplete = false; + private boolean mIsPskSaeTransitionMode = false; + private boolean mIsOweTransitionMode = false; + /** * The EAP type {@link WifiEnterpriseConfig.Eap} associated with this AP if it is a carrier AP. */ @@ -344,6 +346,13 @@ public class AccessPoint implements Comparable<AccessPoint> { if (savedState.containsKey(KEY_PASSPOINT_CONFIGURATION_VERSION)) { mPasspointConfigurationVersion = savedState.getInt(KEY_PASSPOINT_CONFIGURATION_VERSION); } + if (savedState.containsKey(KEY_IS_PSK_SAE_TRANSITION_MODE)) { + mIsPskSaeTransitionMode = savedState.getBoolean(KEY_IS_PSK_SAE_TRANSITION_MODE); + } + if (savedState.containsKey(KEY_IS_OWE_TRANSITION_MODE)) { + mIsOweTransitionMode = savedState.getBoolean(KEY_IS_OWE_TRANSITION_MODE); + } + update(mConfig, mInfo, mNetworkInfo); // Calculate required fields @@ -675,8 +684,15 @@ public class AccessPoint implements Comparable<AccessPoint> { return oldMetering == mIsScoredNetworkMetered; } - public static String getKey(ScanResult result) { - return getKey(result.SSID, result.BSSID, getSecurity(result)); + /** + * Generates an AccessPoint key for a given scan result + * + * @param context + * @param result Scan result + * @return AccessPoint key + */ + public static String getKey(Context context, ScanResult result) { + return getKey(result.SSID, result.BSSID, getSecurity(context, result)); } /** @@ -734,7 +750,42 @@ public class AccessPoint implements Comparable<AccessPoint> { * Determines if the other AccessPoint represents the same network as this AccessPoint */ public boolean matches(AccessPoint other) { - return getKey().equals(other.getKey()); + if (isPasspoint() || isPasspointConfig() || isOsuProvider()) { + return getKey().equals(other.getKey()); + } + + if (!isSameSsidOrBssid(other)) { + return false; + } + + final int otherApSecurity = other.getSecurity(); + if (mIsPskSaeTransitionMode) { + if (otherApSecurity == SECURITY_SAE && getWifiManager().isWpa3SaeSupported()) { + return true; + } else if (otherApSecurity == SECURITY_PSK) { + return true; + } + } else { + if ((security == SECURITY_SAE || security == SECURITY_PSK) + && other.isPskSaeTransitionMode()) { + return true; + } + } + + if (mIsOweTransitionMode) { + if (otherApSecurity == SECURITY_OWE && getWifiManager().isEnhancedOpenSupported()) { + return true; + } else if (otherApSecurity == SECURITY_NONE) { + return true; + } + } else { + if ((security == SECURITY_OWE || security == SECURITY_NONE) + && other.isOweTransitionMode()) { + return true; + } + } + + return security == other.getSecurity(); } public boolean matches(WifiConfiguration config) { @@ -748,18 +799,77 @@ public class AccessPoint implements Comparable<AccessPoint> { } final int configSecurity = getSecurity(config); - final WifiManager wifiManager = getWifiManager(); - switch (security) { - case SECURITY_PSK_SAE_TRANSITION: - return configSecurity == SECURITY_PSK - || (wifiManager.isWpa3SaeSupported() && configSecurity == SECURITY_SAE); - case SECURITY_OWE_TRANSITION: - return configSecurity == SECURITY_NONE - || (wifiManager.isEnhancedOpenSupported() - && configSecurity == SECURITY_OWE); - default: - return security == configSecurity; + if (mIsPskSaeTransitionMode) { + if (configSecurity == SECURITY_SAE && getWifiManager().isWpa3SaeSupported()) { + return true; + } else if (configSecurity == SECURITY_PSK) { + return true; + } + } + + if (mIsOweTransitionMode) { + if (configSecurity == SECURITY_OWE && getWifiManager().isEnhancedOpenSupported()) { + return true; + } else if (configSecurity == SECURITY_NONE) { + return true; + } } + + return security == getSecurity(config); + } + + private boolean matches(WifiConfiguration config, WifiInfo wifiInfo) { + if (config == null || wifiInfo == null) { + return false; + } + if (!config.isPasspoint() && !isSameSsidOrBssid(wifiInfo)) { + return false; + } + return matches(config); + } + + @VisibleForTesting + boolean matches(ScanResult scanResult) { + if (scanResult == null) { + return false; + } + if (isPasspoint() || isOsuProvider()) { + throw new IllegalStateException("Should not matches a Passpoint by ScanResult"); + } + + if (!isSameSsidOrBssid(scanResult)) { + return false; + } + + if (mIsPskSaeTransitionMode) { + if (scanResult.capabilities.contains("SAE") + && getWifiManager().isWpa3SaeSupported()) { + return true; + } else if (scanResult.capabilities.contains("PSK")) { + return true; + } + } else { + if ((security == SECURITY_SAE || security == SECURITY_PSK) + && AccessPoint.isPskSaeTransitionMode(scanResult)) { + return true; + } + } + + if (mIsOweTransitionMode) { + final int scanResultSccurity = getSecurity(mContext, scanResult); + if (scanResultSccurity == SECURITY_OWE && getWifiManager().isEnhancedOpenSupported()) { + return true; + } else if (scanResultSccurity == SECURITY_NONE) { + return true; + } + } else { + if ((security == SECURITY_OWE || security == SECURITY_NONE) + && AccessPoint.isOweTransitionMode(scanResult)) { + return true; + } + } + + return security == getSecurity(mContext, scanResult); } public WifiConfiguration getConfig() { @@ -846,14 +956,17 @@ public class AccessPoint implements Comparable<AccessPoint> { if (bestResult != null) { ssid = bestResult.SSID; bssid = bestResult.BSSID; - security = getSecurity(bestResult); - if (security == SECURITY_PSK || security == SECURITY_SAE - || security == SECURITY_PSK_SAE_TRANSITION) { + security = getSecurity(mContext, bestResult); + if (security == SECURITY_PSK || security == SECURITY_SAE) { pskType = getPskType(bestResult); } if (security == SECURITY_EAP) { mEapType = getEapType(bestResult); } + + mIsPskSaeTransitionMode = AccessPoint.isPskSaeTransitionMode(bestResult); + mIsOweTransitionMode = AccessPoint.isOweTransitionMode(bestResult); + mIsCarrierAp = bestResult.isCarrierAp; mCarrierApEapType = bestResult.carrierApEapType; mCarrierName = bestResult.carrierName; @@ -886,6 +999,12 @@ public class AccessPoint implements Comparable<AccessPoint> { return concise ? context.getString(R.string.wifi_security_short_eap) : context.getString(R.string.wifi_security_eap); } + + if (mIsPskSaeTransitionMode) { + return concise ? context.getString(R.string.wifi_security_short_psk_sae) : + context.getString(R.string.wifi_security_psk_sae); + } + switch(security) { case SECURITY_EAP: switch (mEapType) { @@ -925,20 +1044,8 @@ public class AccessPoint implements Comparable<AccessPoint> { return concise ? context.getString(R.string.wifi_security_short_wep) : context.getString(R.string.wifi_security_wep); case SECURITY_SAE: - case SECURITY_PSK_SAE_TRANSITION: - if (pskType == PSK_SAE) { - return concise ? context.getString(R.string.wifi_security_short_psk_sae) : - context.getString(R.string.wifi_security_psk_sae); - } else { - return concise ? context.getString(R.string.wifi_security_short_sae) : - context.getString(R.string.wifi_security_sae); - } - case SECURITY_OWE_TRANSITION: - if (mConfig != null && getSecurity(mConfig) == SECURITY_OWE) { - return concise ? context.getString(R.string.wifi_security_short_owe) : - context.getString(R.string.wifi_security_owe); - } - return concise ? "" : context.getString(R.string.wifi_security_none); + return concise ? context.getString(R.string.wifi_security_short_sae) : + context.getString(R.string.wifi_security_sae); case SECURITY_OWE: return concise ? context.getString(R.string.wifi_security_short_owe) : context.getString(R.string.wifi_security_owe); @@ -1250,7 +1357,7 @@ public class AccessPoint implements Comparable<AccessPoint> { if (networkId != WifiConfiguration.INVALID_NETWORK_ID) { return networkId == info.getNetworkId(); } else if (config != null) { - return isKeyEqual(getKey(config)); + return matches(config, info); } else { // Might be an ephemeral connection with no WifiConfiguration. Try matching on SSID. // (Note that we only do this if the WifiConfiguration explicitly equals INVALID). @@ -1322,43 +1429,14 @@ public class AccessPoint implements Comparable<AccessPoint> { savedState.putLong(KEY_SUBSCRIPTION_EXPIRATION_TIME_IN_MILLIS, mSubscriptionExpirationTimeInMillis); savedState.putInt(KEY_PASSPOINT_CONFIGURATION_VERSION, mPasspointConfigurationVersion); + savedState.putBoolean(KEY_IS_PSK_SAE_TRANSITION_MODE, mIsPskSaeTransitionMode); + savedState.putBoolean(KEY_IS_OWE_TRANSITION_MODE, mIsOweTransitionMode); } public void setListener(AccessPointListener listener) { mAccessPointListener = listener; } - private static final String sPskSuffix = "," + String.valueOf(SECURITY_PSK); - private static final String sSaeSuffix = "," + String.valueOf(SECURITY_SAE); - private static final String sPskSaeSuffix = "," + String.valueOf(SECURITY_PSK_SAE_TRANSITION); - private static final String sOweSuffix = "," + String.valueOf(SECURITY_OWE); - private static final String sOpenSuffix = "," + String.valueOf(SECURITY_NONE); - private static final String sOweTransSuffix = "," + String.valueOf(SECURITY_OWE_TRANSITION); - - private boolean isKeyEqual(String compareTo) { - if (mKey == null) { - return false; - } - - if (compareTo.endsWith(sPskSuffix) || compareTo.endsWith(sSaeSuffix)) { - if (mKey.endsWith(sPskSaeSuffix)) { - // Special handling for PSK-SAE transition mode. If the AP has advertised both, - // we compare the key with both PSK and SAE for a match. - return TextUtils.equals(mKey.substring(0, mKey.lastIndexOf(',')), - compareTo.substring(0, compareTo.lastIndexOf(','))); - } - } - if (compareTo.endsWith(sOpenSuffix) || compareTo.endsWith(sOweSuffix)) { - if (mKey.endsWith(sOweTransSuffix)) { - // Special handling for OWE/Open networks. If AP advertises OWE in transition mode - // and we have an Open network saved, allow this connection to be established. - return TextUtils.equals(mKey.substring(0, mKey.lastIndexOf(',')), - compareTo.substring(0, compareTo.lastIndexOf(','))); - } - } - return mKey.equals(compareTo); - } - /** * Sets {@link #mScanResults} to the given collection and updates info based on the best RSSI * scan result. @@ -1375,11 +1453,10 @@ public class AccessPoint implements Comparable<AccessPoint> { // Passpoint networks are not bound to a specific SSID/BSSID, so skip this for passpoint. if (mKey != null && !isPasspoint() && !isOsuProvider()) { for (ScanResult result : scanResults) { - String scanResultKey = AccessPoint.getKey(result); - if (!isKeyEqual(scanResultKey)) { + if (!matches(result)) { Log.d(TAG, String.format( - "ScanResult %s\nkey of %s did not match current AP key %s", - result, scanResultKey, mKey)); + "ScanResult %s\nkey of %s did not match current AP key %s", + result, getKey(mContext, result), mKey)); return; } } @@ -1653,11 +1730,8 @@ public class AccessPoint implements Comparable<AccessPoint> { private static int getPskType(ScanResult result) { boolean wpa = result.capabilities.contains("WPA-PSK"); boolean wpa2 = result.capabilities.contains("RSN-PSK"); - boolean wpa3TransitionMode = result.capabilities.contains("PSK+SAE"); boolean wpa3 = result.capabilities.contains("RSN-SAE"); - if (wpa3TransitionMode) { - return PSK_SAE; - } else if (wpa2 && wpa) { + if (wpa2 && wpa) { return PSK_WPA_WPA2; } else if (wpa2) { return PSK_WPA2; @@ -1684,22 +1758,37 @@ public class AccessPoint implements Comparable<AccessPoint> { return EAP_UNKNOWN; } - private static int getSecurity(ScanResult result) { - if (result.capabilities.contains("WEP")) { + private static int getSecurity(Context context, ScanResult result) { + final boolean isWep = result.capabilities.contains("WEP"); + final boolean isSae = result.capabilities.contains("SAE"); + final boolean isPsk = result.capabilities.contains("PSK"); + final boolean isEapSuiteB192 = result.capabilities.contains("EAP_SUITE_B_192"); + final boolean isEap = result.capabilities.contains("EAP"); + final boolean isOwe = result.capabilities.contains("OWE"); + final boolean isOweTransition = result.capabilities.contains("OWE_TRANSITION"); + + if (isSae && isPsk) { + final WifiManager wifiManager = (WifiManager) + context.getSystemService(Context.WIFI_SERVICE); + return wifiManager.isWpa3SaeSupported() ? SECURITY_SAE : SECURITY_PSK; + } + if (isOweTransition) { + final WifiManager wifiManager = (WifiManager) + context.getSystemService(Context.WIFI_SERVICE); + return wifiManager.isEnhancedOpenSupported() ? SECURITY_OWE : SECURITY_NONE; + } + + if (isWep) { return SECURITY_WEP; - } else if (result.capabilities.contains("PSK+SAE")) { - return SECURITY_PSK_SAE_TRANSITION; - } else if (result.capabilities.contains("SAE")) { + } else if (isSae) { return SECURITY_SAE; - } else if (result.capabilities.contains("PSK")) { + } else if (isPsk) { return SECURITY_PSK; - } else if (result.capabilities.contains("EAP_SUITE_B_192")) { + } else if (isEapSuiteB192) { return SECURITY_EAP_SUITE_B; - } else if (result.capabilities.contains("EAP")) { + } else if (isEap) { return SECURITY_EAP; - } else if (result.capabilities.contains("OWE_TRANSITION")) { - return SECURITY_OWE_TRANSITION; - } else if (result.capabilities.contains("OWE")) { + } else if (isOwe) { return SECURITY_OWE; } return SECURITY_NONE; @@ -1745,10 +1834,6 @@ public class AccessPoint implements Comparable<AccessPoint> { return "SUITE_B"; } else if (security == SECURITY_OWE) { return "OWE"; - } else if (security == SECURITY_PSK_SAE_TRANSITION) { - return "PSK+SAE"; - } else if (security == SECURITY_OWE_TRANSITION) { - return "OWE_TRANSITION"; } return "NONE"; } @@ -1776,8 +1861,7 @@ public class AccessPoint implements Comparable<AccessPoint> { * Return true if this is an open network AccessPoint. */ public boolean isOpenNetwork() { - return security == SECURITY_NONE || security == SECURITY_OWE - || security == SECURITY_OWE_TRANSITION; + return security == SECURITY_NONE || security == SECURITY_OWE; } /** @@ -1926,4 +2010,61 @@ public class AccessPoint implements Comparable<AccessPoint> { } } } + + public boolean isPskSaeTransitionMode() { + return mIsPskSaeTransitionMode; + } + + public boolean isOweTransitionMode() { + return mIsOweTransitionMode; + } + + private static boolean isPskSaeTransitionMode(ScanResult scanResult) { + return scanResult.capabilities.contains("PSK") + && scanResult.capabilities.contains("SAE"); + } + + private static boolean isOweTransitionMode(ScanResult scanResult) { + return scanResult.capabilities.contains("OWE_TRANSITION"); + } + + private boolean isSameSsidOrBssid(ScanResult scanResult) { + if (scanResult == null) { + return false; + } + + if (TextUtils.equals(ssid, scanResult.SSID)) { + return true; + } else if (scanResult.BSSID != null && TextUtils.equals(bssid, scanResult.BSSID)) { + return true; + } + return false; + } + + private boolean isSameSsidOrBssid(WifiInfo wifiInfo) { + if (wifiInfo == null) { + return false; + } + + if (TextUtils.equals(ssid, removeDoubleQuotes(wifiInfo.getSSID()))) { + return true; + } else if (wifiInfo.getBSSID() != null && TextUtils.equals(bssid, wifiInfo.getBSSID())) { + return true; + } + return false; + } + + private boolean isSameSsidOrBssid(AccessPoint accessPoint) { + if (accessPoint == null) { + return false; + } + + if (TextUtils.equals(ssid, accessPoint.getSsid())) { + return true; + } else if (accessPoint.getBssid() != null + && TextUtils.equals(bssid, accessPoint.getBssid())) { + return true; + } + return false; + } } diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java index dae546497aba..6269a717b333 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java @@ -201,8 +201,7 @@ public class AccessPointPreference extends Preference { return; } if ((mAccessPoint.getSecurity() != AccessPoint.SECURITY_NONE) - && (mAccessPoint.getSecurity() != AccessPoint.SECURITY_OWE) - && (mAccessPoint.getSecurity() != AccessPoint.SECURITY_OWE_TRANSITION)) { + && (mAccessPoint.getSecurity() != AccessPoint.SECURITY_OWE)) { mFrictionSld.setState(STATE_SECURED); } else if (mAccessPoint.isMetered()) { mFrictionSld.setState(STATE_METERED); diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java index 23b16e811606..ba6a8ea31987 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java @@ -70,8 +70,10 @@ import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Collectors; /** * Tracks saved or available wifi networks and their state. @@ -475,7 +477,7 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro continue; } - String apKey = AccessPoint.getKey(result); + String apKey = AccessPoint.getKey(mContext, result); List<ScanResult> resultList; if (scanResultsByApKey.containsKey(apKey)) { resultList = scanResultsByApKey.get(apKey); @@ -547,14 +549,6 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro private void updateAccessPoints(final List<ScanResult> newScanResults, List<WifiConfiguration> configs) { - // Map configs and scan results necessary to make AccessPoints - final Map<String, WifiConfiguration> configsByKey = new ArrayMap(configs.size()); - if (configs != null) { - for (WifiConfiguration config : configs) { - configsByKey.put(AccessPoint.getKey(config), config); - } - } - WifiConfiguration connectionConfig = null; if (mLastInfo != null) { connectionConfig = getWifiConfigurationForNetworkId(mLastInfo.getNetworkId(), configs); @@ -586,7 +580,26 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro getCachedOrCreate(entry.getValue(), cachedAccessPoints); // Update the matching config if there is one, to populate saved network info - accessPoint.update(configsByKey.get(entry.getKey())); + final List<WifiConfiguration> matchedConfigs = configs.stream() + .filter(config -> accessPoint.matches(config)) + .collect(Collectors.toList()); + + final int matchedConfigCount = matchedConfigs.size(); + if (matchedConfigCount == 0) { + accessPoint.update(null); + } else if (matchedConfigCount == 1) { + accessPoint.update(matchedConfigs.get(0)); + } else { + // We may have 2 matched configured WifiCongiguration if the AccessPoint is + // of PSK/SAE transition mode or open/OWE transition mode. + Optional<WifiConfiguration> preferredConfig = matchedConfigs.stream() + .filter(config -> isSaeOrOwe(config)).findFirst(); + if (preferredConfig.isPresent()) { + accessPoint.update(preferredConfig.get()); + } else { + accessPoint.update(matchedConfigs.get(0)); + } + } accessPoints.add(accessPoint); } @@ -652,6 +665,11 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro conditionallyNotifyListeners(); } + private static boolean isSaeOrOwe(WifiConfiguration config) { + final int security = AccessPoint.getSecurity(config); + return security == AccessPoint.SECURITY_SAE || security == AccessPoint.SECURITY_OWE; + } + @VisibleForTesting List<AccessPoint> updatePasspointAccessPoints( List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> passpointConfigsAndScans, @@ -700,7 +718,8 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro private AccessPoint getCachedOrCreate( List<ScanResult> scanResults, List<AccessPoint> cache) { - AccessPoint accessPoint = getCachedByKey(cache, AccessPoint.getKey(scanResults.get(0))); + AccessPoint accessPoint = getCachedByKey(cache, + AccessPoint.getKey(mContext, scanResults.get(0))); if (accessPoint == null) { accessPoint = new AccessPoint(mContext, scanResults); } else { diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java index 7b1c3825fcc6..325366ea6e40 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java @@ -39,6 +39,7 @@ import android.net.ScoredNetwork; import android.net.WifiKey; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiConfiguration.KeyMgmt; import android.net.wifi.WifiEnterpriseConfig; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; @@ -1273,7 +1274,7 @@ public class AccessPointTest { @Test public void testGetKey_matchesKeysCorrectly() { AccessPoint ap = new AccessPoint(mContext, mScanResults); - assertThat(ap.getKey()).isEqualTo(AccessPoint.getKey(mScanResults.get(0))); + assertThat(ap.getKey()).isEqualTo(AccessPoint.getKey(mContext, mScanResults.get(0))); WifiConfiguration spyConfig = spy(new WifiConfiguration()); when(spyConfig.isPasspoint()).thenReturn(true); @@ -1295,6 +1296,44 @@ public class AccessPointTest { } /** + * Test that getKey returns a key of SAE type for a PSK/SAE transition mode ScanResult. + */ + @Test + public void testGetKey_supportSaeTransitionMode_shouldGetSaeKey() { + ScanResult scanResult = createScanResult(TEST_SSID, TEST_BSSID, DEFAULT_RSSI); + scanResult.capabilities = + "[WPA2-FT/PSK-CCMP][RSN-FT/PSK+PSK-SHA256+SAE+FT/SAE-CCMP][ESS][WPS]"; + when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(true); + when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager); + StringBuilder key = new StringBuilder(); + key.append(AccessPoint.KEY_PREFIX_AP); + key.append(TEST_SSID); + key.append(','); + key.append(AccessPoint.SECURITY_SAE); + + assertThat(AccessPoint.getKey(mMockContext, scanResult)).isEqualTo(key.toString()); + } + + /** + * Test that getKey returns a key of PSK type for a PSK/SAE transition mode ScanResult. + */ + @Test + public void testGetKey_notSupportSaeTransitionMode_shouldGetPskKey() { + ScanResult scanResult = createScanResult(TEST_SSID, TEST_BSSID, DEFAULT_RSSI); + scanResult.capabilities = + "[WPA2-FT/PSK-CCMP][RSN-FT/PSK+PSK-SHA256+SAE+FT/SAE-CCMP][ESS][WPS]"; + when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(false); + when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager); + StringBuilder key = new StringBuilder(); + key.append(AccessPoint.KEY_PREFIX_AP); + key.append(TEST_SSID); + key.append(','); + key.append(AccessPoint.SECURITY_PSK); + + assertThat(AccessPoint.getKey(mMockContext, scanResult)).isEqualTo(key.toString()); + } + + /** * Verifies that the Passpoint AccessPoint constructor creates AccessPoints whose isPasspoint() * returns true. */ @@ -1537,12 +1576,120 @@ public class AccessPointTest { bundle.putInt("key_security", i); ap = new AccessPoint(InstrumentationRegistry.getTargetContext(), bundle); - if (i == AccessPoint.SECURITY_NONE || i == AccessPoint.SECURITY_OWE - || i == AccessPoint.SECURITY_OWE_TRANSITION) { + if (i == AccessPoint.SECURITY_NONE || i == AccessPoint.SECURITY_OWE) { assertThat(ap.isOpenNetwork()).isTrue(); } else { assertThat(ap.isOpenNetwork()).isFalse(); } } } + + /** + * Verifies that matches(AccessPoint other) matches a PSK/SAE transition mode AP to a PSK or a + * SAE AP. + */ + @Test + public void testMatches1_transitionModeApMatchesNotTransitionModeAp_shouldMatchCorrectly() { + when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager); + when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(true); + AccessPoint pskSaeTransitionModeAp = getPskSaeTransitionModeAp(); + + // Transition mode AP matches a SAE AP. + AccessPoint saeAccessPoint = new TestAccessPointBuilder(mContext) + .setSsid(AccessPoint.removeDoubleQuotes(TEST_SSID)) + .setSecurity(AccessPoint.SECURITY_SAE) + .build(); + assertThat(pskSaeTransitionModeAp.matches(saeAccessPoint)).isTrue(); + + // Transition mode AP matches a PSK AP. + AccessPoint pskAccessPoint = new TestAccessPointBuilder(mContext) + .setSsid(AccessPoint.removeDoubleQuotes(TEST_SSID)) + .setSecurity(AccessPoint.SECURITY_PSK) + .build(); + + assertThat(pskSaeTransitionModeAp.matches(pskAccessPoint)).isTrue(); + + // Transition mode AP does not match a SAE AP if the device does not support SAE. + when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(false); + pskSaeTransitionModeAp = getPskSaeTransitionModeAp(); + saeAccessPoint = new TestAccessPointBuilder(mContext) + .setSsid(AccessPoint.removeDoubleQuotes(TEST_SSID)) + .setSecurity(AccessPoint.SECURITY_SAE) + .build(); + + assertThat(pskSaeTransitionModeAp.matches(saeAccessPoint)).isFalse(); + } + + /** + * Verifies that matches(WifiConfiguration config) matches a PSK/SAE transition mode AP to a PSK + * or a SAE WifiConfiguration. + */ + @Test + public void testMatches2_transitionModeApMatchesNotTransitionModeAp_shouldMatchCorrectly() { + when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager); + when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(true); + AccessPoint pskSaeTransitionModeAp = getPskSaeTransitionModeAp(); + + // Transition mode AP matches a SAE WifiConfiguration. + WifiConfiguration saeConfig = new WifiConfiguration(); + saeConfig.SSID = TEST_SSID; + saeConfig.allowedKeyManagement.set(KeyMgmt.SAE); + + assertThat(pskSaeTransitionModeAp.matches(saeConfig)).isTrue(); + + // Transition mode AP matches a PSK WifiConfiguration. + WifiConfiguration pskConfig = new WifiConfiguration(); + pskConfig.SSID = TEST_SSID; + pskConfig.allowedKeyManagement.set(KeyMgmt.WPA_PSK); + + assertThat(pskSaeTransitionModeAp.matches(pskConfig)).isTrue(); + + // Transition mode AP does not matches a SAE WifiConfiguration if the device does not + // support SAE. + when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(false); + pskSaeTransitionModeAp = getPskSaeTransitionModeAp(); + + assertThat(pskSaeTransitionModeAp.matches(saeConfig)).isFalse(); + } + + /** + * Verifies that matches(ScanResult scanResult) matches a PSK/SAE transition mode AP to a PSK + * or a SAE ScanResult. + */ + @Test + public void testMatches3_transitionModeApMatchesNotTransitionModeAp_shouldMatchCorrectly() { + when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager); + when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(true); + AccessPoint pskSaeTransitionModeAp = getPskSaeTransitionModeAp(); + + // Transition mode AP matches a SAE ScanResult. + ScanResult saeScanResult = createScanResult(AccessPoint.removeDoubleQuotes(TEST_SSID), + TEST_BSSID, DEFAULT_RSSI); + saeScanResult.capabilities = "[SAE-CCMP][ESS][WPS]"; + + assertThat(pskSaeTransitionModeAp.matches(saeScanResult)).isTrue(); + + // Transition mode AP matches a PSK ScanResult. + ScanResult pskScanResult = createScanResult(AccessPoint.removeDoubleQuotes(TEST_SSID), + TEST_BSSID, DEFAULT_RSSI); + pskScanResult.capabilities = "[RSN-PSK-CCMP][ESS][WPS]"; + + assertThat(pskSaeTransitionModeAp.matches(pskScanResult)).isTrue(); + + // Transition mode AP does not matches a SAE ScanResult if the device does not support SAE. + when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(false); + pskSaeTransitionModeAp = getPskSaeTransitionModeAp(); + + assertThat(pskSaeTransitionModeAp.matches(saeScanResult)).isFalse(); + } + + private AccessPoint getPskSaeTransitionModeAp() { + ScanResult scanResult = createScanResult(AccessPoint.removeDoubleQuotes(TEST_SSID), + TEST_BSSID, DEFAULT_RSSI); + scanResult.capabilities = + "[WPA2-FT/PSK-CCMP][RSN-FT/PSK+PSK-SHA256+SAE+FT/SAE-CCMP][ESS][WPS]"; + return new TestAccessPointBuilder(mMockContext) + .setScanResults(new ArrayList<ScanResult>(Arrays.asList(scanResult))) + .build(); + } } |