From 34d9cd2cb8c8d29fcbcd119a4f4036a2afe082bf Mon Sep 17 00:00:00 2001 From: Quang Luong Date: Wed, 2 Oct 2019 16:26:57 -0700 Subject: Added WifiConfiguration to StandardWifiEntry StandardWifiEntries need to store a WifiConfiguration if it represents a saved network, and must be able to dynamically update or remove it if the configuration changes or the network is forgotten. StandardWifiEntries can also be represented with just a WifiConfiguration and no scan results, which is needed by the Saved Networks page. Test: atest WifiTrackerLibTests Bug: 70983952 Change-Id: Ia448c3fc009155ddecba198e84393c3122ecf61d --- .../android/wifitrackerlib/StandardWifiEntry.java | 77 +++++++++++++-- .../src/com/android/wifitrackerlib/Utils.java | 22 +++++ .../src/com/android/wifitrackerlib/WifiEntry.java | 19 ++++ .../wifitrackerlib/StandardWifiEntryTest.java | 109 +++++++++++++++++---- 4 files changed, 201 insertions(+), 26 deletions(-) (limited to 'libs') diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java index f4c4f05ed..af7df4d9c 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java @@ -16,15 +16,22 @@ package com.android.wifitrackerlib; +import static android.net.wifi.WifiInfo.removeDoubleQuotes; + +import static androidx.core.util.Preconditions.checkNotNull; + import static com.android.wifitrackerlib.Utils.getBestScanResultByLevel; import static com.android.wifitrackerlib.Utils.getSecurityFromScanResult; +import static com.android.wifitrackerlib.Utils.getSecurityFromWifiConfiguration; import android.net.wifi.ScanResult; +import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.Handler; import android.text.TextUtils; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; import java.util.ArrayList; @@ -40,9 +47,10 @@ class StandardWifiEntry extends WifiEntry { private final List mCurrentScanResults = new ArrayList<>(); - private final String mKey; - private final String mSsid; + @NonNull private final String mKey; + @NonNull private final String mSsid; private final @Security int mSecurity; + @Nullable private WifiConfiguration mWifiConfig; private int mLevel = WIFI_LEVEL_UNREACHABLE; @@ -50,6 +58,7 @@ class StandardWifiEntry extends WifiEntry { throws IllegalArgumentException { super(callbackHandler); + checkNotNull(scanResults, "Cannot construct with null ScanResult list!"); if (scanResults.isEmpty()) { throw new IllegalArgumentException("Cannot construct with empty ScanResult list!"); } @@ -60,6 +69,19 @@ class StandardWifiEntry extends WifiEntry { updateScanResultInfo(scanResults); } + StandardWifiEntry(@NonNull Handler callbackHandler, @NonNull WifiConfiguration config) + throws IllegalArgumentException { + super(callbackHandler); + + checkNotNull(config, "Cannot construct with null config!"); + checkNotNull(config.SSID, "Supplied config must have an SSID!"); + + mKey = createStandardWifiEntryKey(config); + mSsid = removeDoubleQuotes(config.SSID); + mSecurity = getSecurityFromWifiConfiguration(config); + mWifiConfig = config; + } + @Override public String getKey() { return mKey; @@ -101,6 +123,11 @@ class StandardWifiEntry extends WifiEntry { return false; } + @Override + public boolean isSaved() { + return mWifiConfig != null; + } + @Override public ConnectedInfo getConnectedInfo() { // TODO(b/70983952): Fill this method in @@ -241,9 +268,7 @@ class StandardWifiEntry extends WifiEntry { @WorkerThread void updateScanResultInfo(@NonNull List scanResults) throws IllegalArgumentException { - if (scanResults.isEmpty()) { - throw new IllegalArgumentException("Cannot update with empty ScanResult list!"); - } + checkNotNull(scanResults); for (ScanResult result : scanResults) { if (!TextUtils.equals(result.SSID, mSsid)) { @@ -263,12 +288,50 @@ class StandardWifiEntry extends WifiEntry { mCurrentScanResults.addAll(scanResults); final ScanResult bestScanResult = getBestScanResultByLevel(mCurrentScanResults); - mLevel = WifiManager.calculateSignalLevel(bestScanResult.level, WifiManager.RSSI_LEVELS); + if (bestScanResult == null) { + mLevel = WIFI_LEVEL_UNREACHABLE; + } else { + mLevel = WifiManager.calculateSignalLevel( + bestScanResult.level, WifiManager.RSSI_LEVELS); + } notifyOnUpdated(); } - static String createStandardWifiEntryKey(ScanResult scan) { + @WorkerThread + void updateConfig(@Nullable WifiConfiguration wifiConfig) throws IllegalArgumentException { + if (wifiConfig != null) { + if (!TextUtils.equals(mSsid, removeDoubleQuotes(wifiConfig.SSID))) { + throw new IllegalArgumentException( + "Attempted to update with wrong SSID!" + + " Expected: " + mSsid + + ", Actual: " + removeDoubleQuotes(wifiConfig.SSID) + + ", Config: " + wifiConfig); + } + if (mSecurity != getSecurityFromWifiConfiguration(wifiConfig)) { + throw new IllegalArgumentException( + "Attempted to update with wrong security!" + + " Expected: " + mSsid + + ", Actual: " + getSecurityFromWifiConfiguration(wifiConfig) + + ", Config: " + wifiConfig); + } + } + + mWifiConfig = wifiConfig; + notifyOnUpdated(); + } + + @NonNull + static String createStandardWifiEntryKey(@NonNull ScanResult scan) { + checkNotNull(scan, "Cannot create key with null scan result!"); return KEY_PREFIX + scan.SSID + "," + getSecurityFromScanResult(scan); } + + @NonNull + static String createStandardWifiEntryKey(@NonNull WifiConfiguration config) { + checkNotNull(config, "Cannot create key with null config!"); + checkNotNull(config.SSID, "Cannot create key with null SSID in config!"); + return KEY_PREFIX + removeDoubleQuotes(config.SSID) + "," + + getSecurityFromWifiConfiguration(config); + } } diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java index aa7f45169..10c890ad7 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java @@ -29,6 +29,7 @@ import static com.android.wifitrackerlib.WifiEntry.SECURITY_WEP; import static java.util.Comparator.comparingInt; import android.net.wifi.ScanResult; +import android.net.wifi.WifiConfiguration; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -74,4 +75,25 @@ class Utils { } return SECURITY_NONE; } + + @WifiEntry.Security + static int getSecurityFromWifiConfiguration(@NonNull WifiConfiguration config) { + if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)) { + return SECURITY_SAE; + } + if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)) { + return SECURITY_PSK; + } + if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SUITE_B_192)) { + return SECURITY_EAP_SUITE_B; + } + if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP) + || config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X)) { + return SECURITY_EAP; + } + if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.OWE)) { + return SECURITY_OWE; + } + return (config.wepKeys[0] != null) ? SECURITY_WEP : SECURITY_NONE; + } } diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java index 3148e6600..c3b762633 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java @@ -16,6 +16,8 @@ package com.android.wifitrackerlib; +import static androidx.core.util.Preconditions.checkNotNull; + import android.os.Handler; import androidx.annotation.AnyThread; @@ -128,6 +130,7 @@ public abstract class WifiEntry implements Comparable { private Handler mCallbackHandler; WifiEntry(@NonNull Handler callbackHandler) throws IllegalArgumentException { + checkNotNull(callbackHandler, "Cannot construct with null handler!"); mCallbackHandler = callbackHandler; } @@ -161,6 +164,12 @@ public abstract class WifiEntry implements Comparable { */ public abstract boolean isMetered(); + /** + * Indicates whether or not an entry is saved, whether by a saved configuration or + * subscription. + */ + public abstract boolean isSaved(); + /** * Returns the ConnectedInfo object pertaining to an active connection. * @@ -375,6 +384,16 @@ public abstract class WifiEntry implements Comparable { // TODO (b/70983952) Come up with a sorting scheme that does the right thing. @Override public int compareTo(@NonNull WifiEntry other) { + if (getLevel() != WIFI_LEVEL_UNREACHABLE && other.getLevel() == WIFI_LEVEL_UNREACHABLE) { + return -1; + } + if (getLevel() == WIFI_LEVEL_UNREACHABLE && other.getLevel() != WIFI_LEVEL_UNREACHABLE) { + return 1; + } + + if (isSaved() && !other.isSaved()) return -1; + if (!isSaved() && other.isSaved()) return 1; + if (getLevel() > other.getLevel()) return -1; if (getLevel() < other.getLevel()) return 1; diff --git a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/StandardWifiEntryTest.java b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/StandardWifiEntryTest.java index 8c07cec83..374b99f36 100644 --- a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/StandardWifiEntryTest.java +++ b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/StandardWifiEntryTest.java @@ -24,6 +24,7 @@ import static org.junit.Assert.fail; import static org.mockito.Mockito.verify; import android.net.wifi.ScanResult; +import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.Handler; import android.os.test.TestLooper; @@ -86,7 +87,7 @@ public class StandardWifiEntryTest { * Tests that the level is set to the level of the strongest scan */ @Test - public void testConstructor_setsBestLevel() { + public void testConstructor_scanResults_setsBestLevel() { final StandardWifiEntry entry = new StandardWifiEntry(mTestHandler, Arrays.asList( buildScanResult("ssid", "bssid0", 0, GOOD_RSSI), buildScanResult("ssid", "bssid1", 0, OKAY_RSSI), @@ -100,7 +101,7 @@ public class StandardWifiEntryTest { * Tests that the security is set to the security capabilities of the scan */ @Test - public void testConstructor_setsSecurity() { + public void testConstructor_scanResults_setsSecurity() { final ScanResult unsecureScan = buildScanResult("ssid", "bssid", 0, GOOD_RSSI); final ScanResult secureScan = buildScanResult("ssid", "bssid", 0, GOOD_RSSI); secureScan.capabilities = "EAP"; @@ -114,23 +115,6 @@ public class StandardWifiEntryTest { assertThat(secureEntry.getSecurity()).isEqualTo(WifiEntry.SECURITY_EAP); } - /** - * Tests that updating with an empty list of scans throws an exception. - */ - @Test - public void testUpdateScanResultInfo_emptyScanList_throwsException() { - final StandardWifiEntry entry = new StandardWifiEntry(mTestHandler, Arrays.asList( - buildScanResult("ssid", "bssid", 0, GOOD_RSSI)) - ); - - try { - entry.updateScanResultInfo(new ArrayList<>()); - fail("Empty scan list should have thrown exception"); - } catch (IllegalArgumentException e) { - // Test succeeded - } - } - /** * Tests that updating with a list of scans with differing SSIDs throws an exception */ @@ -198,4 +182,91 @@ public class StandardWifiEntryTest { assertThat(entry.getLevel()).isEqualTo( WifiManager.calculateSignalLevel(GOOD_RSSI, WifiManager.RSSI_LEVELS)); } + + @Test + public void testConstructor_wifiConfig_setsTitle() { + final WifiConfiguration config = new WifiConfiguration(); + config.SSID = "\"ssid\""; + config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP); + final StandardWifiEntry entry = new StandardWifiEntry(mTestHandler, config); + + assertThat(entry.getTitle()).isEqualTo("ssid"); + } + + @Test + public void testConstructor_wifiConfig_setsSecurity() { + final WifiConfiguration config = new WifiConfiguration(); + config.SSID = "\"ssid\""; + config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP); + final StandardWifiEntry entry = new StandardWifiEntry(mTestHandler, config); + + assertThat(entry.getSecurity()).isEqualTo(WifiEntry.SECURITY_EAP); + } + + @Test + public void testUpdateConfig_mismatchedSsids_throwsException() { + final WifiConfiguration config = new WifiConfiguration(); + config.SSID = "\"ssid\""; + config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP); + final StandardWifiEntry entry = new StandardWifiEntry(mTestHandler, config); + + final WifiConfiguration config2 = new WifiConfiguration(config); + config2.SSID = "\"ssid2\""; + try { + entry.updateConfig(config2); + fail("Updating with wrong SSID config should throw exception"); + } catch (IllegalArgumentException e) { + // Test Succeeded + } + } + + @Test + public void testUpdateConfig_mismatchedSecurity_throwsException() { + final WifiConfiguration config = new WifiConfiguration(); + config.SSID = "\"ssid\""; + config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_WEP); + final StandardWifiEntry entry = new StandardWifiEntry(mTestHandler, config); + + final WifiConfiguration config2 = new WifiConfiguration(config); + config2.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP); + try { + entry.updateConfig(config2); + fail("Updating with wrong security config should throw exception"); + } catch (IllegalArgumentException e) { + // Test Succeeded + } + } + + @Test + public void testUpdateConfig_unsavedToSaved() { + final ScanResult scan = buildScanResult("ssid", "bssid", 0, GOOD_RSSI); + scan.capabilities = "EAP"; + final StandardWifiEntry entry = new StandardWifiEntry(mTestHandler, + Arrays.asList(scan)); + + assertThat(entry.isSaved()).isFalse(); + + final WifiConfiguration config = new WifiConfiguration(); + config.SSID = "\"ssid\""; + config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP); + config.networkId = 1; + entry.updateConfig(config); + + assertThat(entry.isSaved()).isTrue(); + } + + @Test + public void testUpdateConfig_savedToUnsaved() { + final WifiConfiguration config = new WifiConfiguration(); + config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP); + config.SSID = "\"ssid\""; + config.networkId = 1; + final StandardWifiEntry entry = new StandardWifiEntry(mTestHandler, config); + + assertThat(entry.isSaved()).isTrue(); + + entry.updateConfig(null); + + assertThat(entry.isSaved()).isFalse(); + } } -- cgit v1.2.3