summaryrefslogtreecommitdiffstats
path: root/service
diff options
context:
space:
mode:
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/WifiConfigManager.java20
-rw-r--r--service/java/com/android/server/wifi/WifiConfigStore.java36
-rw-r--r--service/java/com/android/server/wifi/WifiQualifiedNetworkSelector.java221
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachine.java1
-rw-r--r--service/java/com/android/server/wifi/hotspot2/omadm/OMAParser.java3
-rw-r--r--service/java/com/android/server/wifi/util/ScanDetailUtil.java8
6 files changed, 270 insertions, 19 deletions
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index 4a27fef97..407773ce9 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -94,6 +94,7 @@ import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -242,6 +243,9 @@ public class WifiConfigManager {
public AtomicInteger mCurrentNetworkBoost = new AtomicInteger();
public AtomicInteger mBandAward5Ghz = new AtomicInteger();
+ // Indicates whether the system is capable of 802.11r fast BSS transition.
+ private boolean mSystemSupportsFastBssTransition = false;
+
/**
* Framework keeps a list of ephemeral SSIDs that where deleted by user,
* so as, framework knows not to autojoin again those SSIDs based on scorer input.
@@ -377,6 +381,8 @@ public class WifiConfigManager {
R.integer.config_wifi_framework_current_network_boost));
mNetworkSwitchingBlackListPeriodMs = mContext.getResources().getInteger(
R.integer.config_wifi_network_switching_blacklist_time);
+ mSystemSupportsFastBssTransition = mContext.getResources().getBoolean(
+ R.bool.config_wifi_fast_bss_transition_enabled);
boolean hs2on = mContext.getResources().getBoolean(R.bool.config_wifi_hotspot2_enabled);
Log.d(Utils.hs2LogTag(getClass()), "Passpoint is " + (hs2on ? "enabled" : "disabled"));
@@ -1123,6 +1129,14 @@ public class WifiConfigManager {
ArrayList<WifiScanner.PnoSettings.PnoNetwork> pnoList = new ArrayList<>();
ArrayList<WifiConfiguration> wifiConfigurations =
new ArrayList<>(mConfiguredNetworks.valuesForCurrentUser());
+ // Remove any permanently disabled networks.
+ Iterator<WifiConfiguration> iter = wifiConfigurations.iterator();
+ while (iter.hasNext()) {
+ WifiConfiguration config = iter.next();
+ if (config.getNetworkSelectionStatus().isNetworkPermanentlyDisabled()) {
+ iter.remove();
+ }
+ }
Collections.sort(wifiConfigurations, pnoListComparator);
// Let's use the network list size as the highest priority and then go down from there.
// So, the most frequently connected network has the highest priority now.
@@ -1951,7 +1965,8 @@ public class WifiConfigManager {
// HasEverConnected to be set to false.
WifiConfiguration originalConfig = new WifiConfiguration(currentConfig);
- if (!mWifiConfigStore.addOrUpdateNetwork(config, currentConfig)) {
+ if (!mWifiConfigStore.addOrUpdateNetwork(config, currentConfig,
+ mSystemSupportsFastBssTransition)) {
return new NetworkUpdateResult(INVALID_NETWORK_ID);
}
int netId = config.networkId;
@@ -3240,7 +3255,8 @@ public class WifiConfigManager {
/**
* Check if the provided ephemeral network was deleted by the user or not.
- * @param ssid ssid of the network
+ * @param ssid caller must ensure that the SSID passed thru this API match
+ * the WifiConfiguration.SSID rules, and thus be surrounded by quotes.
* @return true if network was deleted, false otherwise.
*/
public boolean wasEphemeralNetworkDeleted(String ssid) {
diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java
index b693e2344..beb3373d2 100644
--- a/service/java/com/android/server/wifi/WifiConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiConfigStore.java
@@ -421,13 +421,6 @@ public class WifiConfigStore {
}
config.setIpAssignment(IpAssignment.DHCP);
config.setProxySettings(ProxySettings.NONE);
- if (!WifiServiceImpl.isValid(config)) {
- if (mShowNetworks) {
- localLog("Ignoring network " + config.networkId + " because configuration "
- + "loaded from wpa_supplicant.conf is not valid.");
- }
- continue;
- }
// The configKey is explicitly stored in wpa_supplicant.conf, because config does
// not contain sufficient information to compute it at this point.
String configKey = extras.get(ID_STRING_KEY_CONFIG_KEY);
@@ -601,14 +594,27 @@ public class WifiConfigStore {
return true;
}
+ private BitSet addFastTransitionFlags(BitSet keyManagementFlags) {
+ BitSet modifiedFlags = keyManagementFlags;
+ if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_PSK)) {
+ modifiedFlags.set(WifiConfiguration.KeyMgmt.FT_PSK);
+ }
+ if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_EAP)) {
+ modifiedFlags.set(WifiConfiguration.KeyMgmt.FT_EAP);
+ }
+ return modifiedFlags;
+ }
+
/**
* Save an entire network configuration to wpa_supplicant.
*
* @param config Config corresponding to the network.
- * @param netId Net Id of the network.
+ * @param netId Net Id of the network.
+ * @param addFastTransitionFlags Add the BSS fast transition(80211r) flags to the network.
* @return true if successful, false otherwise.
*/
- private boolean saveNetwork(WifiConfiguration config, int netId) {
+ private boolean saveNetwork(WifiConfiguration config, int netId,
+ boolean addFastTransitionFlags) {
if (config == null) {
return false;
}
@@ -631,6 +637,10 @@ public class WifiConfigStore {
return false;
}
}
+ BitSet allowedKeyManagement = config.allowedKeyManagement;
+ if (addFastTransitionFlags) {
+ allowedKeyManagement = addFastTransitionFlags(config.allowedKeyManagement);
+ }
String allowedKeyManagementString =
makeString(config.allowedKeyManagement, WifiConfiguration.KeyMgmt.strings);
if (config.allowedKeyManagement.cardinality() != 0 && !mWifiNative.setNetworkVariable(
@@ -788,11 +798,13 @@ public class WifiConfigStore {
/**
* Add or update a network configuration to wpa_supplicant.
*
- * @param config Config corresponding to the network.
+ * @param config Config corresponding to the network.
* @param existingConfig Existing config corresponding to the network saved in our database.
+ * @param addFastTransitionFlags Add the BSS fast transition(80211r) flags to the network.
* @return true if successful, false otherwise.
*/
- public boolean addOrUpdateNetwork(WifiConfiguration config, WifiConfiguration existingConfig) {
+ public boolean addOrUpdateNetwork(WifiConfiguration config, WifiConfiguration existingConfig,
+ boolean addFastTransitionFlags) {
if (config == null) {
return false;
}
@@ -816,7 +828,7 @@ public class WifiConfigStore {
// Save the new network ID to the config
config.networkId = netId;
}
- if (!saveNetwork(config, netId)) {
+ if (!saveNetwork(config, netId, addFastTransitionFlags)) {
if (newNetwork) {
mWifiNative.removeNetwork(netId);
loge("Failed to set a network variable, removed network: " + netId);
diff --git a/service/java/com/android/server/wifi/WifiQualifiedNetworkSelector.java b/service/java/com/android/server/wifi/WifiQualifiedNetworkSelector.java
index dd8bdae50..a612cbba1 100644
--- a/service/java/com/android/server/wifi/WifiQualifiedNetworkSelector.java
+++ b/service/java/com/android/server/wifi/WifiQualifiedNetworkSelector.java
@@ -17,7 +17,10 @@
package com.android.server.wifi;
import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.net.NetworkKey;
import android.net.NetworkScoreManager;
import android.net.WifiKey;
@@ -25,18 +28,24 @@ import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
import android.text.TextUtils;
+import android.util.Base64;
import android.util.LocalLog;
import android.util.Log;
import android.util.Pair;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.wifi.util.ScanDetailUtil;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.nio.charset.StandardCharsets;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -108,6 +117,8 @@ public class WifiQualifiedNetworkSelector {
private int mUserPreferedBand = WifiManager.WIFI_FREQUENCY_BAND_AUTO;
private Map<String, BssidBlacklistStatus> mBssidBlacklist =
new HashMap<String, BssidBlacklistStatus>();
+ private List<WifiConfiguration> mCarrierConfiguredNetworks = new ArrayList<WifiConfiguration>();
+ private CarrierConfigManager mCarrierConfigManager;
/**
* class save the blacklist status of a given BSSID
@@ -191,6 +202,50 @@ public class WifiQualifiedNetworkSelector {
mNoIntnetPenalty = (mWifiConfigManager.mThresholdSaturatedRssi24.get() + mRssiScoreOffset)
* mRssiScoreSlope + mWifiConfigManager.mBandAward5Ghz.get()
+ mWifiConfigManager.mCurrentNetworkBoost.get() + mSameBssidAward + mSecurityAward;
+ mCarrierConfigManager = (CarrierConfigManager)
+ context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+
+ final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ localLog("mBroadcastReceiver: onReceive " + intent.getAction());
+ PersistableBundle b = mCarrierConfigManager.getConfig();
+ String[] mWifiArray =
+ b.getStringArray(CarrierConfigManager.KEY_CARRIER_WIFI_STRING_ARRAY);
+ WifiConfiguration wifiConfig;
+ if (mWifiArray == null) {
+ return;
+ }
+
+ for (String config : mWifiArray) {
+ String[] wc = config.split("\\|");
+ wifiConfig = new WifiConfiguration();
+ try {
+ byte[] decodedBytes = Base64.decode(wc[0], Base64.DEFAULT);
+ String ssid = new String(decodedBytes);
+ wifiConfig.SSID = "\"" + ssid + "\"";
+ } catch (IllegalArgumentException ex) {
+ localLog("mBroadcaseReceiver: Could not decode base64 string");
+ continue;
+ }
+ try {
+ int s = Integer.parseInt(wc[1]);
+ wifiConfig.allowedKeyManagement.set(s);
+ } catch (NumberFormatException e) {
+ localLog("mBroadcastReceiver: not an integer" + wc[1]);
+ }
+ mCarrierConfiguredNetworks.add(wifiConfig);
+ localLog("mBroadcastReceiver: onReceive networks:" + wifiConfig.SSID);
+ }
+ }
+ };
+ context.registerReceiver(mBroadcastReceiver, new IntentFilter(
+ CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+ }
+
+ @VisibleForTesting
+ public void setCarrierConfiguredNetworks(List<WifiConfiguration> carrierConfiguredNetworks) {
+ mCarrierConfiguredNetworks = carrierConfiguredNetworks;
}
void enableVerboseLogging(int verbose) {
@@ -238,7 +293,7 @@ public class WifiQualifiedNetworkSelector {
// Current network band must match with user preference selection
if (mWifiInfo.is24GHz() && (mUserPreferedBand != WifiManager.WIFI_FREQUENCY_BAND_2GHZ)) {
- localLog("Current band dose not match user preference. Start Qualified Network"
+ localLog("Current band does not match user preference. Start Qualified Network"
+ " Selection Current band = " + (mWifiInfo.is24GHz() ? "2.4GHz band"
: "5GHz band") + "UserPreference band = " + mUserPreferedBand);
return false;
@@ -582,6 +637,16 @@ public class WifiQualifiedNetworkSelector {
return status == null ? false : status.mIsBlacklisted;
}
+ private boolean isCarrierNetwork(ScanResult scanResult) {
+ String ssid = "\"" + scanResult.SSID + "\"";
+ for (WifiConfiguration config : mCarrierConfiguredNetworks) {
+ if (config.SSID.equals(ssid)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* ToDo: This should be called in Connectivity Manager when it gets new scan result
* check whether a network slection is needed. If need, check all the new scan results and
@@ -605,7 +670,7 @@ public class WifiQualifiedNetworkSelector {
* false -- supplicant is not in a transient state
* @return the qualified network candidate found. If no available candidate, return null
*/
- public WifiConfiguration selectQualifiedNetwork(boolean forceSelectNetwork ,
+ public WifiConfiguration selectQualifiedNetwork(boolean forceSelectNetwork,
boolean isUntrustedConnectionsAllowed, List<ScanDetail> scanDetails,
boolean isLinkDebouncing, boolean isConnected, boolean isDisconnected,
boolean isSupplicantTransient) {
@@ -632,8 +697,11 @@ public class WifiQualifiedNetworkSelector {
int currentHighestScore = Integer.MIN_VALUE;
ScanResult scanResultCandidate = null;
WifiConfiguration networkCandidate = null;
+ WifiConfiguration carrierCandidate = null;
final ExternalScoreEvaluator externalScoreEvaluator =
new ExternalScoreEvaluator(mLocalLog, mDbg);
+ final CarrierScoreEvaluator carrierScoreEvaluator =
+ new CarrierScoreEvaluator(mLocalLog, mDbg);
String lastUserSelectedNetWorkKey = mWifiConfigManager.getLastSelectedConfiguration();
WifiConfiguration lastUserSelectedNetwork =
mWifiConfigManager.getWifiConfiguration(lastUserSelectedNetWorkKey);
@@ -651,6 +719,7 @@ public class WifiQualifiedNetworkSelector {
StringBuffer noValidSsid = new StringBuffer();
StringBuffer scoreHistory = new StringBuffer();
ArrayList<NetworkKey> unscoredNetworks = new ArrayList<NetworkKey>();
+ boolean scanResultsHaveCurrentBssid = false;
//iterate all scan results and find the best candidate with the highest score
for (ScanDetail scanDetail : mScanDetails) {
@@ -664,6 +733,12 @@ public class WifiQualifiedNetworkSelector {
continue;
}
+ //check if the scan results contain the current connected
+ //BSSID.
+ if (scanResult.BSSID.equals(mCurrentBssid)) {
+ scanResultsHaveCurrentBssid = true;
+ }
+
final String scanId = toScanId(scanResult);
//check whether this BSSID is blocked or not
if (mWifiConfigManager.isBssidBlacklisted(scanResult.BSSID)
@@ -725,10 +800,22 @@ public class WifiQualifiedNetworkSelector {
// Evaluate the potentially ephemeral network as a possible candidate if untrusted
// connections are allowed and we have an external score for the scan result.
if (potentiallyEphemeral) {
+ localLog("Network is a ephemeral network...");
if (isUntrustedConnectionsAllowed) {
Integer netScore = getNetworkScore(scanResult, false);
- if (netScore != null
- && !mWifiConfigManager.wasEphemeralNetworkDeleted(scanResult.SSID)) {
+ if (netScore == null) {
+ localLog("Checking the carrierScoreEvaluator for candidates...");
+ // Evaluate the carrier network as a possible candidate.
+ if (!mCarrierConfiguredNetworks.isEmpty() && isCarrierNetwork(scanResult)) {
+ carrierScoreEvaluator.evalCarrierCandidate(scanResult,
+ getCarrierScore(scanResult, mCurrentConnectedNetwork,
+ (mCurrentBssid == null ? false :
+ mCurrentBssid.equals(scanResult.BSSID))));
+ }
+
+ }
+ else if (!mWifiConfigManager.wasEphemeralNetworkDeleted(
+ ScanDetailUtil.createQuotedSSID(scanResult.SSID))) {
externalScoreEvaluator.evalUntrustedCandidate(netScore, scanResult);
// scanDetail is for available ephemeral network
filteredScanDetails.add(Pair.create(scanDetail,
@@ -817,6 +904,16 @@ public class WifiQualifiedNetworkSelector {
localLog(scoreHistory.toString());
}
+ //QNS listens to all single scan results. Some scan requests may not include
+ //the channel of the currently connected network, so the currently connected network
+ //won't show up in the scan results. We don't act on these scan results to avoid
+ //aggressive network switching which might trigger disconnection.
+ if (isConnected && !scanResultsHaveCurrentBssid) {
+ localLog("Current connected BSSID " + mCurrentBssid + " is not in the scan results."
+ + " Skip network selection.");
+ return null;
+ }
+
//we need traverse the whole user preference to choose the one user like most now
if (scanResultCandidate != null) {
WifiConfiguration tempConfig = networkCandidate;
@@ -853,6 +950,14 @@ public class WifiQualifiedNetworkSelector {
}
if (scanResultCandidate == null) {
+ networkCandidate = getCarrierScoreCandidate(carrierScoreEvaluator);
+ localLog("Carrier candidate::" + networkCandidate);
+ if (networkCandidate != null) {
+ scanResultCandidate = networkCandidate.getNetworkSelectionStatus().getCandidate();
+ }
+ }
+
+ if (scanResultCandidate == null) {
localLog("Can not find any suitable candidates");
return null;
}
@@ -937,6 +1042,32 @@ public class WifiQualifiedNetworkSelector {
}
/**
+ * Returns the best candidate network according to the given CarrierScoreEvaluator.
+ */
+ @Nullable
+ WifiConfiguration getCarrierScoreCandidate(CarrierScoreEvaluator scoreEvaluator) {
+ WifiConfiguration networkCandidate = null;
+
+ ScanResult untrustedScanResultCandidate = scoreEvaluator.getScanResultCandidate();
+ if (untrustedScanResultCandidate == null) {
+ return null;
+ }
+ WifiConfiguration unTrustedNetworkCandidate =
+ mWifiConfigManager.wifiConfigurationFromScanResult(
+ untrustedScanResultCandidate);
+ // Mark this config as ephemeral so it isn't persisted.
+ unTrustedNetworkCandidate.ephemeral = true;
+ mWifiConfigManager.saveNetwork(unTrustedNetworkCandidate, WifiConfiguration.UNKNOWN_UID);
+ localLog(String.format("new carrier candidate %s network ID:%d, ",
+ toScanId(untrustedScanResultCandidate), unTrustedNetworkCandidate.networkId));
+
+ unTrustedNetworkCandidate.getNetworkSelectionStatus()
+ .setCandidate(untrustedScanResultCandidate);
+ networkCandidate = unTrustedNetworkCandidate;
+ return networkCandidate;
+ }
+
+ /**
* Returns the available external network score or NULL if no score is available.
*
* @param scanResult The scan result of the network to score.
@@ -954,6 +1085,43 @@ public class WifiQualifiedNetworkSelector {
}
/**
+ * Returns the available external network score or NULL if no score is available.
+ *
+ * @param scanResult The scan result of the network to score.
+ * @return A valid external score if one is available or NULL.
+ */
+ int getCarrierScore(ScanResult scanResult, WifiConfiguration currentNetwork,
+ boolean sameBssid) {
+ localLog("Calc Carrier score: w/" + sameBssid);
+ if (currentNetwork != null) {
+ localLog("scoring: compare::" + scanResult.SSID + ", with:" + currentNetwork.SSID);
+ }
+ int score = 0;
+ // Calculate the RSSI score.
+ int rssi = scanResult.level <= mWifiConfigManager.mThresholdSaturatedRssi24.get()
+ ? scanResult.level : mWifiConfigManager.mThresholdSaturatedRssi24.get();
+ score += (rssi + mRssiScoreOffset) * mRssiScoreSlope;
+
+ // 5GHz band bonus.
+ if (scanResult.is5GHz()) {
+ score += BAND_AWARD_5GHz;
+ }
+
+ //same network award
+ if ((currentNetwork != null) && currentNetwork.SSID.equals(scanResult.SSID)) {
+ score += mWifiConfigManager.mCurrentNetworkBoost.get();
+ }
+
+ //same BSSID award
+ if (sameBssid) {
+ score += mSameBssidAward;
+ }
+
+ localLog("Calc Carrier score:" + score);
+ return score;
+ }
+
+ /**
* Formats the given ScanResult as a scan ID for logging.
*/
private static String toScanId(@Nullable ScanResult scanResult) {
@@ -1042,4 +1210,49 @@ public class WifiQualifiedNetworkSelector {
}
}
}
+
+ /**
+ * Used to track and evaluate networks that are assigned by the Carriers.
+ */
+ static class CarrierScoreEvaluator {
+ // Always set to the best known candidate
+ private int mHighScore = WifiNetworkScoreCache.INVALID_NETWORK_SCORE;
+ private WifiConfiguration mSavedConfig;
+ private ScanResult mScanResultCandidate;
+ private final LocalLog mLocalLog;
+ private final boolean mDbg;
+
+ CarrierScoreEvaluator(LocalLog localLog, boolean dbg) {
+ mLocalLog = localLog;
+ mDbg = dbg;
+ }
+
+ // Determines whether or not the given scan result is the best one its seen so far.
+ void evalCarrierCandidate(ScanResult scanResult, int score) {
+ if (score > mHighScore) {
+ mHighScore = score;
+ mScanResultCandidate = scanResult;
+ localLog(toScanId(scanResult) +
+ " become the new untrusted carrier network candidate");
+ }
+ }
+
+ int getHighScore() {
+ return mHighScore;
+ }
+
+ public ScanResult getScanResultCandidate() {
+ return mScanResultCandidate;
+ }
+
+ WifiConfiguration getSavedConfig() {
+ return mSavedConfig;
+ }
+
+ private void localLog(String log) {
+ if (mDbg) {
+ mLocalLog.log(log);
+ }
+ }
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 9d8a66f2d..0c7e987ee 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -1026,7 +1026,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
mP2pSupported = mContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_WIFI_DIRECT);
-
mWifiConfigManager = mFacade.makeWifiConfigManager(context, mWifiNative, facade,
mWifiInjector.getClock(), userManager, mWifiInjector.getKeyStore());
diff --git a/service/java/com/android/server/wifi/hotspot2/omadm/OMAParser.java b/service/java/com/android/server/wifi/hotspot2/omadm/OMAParser.java
index cbcd81d16..d39fa33a1 100644
--- a/service/java/com/android/server/wifi/hotspot2/omadm/OMAParser.java
+++ b/service/java/com/android/server/wifi/hotspot2/omadm/OMAParser.java
@@ -26,6 +26,9 @@ public class OMAParser extends DefaultHandler {
}
public MOTree parse(String text, String urn) throws IOException, SAXException {
+ if (text == null) {
+ throw new IOException("Missing text string");
+ }
try {
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
parser.parse(new InputSource(new StringReader(text)), this);
diff --git a/service/java/com/android/server/wifi/util/ScanDetailUtil.java b/service/java/com/android/server/wifi/util/ScanDetailUtil.java
index a83900e0a..c5ec92af9 100644
--- a/service/java/com/android/server/wifi/util/ScanDetailUtil.java
+++ b/service/java/com/android/server/wifi/util/ScanDetailUtil.java
@@ -37,4 +37,12 @@ public class ScanDetailUtil {
scanResult.informationElements, scanResult.anqpLines, scanResult.frequency);
return new ScanDetail(scanResult, networkDetail, null);
}
+
+ /**
+ * Helper method to quote the SSID in Scan result to use for comparing/filling SSID stored in
+ * WifiConfiguration object.
+ */
+ public static String createQuotedSSID(String ssid) {
+ return "\"" + ssid + "\"";
+ }
}