diff options
author | Dan Pasanen <dan.pasanen@gmail.com> | 2017-04-05 07:54:13 -0500 |
---|---|---|
committer | Dan Pasanen <dan.pasanen@gmail.com> | 2017-04-05 12:55:23 -0500 |
commit | f0223d50d12fea721a37481ed0500d6ae6d774b6 (patch) | |
tree | 18be3f446cbc4d99df4703dea1683c92a0366c7d /service/java/com | |
parent | 2c25264908d020b03fb91ada6a92ce2728ef576f (diff) | |
parent | 89c893388a2fe8f9b84dca3dd2ec6c5a793fbea1 (diff) | |
download | android_frameworks_opt_net_wifi-staging/cm-14.1_android-7.1.2_r2.tar.gz android_frameworks_opt_net_wifi-staging/cm-14.1_android-7.1.2_r2.tar.bz2 android_frameworks_opt_net_wifi-staging/cm-14.1_android-7.1.2_r2.zip |
Merge tag 'android-7.1.2_r2' into cm-14.1staging/cm-14.1_android-7.1.2_r2
Android 7.1.2 Release 2 (N2G47E)
Change-Id: Id7bfdf0f54f9f0a7f149b8a1f6f62fe4b791e021
Diffstat (limited to 'service/java/com')
10 files changed, 617 insertions, 68 deletions
diff --git a/service/java/com/android/server/wifi/PropertyService.java b/service/java/com/android/server/wifi/PropertyService.java index 2895f43df..c998ff955 100644 --- a/service/java/com/android/server/wifi/PropertyService.java +++ b/service/java/com/android/server/wifi/PropertyService.java @@ -36,4 +36,11 @@ public interface PropertyService { * @throws IllegalArgumentException if the value exceeds 92 characters */ void set(String key, String val); + + /** + * Get the current value of |key|. + * @return value of |key|, if key exists; |defaultValue| otherwise + */ + boolean getBoolean(String key, boolean defaultValue); + } diff --git a/service/java/com/android/server/wifi/SystemPropertyService.java b/service/java/com/android/server/wifi/SystemPropertyService.java index ed689c424..4c7ffb6d2 100644 --- a/service/java/com/android/server/wifi/SystemPropertyService.java +++ b/service/java/com/android/server/wifi/SystemPropertyService.java @@ -27,4 +27,9 @@ class SystemPropertyService implements PropertyService { public void set(String key, String val) { android.os.SystemProperties.set(key, val); } + + @Override + public boolean getBoolean(String key, boolean defaultValue) { + return android.os.SystemProperties.getBoolean(key, defaultValue); + } } diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java index 5a248bee9..9129fe612 100644 --- a/service/java/com/android/server/wifi/WifiConfigManager.java +++ b/service/java/com/android/server/wifi/WifiConfigManager.java @@ -51,6 +51,7 @@ import android.os.UserManager; import android.provider.Settings; import android.security.KeyStore; import android.text.TextUtils; +import android.util.ArraySet; import android.util.LocalLog; import android.util.Log; import android.util.SparseArray; @@ -94,6 +95,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 +244,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. @@ -254,6 +259,12 @@ public class WifiConfigManager { /* configured networks with network id as the key */ private final ConfigurationMap mConfiguredNetworks; + /* + * Stores whether carrier networks are configured. + * This information is provided externally from the CarrierConfig. + */ + private boolean mHasCarrierConfiguredNetworks; + private final LocalLog mLocalLog; private final KeyStore mKeyStore; private final WifiNetworkHistory mWifiNetworkHistory; @@ -377,6 +388,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); boolean hs2onSet = (Settings.Global.getInt(mContext.getContentResolver(), @@ -508,6 +521,22 @@ public class WifiConfigManager { } /** + * Check if Carrier networks have ben configured. + * @return true if carrier networks are present else false. + */ + public boolean hasCarrierNetworks() { + return mHasCarrierConfiguredNetworks; + } + + /** + * Set true/false depending on whether Carrier networks have been configured. + * @param hasCarrierNetworks if Carrier networks have been configured. + */ + public void setHasCarrierNetworks(boolean hasCarrierNetworks) { + mHasCarrierConfiguredNetworks = hasCarrierNetworks; + } + + /** * Fetch the list of currently saved networks (i.e. all configured networks, excluding * ephemeral networks), filled with real preSharedKeys. * @return List of networks @@ -1150,6 +1179,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. @@ -1244,52 +1281,56 @@ public class WifiConfigManager { /* * Remove all networks associated with an application * - * @param packageName name of the package of networks to remove - * @return {@code true} if all networks removed successfully, {@code false} otherwise + * @param app Application info of the package of networks to remove. + * @return the {@link Set} of networks that were removed by this call. Networks which matched + * but failed to remove are omitted from this set. */ - boolean removeNetworksForApp(ApplicationInfo app) { + public Set<Integer> removeNetworksForApp(ApplicationInfo app) { if (app == null || app.packageName == null) { - return false; + return Collections.<Integer>emptySet(); } - boolean success = true; - - WifiConfiguration [] copiedConfigs = - mConfiguredNetworks.valuesForCurrentUser().toArray(new WifiConfiguration[0]); + Log.d(TAG, "Remove all networks for app " + app); + Set<Integer> removedNetworks = new ArraySet<>(); + WifiConfiguration[] copiedConfigs = + mConfiguredNetworks.valuesForAllUsers().toArray(new WifiConfiguration[0]); for (WifiConfiguration config : copiedConfigs) { if (app.uid != config.creatorUid || !app.packageName.equals(config.creatorName)) { continue; } - if (mShowNetworks) { - localLog("Removing network " + config.SSID - + ", application \"" + app.packageName + "\" uninstalled" - + " from user " + UserHandle.getUserId(app.uid)); + localLog("Removing network " + config.SSID + + ", application \"" + app.packageName + "\" uninstalled" + + " from user " + UserHandle.getUserId(app.uid)); + if (removeNetwork(config.networkId)) { + removedNetworks.add(config.networkId); } - success &= removeNetwork(config.networkId); } - saveConfig(); - - return success; + return removedNetworks; } - boolean removeNetworksForUser(int userId) { - boolean success = true; - + /** + * Remove all networks associated with a user. + * + * @param userId The identifier of the user which is being removed. + * @return the {@link Set} of networks that were removed by this call. Networks which matched + * but failed to remove are omitted from this set. + */ + Set<Integer> removeNetworksForUser(int userId) { + Log.d(TAG, "Remove all networks for user " + userId); + Set<Integer> removedNetworks = new ArraySet<>(); WifiConfiguration[] copiedConfigs = mConfiguredNetworks.valuesForAllUsers().toArray(new WifiConfiguration[0]); for (WifiConfiguration config : copiedConfigs) { if (userId != UserHandle.getUserId(config.creatorUid)) { continue; } - success &= removeNetwork(config.networkId); - if (mShowNetworks) { - localLog("Removing network " + config.SSID - + ", user " + userId + " removed"); + localLog("Removing network " + config.SSID + ", user " + userId + " removed"); + if (removeNetwork(config.networkId)) { + removedNetworks.add(config.networkId); } } - - return success; + return removedNetworks; } /** @@ -1979,7 +2020,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; @@ -2018,6 +2060,7 @@ public class WifiConfigManager { currentConfig.updateTime = config.updateTime; currentConfig.creationTime = config.creationTime; currentConfig.shared = config.shared; + currentConfig.isCarrierNetwork = config.isCarrierNetwork; } if (DBG) { log("created new config netId=" + Integer.toString(netId) @@ -3199,6 +3242,33 @@ public class WifiConfigManager { } /** + * Saves the network and set the candidate. + * @param config WifiConfiguration to save. + * @param scanResult ScanResult to be used as the network selection candidate. + * @return WifiConfiguration that was saved and with the status updated. + */ + public WifiConfiguration saveNetworkAndSetCandidate(WifiConfiguration config, + ScanResult scanResult) { + saveNetwork(config, WifiConfiguration.UNKNOWN_UID); + + config.getNetworkSelectionStatus().setCandidate(scanResult); + return config; + } + + + /** + * Get the Scan Result candidate. + * @param config WifiConfiguration to get status for. + * @return scanResult which is the selection candidate. + */ + public ScanResult getScanResultCandidate(WifiConfiguration config) { + if (config == null) { + return null; + } + return config.getNetworkSelectionStatus().getCandidate(); + } + + /** * Checks if uid has access to modify config. */ boolean canModifyNetwork(int uid, WifiConfiguration config, boolean onlyAnnotate) { @@ -3268,10 +3338,20 @@ 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) { return mDeletedEphemeralSSIDs.contains(ssid); } + + /** + * Check if the User has enabled connecting to carrier networks from Settings. + * @return true if enabled in Settings, false otherwise. + */ + public boolean getIsCarrierNetworkEnabledByUser() { + return android.provider.Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.WIFI_CONNECT_CARRIER_NETWORKS, 0) == 1; + } } diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java index 908487152..fc4c122fa 100644 --- a/service/java/com/android/server/wifi/WifiConfigStore.java +++ b/service/java/com/android/server/wifi/WifiConfigStore.java @@ -350,6 +350,8 @@ public class WifiConfigStore { readNetworkBitsetVariable(config.networkId, config.allowedKeyManagement, WifiConfiguration.KeyMgmt.varName, WifiConfiguration.KeyMgmt.strings); + // The FT flags should not be exposed to external apps. + config.allowedKeyManagement = removeFastTransitionFlags(config.allowedKeyManagement); readNetworkBitsetVariable(config.networkId, config.allowedAuthAlgorithms, WifiConfiguration.AuthAlgorithm.varName, WifiConfiguration.AuthAlgorithm.strings); @@ -430,13 +432,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); @@ -610,14 +605,34 @@ 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; + } + + private BitSet removeFastTransitionFlags(BitSet keyManagementFlags) { + BitSet modifiedFlags = keyManagementFlags; + modifiedFlags.clear(WifiConfiguration.KeyMgmt.FT_PSK); + modifiedFlags.clear(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; } @@ -640,6 +655,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( @@ -804,11 +823,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; } @@ -832,7 +853,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/WifiController.java b/service/java/com/android/server/wifi/WifiController.java index b72540f8b..26f662adb 100644 --- a/service/java/com/android/server/wifi/WifiController.java +++ b/service/java/com/android/server/wifi/WifiController.java @@ -694,8 +694,10 @@ public class WifiController extends StateMachine { @Override public void enter() { - mWifiStateMachine.setSupplicantRunning(true); + // need to set the mode before starting supplicant because WSM will assume we are going + // in to client mode mWifiStateMachine.setOperationalMode(WifiStateMachine.SCAN_ONLY_WITH_WIFI_OFF_MODE); + mWifiStateMachine.setSupplicantRunning(true); mWifiStateMachine.setDriverStart(true); // Supplicant can't restart right away, so not the time we switched off mDisabledTimestamp = SystemClock.elapsedRealtime(); diff --git a/service/java/com/android/server/wifi/WifiQualifiedNetworkSelector.java b/service/java/com/android/server/wifi/WifiQualifiedNetworkSelector.java index 00fffdb4b..e429d835a 100644 --- a/service/java/com/android/server/wifi/WifiQualifiedNetworkSelector.java +++ b/service/java/com/android/server/wifi/WifiQualifiedNetworkSelector.java @@ -17,26 +17,36 @@ 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; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiEnterpriseConfig; 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; @@ -70,6 +80,10 @@ public class WifiQualifiedNetworkSelector { //usable only when current state is connected state default 10 s private static final int MINIMUM_QUALIFIED_NETWORK_SELECTION_INTERVAL = 10 * 1000; + private static final int CARRIER_SSID = 0; + private static final int CARRIER_KEY = 1; + private static final int CARRIER_EAP_METHOD = 2; + //if current network is on 2.4GHz band and has a RSSI over this, need not new network selection public static final int QUALIFIED_RSSI_24G_BAND = -73; //if current network is on 5GHz band and has a RSSI over this, need not new network selection @@ -109,6 +123,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 Context mContext; /** * class save the blacklist status of a given BSSID @@ -127,6 +143,11 @@ public class WifiQualifiedNetworkSelector { } } + @VisibleForTesting + public void setCarrierConfiguredNetworks(List<WifiConfiguration> carrierConfiguredNetworks) { + mCarrierConfiguredNetworks = carrierConfiguredNetworks; + } + private void localLoge(String log) { mLocalLog.log(log); } @@ -167,6 +188,7 @@ public class WifiQualifiedNetworkSelector { mWifiConfigManager = configureStore; mWifiInfo = wifiInfo; mClock = clock; + mContext = context; mScoreManager = (NetworkScoreManager) context.getSystemService(Context.NETWORK_SCORE_SERVICE); if (mScoreManager != null) { @@ -193,8 +215,73 @@ public class WifiQualifiedNetworkSelector { mNoIntnetPenalty = (mWifiConfigManager.mThresholdSaturatedRssi24.get() + mRssiScoreOffset) * mRssiScoreSlope + mWifiConfigManager.mBandAward5Ghz.get() + mWifiConfigManager.mCurrentNetworkBoost.get() + mSameBssidAward + mSecurityAward; + + context.registerReceiver(mBroadcastReceiver, new IntentFilter( + CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)); + } + + @VisibleForTesting + public List<WifiConfiguration> parseCarrierSuppliedWifiInfo(String[] wifiArray) { + List<WifiConfiguration> carrierConfiguredNetworks = new ArrayList<WifiConfiguration>(); + for (String config : wifiArray) { + String[] wc = config.split("\\|"); + if (wc.length != 3) { + continue; + } + WifiConfiguration wifiConfig = new WifiConfiguration(); + try { + byte[] decodedBytes = Base64.decode(wc[CARRIER_SSID], Base64.DEFAULT); + String ssid = new String(decodedBytes); + wifiConfig.SSID = "\"" + ssid + "\""; + } catch (IllegalArgumentException ex) { + localLog("mBroadcaseReceiver: Could not decode base64 string"); + continue; + } + try { + int key = Integer.parseInt(wc[CARRIER_KEY]); + wifiConfig.allowedKeyManagement.set(key); + int eapType = Integer.parseInt(wc[CARRIER_EAP_METHOD]); + wifiConfig.enterpriseConfig = new WifiEnterpriseConfig(); + wifiConfig.enterpriseConfig.setEapMethod(eapType); + } catch (NumberFormatException e) { + localLog("mBroadcastReceiver: not an integer:" + wc[CARRIER_KEY] + "," + + wc[CARRIER_EAP_METHOD]); + continue; + } catch (IllegalArgumentException e) { + localLog("mBroadcastReceiver: invalid config" + wc[CARRIER_KEY] + "," + + wc[CARRIER_EAP_METHOD]); + } + carrierConfiguredNetworks.add(wifiConfig); + localLog("mBroadcastReceiver: carrier config:" + wifiConfig.SSID); + } + return carrierConfiguredNetworks; } + final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + localLog("mBroadcastReceiver: onReceive " + intent.getAction()); + String[] wifiArray = null; + CarrierConfigManager carrierConfigManager = (CarrierConfigManager) + mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); + if (carrierConfigManager != null) { + PersistableBundle b = carrierConfigManager.getConfig(); + if (b != null) { + wifiArray = b.getStringArray( + CarrierConfigManager.KEY_CARRIER_WIFI_STRING_ARRAY); + } + } + + if (wifiArray == null) { + return; + } + mCarrierConfiguredNetworks = parseCarrierSuppliedWifiInfo(wifiArray); + boolean hasCarrierNetworks = (mCarrierConfiguredNetworks == null || + mCarrierConfiguredNetworks.size() == 0) ? false : true; + mWifiConfigManager.setHasCarrierNetworks(hasCarrierNetworks); + } + }; + void enableVerboseLogging(int verbose) { mDbg = verbose > 0 || FORCE_DEBUG; } @@ -240,7 +327,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; @@ -591,6 +678,11 @@ public class WifiQualifiedNetworkSelector { return status == null ? false : status.mIsBlacklisted; } + private boolean isCarrierNetwork(ScanResult scanResult) { + return (getMatchingConfigForEAPNetworks(scanResult, + mCarrierConfiguredNetworks) != null ? true : 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 @@ -614,7 +706,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) { @@ -641,8 +733,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); @@ -660,6 +755,10 @@ public class WifiQualifiedNetworkSelector { StringBuffer noValidSsid = new StringBuffer(); StringBuffer scoreHistory = new StringBuffer(); ArrayList<NetworkKey> unscoredNetworks = new ArrayList<NetworkKey>(); + boolean scanResultsHaveCurrentBssid = false; + + localLog("isCarrierNetworkEnabledByUser: " + + mWifiConfigManager.getIsCarrierNetworkEnabledByUser()); //iterate all scan results and find the best candidate with the highest score for (ScanDetail scanDetail : mScanDetails) { @@ -673,6 +772,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) @@ -734,12 +839,26 @@ 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) { - if (isUntrustedConnectionsAllowed) { - Integer netScore = getNetworkScore(scanResult, false); - if (netScore != null - && !mWifiConfigManager.wasEphemeralNetworkDeleted(scanResult.SSID)) { - externalScoreEvaluator.evalUntrustedCandidate(netScore, scanResult); - // scanDetail is for available ephemeral network + if (!mWifiConfigManager.wasEphemeralNetworkDeleted( + ScanDetailUtil.createQuotedSSID(scanResult.SSID))) { + if (isUntrustedConnectionsAllowed) { + Integer netScore = getNetworkScore(scanResult, false); + if (netScore != null) { + externalScoreEvaluator.evalUntrustedCandidate(netScore, scanResult); + // scanDetail is for available ephemeral network + filteredScanDetails.add(Pair.create(scanDetail, + potentialEphemeralCandidate)); + } + // Evaluate the carrier network as a possible candidate. + // todo need to add flag isCarrierConnectionsAllowed, config in settings. + } else if (!mCarrierConfiguredNetworks.isEmpty() && + isCarrierNetwork(scanResult) && + mWifiConfigManager.getIsCarrierNetworkEnabledByUser()) { + localLog("Checking the carrierScoreEvaluator for candidates..."); + carrierScoreEvaluator.evalCarrierCandidate(scanResult, + getCarrierScore(scanResult, mCurrentConnectedNetwork, + (mCurrentBssid == null ? false : + mCurrentBssid.equals(scanResult.BSSID)))); filteredScanDetails.add(Pair.create(scanDetail, potentialEphemeralCandidate)); } @@ -826,6 +945,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; @@ -862,6 +991,15 @@ public class WifiQualifiedNetworkSelector { } if (scanResultCandidate == null) { + networkCandidate = getCarrierScoreCandidate(carrierScoreEvaluator); + localLog("Carrier candidate::" + networkCandidate); + if (networkCandidate != null) { + scanResultCandidate = + mWifiConfigManager.getScanResultCandidate(networkCandidate); + } + } + + if (scanResultCandidate == null) { localLog("Can not find any suitable candidates"); return null; } @@ -946,6 +1084,37 @@ public class WifiQualifiedNetworkSelector { } /** + * Returns the best candidate network according to the given CarrierScoreEvaluator. + */ + @Nullable + WifiConfiguration getCarrierScoreCandidate(CarrierScoreEvaluator scoreEvaluator) { + + ScanResult untrustedCarrierScanResult = scoreEvaluator.getScanResultCandidate(); + if (untrustedCarrierScanResult == null) { + return null; + } + + WifiConfiguration untrustedCandidateConfig = getMatchingConfigForEAPNetworks( + untrustedCarrierScanResult, mCarrierConfiguredNetworks); + + if (untrustedCandidateConfig == null) { + return null; + } + + WifiConfiguration newUntrustedCandidateConfig = + new WifiConfiguration(untrustedCandidateConfig); + + // Mark this config as ephemeral so it isn't persisted. + newUntrustedCandidateConfig.ephemeral = true; + // Mark this config as a Carrier Network. + newUntrustedCandidateConfig.isCarrierNetwork = true; + + mWifiConfigManager.saveNetworkAndSetCandidate( + newUntrustedCandidateConfig, untrustedCarrierScanResult); + return newUntrustedCandidateConfig; + } + + /** * Returns the available external network score or NULL if no score is available. * * @param scanResult The scan result of the network to score. @@ -963,6 +1132,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) { @@ -1051,4 +1257,66 @@ 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 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; + } + + private void localLog(String log) { + if (mDbg) { + mLocalLog.log(log); + } + } + } + + private WifiConfiguration getMatchingConfigForEAPNetworks( + ScanResult scanResult, List<WifiConfiguration> candidateConfigs) { + if (scanResult == null || candidateConfigs == null) { + return null; + } + // TODO currently we only support EAP. We'll add to this in OC. + if (!scanResult.capabilities.contains("EAP")) { + return null; + } + String ssid = "\"" + scanResult.SSID + "\""; + for (WifiConfiguration config : candidateConfigs) { + if (config.SSID.equals(ssid)) { + // TODO currently we only support EAP. We'll add to this in OC. + if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP) || + config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X)) { + return config; + } + } + } + return null; + } } diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java index e5a537dd0..bea194908 100755 --- a/service/java/com/android/server/wifi/WifiServiceImpl.java +++ b/service/java/com/android/server/wifi/WifiServiceImpl.java @@ -37,6 +37,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.database.ContentObserver; @@ -72,6 +73,7 @@ import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.os.PowerManager; +import android.os.Process; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.SystemClock; @@ -188,6 +190,8 @@ public class WifiServiceImpl extends IWifiManager.Stub { */ private AsyncChannel mWifiStateMachineChannel; + private final boolean mPermissionReviewRequired; + /** * Handles client connections */ @@ -390,6 +394,10 @@ public class WifiServiceImpl extends IWifiManager.Stub { } // Set the WifiController for WifiLastResortWatchdog mWifiInjector.getWifiLastResortWatchdog().setWifiController(mWifiController); + + mPermissionReviewRequired = Build.PERMISSIONS_REVIEW_REQUIRED + || context.getResources().getBoolean( + com.android.internal.R.bool.config_permissionReviewRequired); } @@ -451,7 +459,13 @@ public class WifiServiceImpl extends IWifiManager.Stub { // If we are already disabled (could be due to airplane mode), avoid changing persist // state here - if (wifiEnabled) setWifiEnabled(wifiEnabled); + if (wifiEnabled) { + try { + setWifiEnabled(mContext.getPackageName(), wifiEnabled); + } catch (RemoteException e) { + /* ignore - local call */ + } + } } public void handleUserSwitch(int userId) { @@ -594,12 +608,12 @@ public class WifiServiceImpl extends IWifiManager.Stub { * @return {@code true} if the enable/disable operation was * started or is already in the queue. */ - public synchronized boolean setWifiEnabled(boolean enable) { + public synchronized boolean setWifiEnabled(String packageName, boolean enable) + throws RemoteException { enforceChangePermission(); Slog.d(TAG, "setWifiEnabled: " + enable + " pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); if(isStrictOpEnable()){ - String packageName = mContext.getPackageManager().getNameForUid(Binder.getCallingUid()); if((Binder.getCallingUid() > 10000) && (packageName.indexOf("android.uid.systemui") !=0) && (packageName.indexOf("android.uid.system") != 0)) { AppOpsManager mAppOpsManager = mContext.getSystemService(AppOpsManager.class); int result = mAppOpsManager.noteOp(AppOpsManager.OP_CHANGE_WIFI_STATE,Binder.getCallingUid(),packageName); @@ -612,7 +626,6 @@ public class WifiServiceImpl extends IWifiManager.Stub { * Caller might not have WRITE_SECURE_SETTINGS, * only CHANGE_WIFI_STATE is enforced */ - long ident = Binder.clearCallingIdentity(); try { if (! mSettingsStore.handleWifiToggled(enable)) { @@ -627,6 +640,26 @@ public class WifiServiceImpl extends IWifiManager.Stub { Slog.e(TAG,"WifiController is not yet started, abort setWifiEnabled"); return false; } + + if (mPermissionReviewRequired) { + final int wiFiEnabledState = getWifiEnabledState(); + if (enable) { + if (wiFiEnabledState == WifiManager.WIFI_STATE_DISABLING + || wiFiEnabledState == WifiManager.WIFI_STATE_DISABLED) { + if (startConsentUi(packageName, Binder.getCallingUid(), + WifiManager.ACTION_REQUEST_ENABLE)) { + return true; + } + } + } else if (wiFiEnabledState == WifiManager.WIFI_STATE_ENABLING + || wiFiEnabledState == WifiManager.WIFI_STATE_ENABLED) { + if (startConsentUi(packageName, Binder.getCallingUid(), + WifiManager.ACTION_REQUEST_DISABLE)) { + return true; + } + } + } + mWifiController.sendMessage(CMD_WIFI_TOGGLED); return true; } @@ -860,6 +893,21 @@ public class WifiServiceImpl extends IWifiManager.Stub { } /** + * see {@link android.net.wifi.WifiManager#getHasCarrierNetworks()} + * @return if Carrier Networks have been configured + */ + public boolean hasCarrierConfiguredNetworks() { + enforceAccessPermission(); + if (mWifiStateMachineChannel != null) { + return mWifiStateMachine.syncHasCarrierConfiguredNetworks(Binder.getCallingUid(), + mWifiStateMachineChannel); + } else { + Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); + return false; + } + } + + /** * see {@link android.net.wifi.WifiManager#getPrivilegedConfiguredNetworks()} * @return the list of configured networks with real preSharedKey */ @@ -1456,7 +1504,11 @@ public class WifiServiceImpl extends IWifiManager.Stub { } } else if ( state == WifiManager.WIFI_STATE_DISABLED) { if (mSubSystemRestart) { - setWifiEnabled(true); + try { + setWifiEnabled(mContext.getPackageName(), true); + } catch (RemoteException e) { + /* ignore - local call */ + } } } } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) { @@ -1465,7 +1517,11 @@ public class WifiServiceImpl extends IWifiManager.Stub { if (mSubSystemRestart) { if (wifiApState == WifiManager.WIFI_AP_STATE_DISABLED) { if (getWifiEnabledState() == WifiManager.WIFI_STATE_ENABLED) { - setWifiEnabled(false); + try { + setWifiEnabled(mContext.getPackageName(), false); + } catch (RemoteException e) { + /* ignore - local call */ + } } else { /** * STA in DISABLED state, hence just restart SAP. @@ -1487,6 +1543,34 @@ public class WifiServiceImpl extends IWifiManager.Stub { } }; + private boolean startConsentUi(String packageName, + int callingUid, String intentAction) throws RemoteException { + if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { + return false; + } + try { + // Validate the package only if we are going to use it + ApplicationInfo applicationInfo = mContext.getPackageManager() + .getApplicationInfoAsUser(packageName, + PackageManager.MATCH_DEBUG_TRIAGED_MISSING, + UserHandle.getUserId(callingUid)); + if (applicationInfo.uid != callingUid) { + throw new SecurityException("Package " + callingUid + + " not in uid " + callingUid); + } + + // Permission review mode, trigger a user prompt + Intent intent = new Intent(intentAction); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); + intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName); + mContext.startActivity(intent); + return true; + } catch (PackageManager.NameNotFoundException e) { + throw new RemoteException(e.getMessage()); + } + } + /** * Observes settings changes to scan always mode. */ @@ -1860,7 +1944,11 @@ public class WifiServiceImpl extends IWifiManager.Stub { } else { mIsFactoryResetOn = true; // Enable wifi - setWifiEnabled(true); + try { + setWifiEnabled(mContext.getOpPackageName(), true); + } catch (RemoteException e) { + /* ignore - local call */ + } } } } diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 5d1906aca..f34d0b1e9 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -663,6 +663,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss static final int CMD_GET_PRIVILEGED_CONFIGURED_NETWORKS = BASE + 62; /* Get Link Layer Stats thru HAL */ static final int CMD_GET_LINK_LAYER_STATS = BASE + 63; + /* Has Carrier configured networks */ + static final int CMD_HAS_CARRIER_CONFIGURED_NETWORKS = BASE + 64; /* Supplicant commands after driver start*/ /* Initiate a scan */ static final int CMD_START_SCAN = BASE + 71; @@ -1071,7 +1073,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()); @@ -2151,6 +2152,21 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss return result; } + /** + * Check if Carrier networks have been configured synchronously + * + * @param channel + * @return + */ + public boolean syncHasCarrierConfiguredNetworks( + int uuid, AsyncChannel channel) { + Message resultMsg = channel.sendMessageSynchronously( + CMD_HAS_CARRIER_CONFIGURED_NETWORKS, uuid); + boolean result = resultMsg.obj != null && (boolean) resultMsg.obj; + resultMsg.recycle(); + return result; + } + public List<WifiConfiguration> syncGetPrivilegedConfiguredNetwork(AsyncChannel channel) { Message resultMsg = channel.sendMessageSynchronously( CMD_GET_PRIVILEGED_CONFIGURED_NETWORKS); @@ -2186,6 +2202,14 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss Message resultMsg = channel.sendMessageSynchronously(CMD_GET_SUPPORTED_FEATURES); int supportedFeatureSet = resultMsg.arg1; resultMsg.recycle(); + + // Mask the feature set against system properties. + boolean disableRtt = mPropertyService.getBoolean("config.disable_rtt", false); + if (disableRtt) { + supportedFeatureSet &= + ~(WifiManager.WIFI_FEATURE_D2D_RTT | WifiManager.WIFI_FEATURE_D2AP_RTT); + } + return supportedFeatureSet; } @@ -2911,6 +2935,13 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss sb.append(Integer.toString(msg.arg2)); sb.append(" num=").append(mWifiConfigManager.getConfiguredNetworksSize()); break; + case CMD_HAS_CARRIER_CONFIGURED_NETWORKS: + sb.append(" "); + sb.append(Integer.toString(msg.arg1)); + sb.append(" "); + sb.append(Integer.toString(msg.arg2)); + sb.append(" hasCarrierNetworks=").append(mWifiConfigManager.hasCarrierNetworks()); + break; case DhcpClient.CMD_PRE_DHCP_ACTION: sb.append(" "); sb.append(Integer.toString(msg.arg1)); @@ -4196,6 +4227,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss case CMD_GET_CONFIGURED_NETWORKS: replyToMessage(message, message.what, (List<WifiConfiguration>) null); break; + case CMD_HAS_CARRIER_CONFIGURED_NETWORKS: + replyToMessage(message, message.what, null); + break; case CMD_GET_PRIVILEGED_CONFIGURED_NETWORKS: replyToMessage(message, message.what, (List<WifiConfiguration>) null); break; @@ -4562,7 +4596,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss switch(message.what) { case WifiMonitor.SUP_CONNECTION_EVENT: if (DBG) log("Supplicant connection established"); - setWifiState(WIFI_STATE_ENABLED); + mSupplicantRestartCount = 0; /* Reset the supplicant state to indicate the supplicant * state is not known at this time */ @@ -4627,10 +4661,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss class SupplicantStartedState extends State { @Override public void enter() { - /* Wifi is available as long as we have a connection to supplicant */ - mNetworkInfo.setIsAvailable(true); - if (mNetworkAgent != null) mNetworkAgent.sendNetworkInfo(mNetworkInfo); - int defaultInterval = mContext.getResources().getInteger( R.integer.config_wifi_supplicant_scan_interval); @@ -5518,18 +5548,30 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss @Override public void enter() { + // Let the system know that wifi is enabled + setWifiState(WIFI_STATE_ENABLED); + + mNetworkInfo.setIsAvailable(true); + if (mNetworkAgent != null) mNetworkAgent.sendNetworkInfo(mNetworkInfo); + + // initialize network state + setNetworkDetailedState(DetailedState.DISCONNECTED); + // Inform WifiConnectivityManager that Wifi is enabled if (mWifiConnectivityManager != null) { mWifiConnectivityManager.setWifiEnabled(true); } // Inform metrics that Wifi is Enabled (but not yet connected) mWifiMetrics.setWifiState(WifiMetricsProto.WifiLog.WIFI_DISCONNECTED); - - } @Override public void exit() { + // Let the system know that wifi is not available since we are exiting client mode. + setWifiState(WIFI_STATE_DISABLED); + mNetworkInfo.setIsAvailable(false); + if (mNetworkAgent != null) mNetworkAgent.sendNetworkInfo(mNetworkInfo); + // Inform WifiConnectivityManager that Wifi is disabled if (mWifiConnectivityManager != null) { mWifiConnectivityManager.setWifiEnabled(false); @@ -5547,6 +5589,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss String bssid; String ssid; NetworkUpdateResult result; + Set<Integer> removedNetworkIds; logStateAndMessage(message, this); switch (message.what) { @@ -5830,6 +5873,10 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss replyToMessage(message, message.what, mWifiConfigManager.getSavedNetworks()); break; + case CMD_HAS_CARRIER_CONFIGURED_NETWORKS: + replyToMessage(message, message.what, + (Boolean)mWifiConfigManager.hasCarrierNetworks()); + break; case WifiMonitor.SUP_REQUEST_IDENTITY: int networkId = message.arg2; boolean identitySent = false; @@ -5843,8 +5890,10 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss // For SIM & AKA/AKA' EAP method Only, get identity from ICC if (targetWificonfiguration != null && targetWificonfiguration.networkId == networkId - && targetWificonfiguration.allowedKeyManagement + && (targetWificonfiguration.allowedKeyManagement .get(WifiConfiguration.KeyMgmt.IEEE8021X) + || targetWificonfiguration.allowedKeyManagement + .get(WifiConfiguration.KeyMgmt.WPA_EAP)) && TelephonyUtil.isSimEapMethod(eapMethod)) { String identity = TelephonyUtil.getSimIdentity(mContext, eapMethod); if (identity != null) { @@ -5994,7 +6043,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss //Determine if this CONNECTION is for a user selection if (mWifiConfigManager.isLastSelectedConfiguration(config) && mWifiConfigManager.isCurrentUserProfile( - UserHandle.getUserId(config.lastConnectUid))) { + UserHandle.getUserId(config.lastConnectUid))) { lastConnectUid = config.lastConnectUid; mWifiMetrics.setConnectionEventRoamType( WifiMetricsProto.ConnectionEvent.ROAM_USER_SELECTED); @@ -6039,10 +6088,22 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss } break; case CMD_REMOVE_APP_CONFIGURATIONS: - mWifiConfigManager.removeNetworksForApp((ApplicationInfo) message.obj); + removedNetworkIds = + mWifiConfigManager.removeNetworksForApp((ApplicationInfo) message.obj); + if (removedNetworkIds.contains(mTargetNetworkId) || + removedNetworkIds.contains(mLastNetworkId)) { + // Disconnect and let autojoin reselect a new network. + sendMessage(CMD_DISCONNECT); + } break; case CMD_REMOVE_USER_CONFIGURATIONS: - mWifiConfigManager.removeNetworksForUser(message.arg1); + removedNetworkIds = + mWifiConfigManager.removeNetworksForUser((Integer) message.arg1); + if (removedNetworkIds.contains(mTargetNetworkId) || + removedNetworkIds.contains(mLastNetworkId)) { + // Disconnect and let autojoin reselect a new network. + sendMessage(CMD_DISCONNECT); + } break; case WifiManager.CONNECT_NETWORK: // Only the current foreground user and System UI (which runs as user 0 but acts @@ -6473,7 +6534,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss private void updateCapabilities(WifiConfiguration config) { NetworkCapabilities networkCapabilities = new NetworkCapabilities(mDfltNetworkCapabilities); if (config != null) { - if (config.ephemeral) { + Log.d(TAG, "updateCapabilities for config:" + config.getPrintableSsid() + config.ephemeral + + "," + config.isCarrierNetwork); + if (config.ephemeral && !config.isCarrierNetwork) { networkCapabilities.removeCapability( NetworkCapabilities.NET_CAPABILITY_TRUSTED); } else { @@ -7460,6 +7523,10 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss break; } else { config = mWifiConfigManager.getWifiConfiguration(netId); + if (config == null) { + loge("AUTO_ROAM and invalid netowrk ID, bail out..."); + break; + } } setTargetBssid(config, bssid); 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 + "\""; + } } |