diff options
author | Roshan Pius <rpius@google.com> | 2016-08-26 17:54:29 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2016-08-26 17:54:29 +0000 |
commit | bb820957bbce91b24af6a2889039d4c77ab1cb30 (patch) | |
tree | b07468f8d5e9663b42b08c5031dbe5ba205f245f | |
parent | ac7f9b5a077ffced53d0615a25ea95d39a87c486 (diff) | |
parent | 55b645ab4d044fbe7e0aa1c8cbb9bfdb5c17ff1d (diff) |
Merge changes Ibf88ba16,Id7fe3439,Ia279a95a,I6e757ec2
* changes:
ScanResultUtil: Add a method to create ephemeral networks
WifiConfigManagerNew: Add couple of missing methods
WifiScoreReport: Refactor calculateScore
WifiInjector: Add WifiConfigManagerNew and dependencies.
8 files changed, 395 insertions, 120 deletions
diff --git a/service/java/com/android/server/wifi/WifiConfigManagerNew.java b/service/java/com/android/server/wifi/WifiConfigManagerNew.java index a302df39c..ebcddb59a 100644 --- a/service/java/com/android/server/wifi/WifiConfigManagerNew.java +++ b/service/java/com/android/server/wifi/WifiConfigManagerNew.java @@ -354,6 +354,23 @@ public class WifiConfigManagerNew { } /** + * Helper method to create a copy of the provided internal WifiConfiguration object to be + * passed to external modules. + * + * @param configuration provided WifiConfiguration object. + * @param maskPasswords Mask passwords or not. + * @return Copy of the WifiConfiguration object. + */ + private WifiConfiguration createExternalWifiConfiguration( + WifiConfiguration configuration, boolean maskPasswords) { + WifiConfiguration network = new WifiConfiguration(configuration); + if (maskPasswords) { + maskPasswordsInWifiConfiguration(network); + } + return network; + } + + /** * Fetch the list of currently configured networks maintained in WifiConfigManager. * * This retrieves a copy of the internal configurations maintained by WifiConfigManager and @@ -370,11 +387,7 @@ public class WifiConfigManagerNew { if (savedOnly && config.ephemeral) { continue; } - WifiConfiguration newConfig = new WifiConfiguration(config); - if (maskPasswords) { - maskPasswordsInWifiConfiguration(newConfig); - } - networks.add(newConfig); + networks.add(createExternalWifiConfiguration(config, maskPasswords)); } return networks; } @@ -424,9 +437,24 @@ public class WifiConfigManagerNew { } // Create a new configuration object with the passwords masked to send out to the external // world. - WifiConfiguration network = new WifiConfiguration(config); - maskPasswordsInWifiConfiguration(network); - return network; + return createExternalWifiConfiguration(config, true); + } + + /** + * Retrieves the configured network corresponding to the provided config key with password + * masked. + * + * @param configKey configKey of the requested network. + * @return WifiConfiguration object if found, null otherwise. + */ + public WifiConfiguration getConfiguredNetwork(String configKey) { + WifiConfiguration config = getInternalConfiguredNetwork(configKey); + if (config == null) { + return null; + } + // Create a new configuration object with the passwords masked to send out to the external + // world. + return createExternalWifiConfiguration(config, true); } /** @@ -446,8 +474,7 @@ public class WifiConfigManagerNew { } // Create a new configuration object without the passwords masked to send out to the // external world. - WifiConfiguration network = new WifiConfiguration(config); - return network; + return createExternalWifiConfiguration(config, false); } /** @@ -744,7 +771,6 @@ public class WifiConfigManagerNew { */ private void setDefaultsInWifiConfiguration(WifiConfiguration configuration) { configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); - configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED); configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN); configuration.allowedProtocols.set(WifiConfiguration.Protocol.WPA); @@ -1345,8 +1371,8 @@ public class WifiConfigManagerNew { * {@link NetworkSelectionStatus#mCandidateScore} & * {@link NetworkSelectionStatus#mSeenInLastQualifiedNetworkSelection} for the provided network. * - * This is invoked by Network Selector when it sees a network during network selection procedure to set the - * scan result candidate. + * This is invoked by Network Selector when it sees a network during network selection procedure + * to set the scan result candidate. * * @param networkId network ID corresponding to the network. * @param scanResult Candidate ScanResult associated with this network. @@ -1366,6 +1392,48 @@ public class WifiConfigManagerNew { } /** + * Helper method to clear the {@link NetworkSelectionStatus#mConnectChoice} & + * {@link NetworkSelectionStatus#mConnectChoiceTimestamp} for the provided network. + * + * @param networkId network ID corresponding to the network. + * @return true if the network was found, false otherwise. + */ + public boolean clearNetworkConnectChoice(int networkId) { + WifiConfiguration config = getInternalConfiguredNetwork(networkId); + if (config == null) { + return false; + } + config.getNetworkSelectionStatus().setConnectChoice(null); + config.getNetworkSelectionStatus().setConnectChoiceTimestamp( + NetworkSelectionStatus.INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP); + return true; + } + + /** + * Helper method to set the {@link NetworkSelectionStatus#mConnectChoice} & + * {@link NetworkSelectionStatus#mConnectChoiceTimestamp} for the provided network. + * + * This is invoked by Network Selector when the user overrides the currently connected network + * choice. + * + * @param networkId network ID corresponding to the network. + * @param connectChoiceConfigKey ConfigKey corresponding to the network which was chosen over + * this network. + * @param timestamp timestamp at which the choice was made. + * @return true if the network was found, false otherwise. + */ + public boolean setNetworkConnectChoice( + int networkId, String connectChoiceConfigKey, long timestamp) { + WifiConfiguration config = getInternalConfiguredNetwork(networkId); + if (config == null) { + return false; + } + config.getNetworkSelectionStatus().setConnectChoice(connectChoiceConfigKey); + config.getNetworkSelectionStatus().setConnectChoiceTimestamp(timestamp); + return true; + } + + /** * Helper method to clear out the {@link #mLastNetworkId} user/app network selection. This * is done when either the corresponding network is either removed or disabled. */ @@ -1492,13 +1560,8 @@ public class WifiConfigManagerNew { Log.e(TAG, "No scan result found in scan detail"); return null; } - // Add the double quotes to the scan result SSID for comparison with the network configs. - String ssidToCompare = "\"" + scanResult.SSID + "\""; for (WifiConfiguration config : getInternalConfiguredNetworks()) { - if (config.SSID == null || !config.SSID.equals(ssidToCompare)) { - continue; - } - if (ScanResultUtil.doesScanResultEncryptionMatchWithNetwork(scanResult, config)) { + if (ScanResultUtil.doesScanResultMatchWithNetwork(scanResult, config)) { localLog("getSavedNetworkFromScanDetail: Found " + config.configKey() + " for " + scanResult.SSID + "[" + scanResult.capabilities + "]"); return config; @@ -1819,6 +1882,16 @@ public class WifiConfigManagerNew { } /** + * Check if the provided ephemeral network was deleted by the user or not. + * + * @param ssid ssid of the network + * @return true if network was deleted, false otherwise. + */ + public boolean wasEphemeralNetworkDeleted(String ssid) { + return mDeletedEphemeralSSIDs.contains(ssid); + } + + /** * Helper method to clear internal databases. * This method clears the: * - List of configured networks. diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java index 971e69e9c..b26f1c5f2 100644 --- a/service/java/com/android/server/wifi/WifiInjector.java +++ b/service/java/com/android/server/wifi/WifiInjector.java @@ -25,6 +25,7 @@ import android.os.IBinder; import android.os.INetworkManagementService; import android.os.ServiceManager; import android.os.SystemProperties; +import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.security.KeyStore; @@ -32,6 +33,8 @@ import android.telephony.TelephonyManager; import com.android.internal.R; import com.android.server.am.BatteryStatsService; +import com.android.server.net.DelayedDiskWrite; +import com.android.server.net.IpConfigStore; import java.util.ArrayList; @@ -56,6 +59,7 @@ public class WifiInjector { private final WifiTrafficPoller mTrafficPoller; private final WifiCountryCode mCountryCode; private final BackupManagerProxy mBackupManagerProxy = new BackupManagerProxy(); + private final WifiNative mWifiNative; private final WifiStateMachine mWifiStateMachine; private final WifiSettingsStore mSettingsStore; private final WifiCertManager mCertManager; @@ -70,6 +74,14 @@ public class WifiInjector { private final KeyStore mKeyStore = KeyStore.getInstance(); private final WifiBackupRestore mWifiBackupRestore = new WifiBackupRestore(); private final WifiMulticastLockManager mWifiMulticastLockManager; + private final WifiConfigStoreNew mWifiConfigStore; + private final WifiKeyStore mWifiKeyStore; + private final WifiNetworkHistory mWifiNetworkHistory; + private final WifiSupplicantControl mWifiSupplicantControl; + private final IpConfigStore mIpConfigStore; + private final WifiConfigStoreLegacy mWifiConfigStoreLegacy; + private final WifiConfigManagerNew mWifiConfigManager; + private final boolean mUseRealLogger; public WifiInjector(Context context) { @@ -103,9 +115,10 @@ public class WifiInjector { mFrameworkFacade.getStringSetting(mContext, Settings.Global.WIFI_COUNTRY_CODE), mContext.getResources() .getBoolean(R.bool.config_wifi_revert_country_code_on_cellular_loss)); + mWifiNative = WifiNative.getWlanNativeInterface(); mWifiStateMachine = new WifiStateMachine(mContext, mFrameworkFacade, mWifiStateMachineHandlerThread.getLooper(), UserManager.get(mContext), - this, mBackupManagerProxy, mCountryCode); + this, mBackupManagerProxy, mCountryCode, mWifiNative); mSettingsStore = new WifiSettingsStore(mContext); mCertManager = new WifiCertManager(mContext); mNotificationController = new WifiNotificationController(mContext, @@ -117,6 +130,25 @@ public class WifiInjector { mWifiLastResortWatchdog = new WifiLastResortWatchdog(mWifiController, mWifiMetrics); mWifiMulticastLockManager = new WifiMulticastLockManager(mWifiStateMachine, BatteryStatsService.getService()); + + // WifiConfigManager/Store objects and their dependencies. + // New config store + mWifiConfigStore = new WifiConfigStoreNew(mContext, + mWifiStateMachineHandlerThread.getLooper(), mClock, + WifiConfigStoreNew.createSharedFile(), + WifiConfigStoreNew.createUserFile(UserHandle.USER_SYSTEM)); + mWifiKeyStore = new WifiKeyStore(mKeyStore); + // Legacy config store + DelayedDiskWrite writer = new DelayedDiskWrite(); + mWifiNetworkHistory = new WifiNetworkHistory(mContext, mWifiNative.getLocalLog(), writer); + mWifiSupplicantControl = new WifiSupplicantControl( + TelephonyManager.from(mContext), mWifiNative, mWifiNative.getLocalLog()); + mIpConfigStore = new IpConfigStore(writer); + mWifiConfigStoreLegacy = new WifiConfigStoreLegacy( + mWifiNetworkHistory, mWifiSupplicantControl, mIpConfigStore); + // Config Manager + mWifiConfigManager = new WifiConfigManagerNew(mContext, mFrameworkFacade, mClock, + UserManager.get(mContext), mWifiKeyStore, mWifiConfigStore, mWifiConfigStoreLegacy); } /** @@ -213,6 +245,14 @@ public class WifiInjector { return mWifiMulticastLockManager; } + public WifiSupplicantControl getWifiSupplicantControl() { + return mWifiSupplicantControl; + } + + public WifiConfigManagerNew getWifiConfigManager() { + return mWifiConfigManager; + } + public TelephonyManager makeTelephonyManager() { // may not be available when WiFi starts return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); diff --git a/service/java/com/android/server/wifi/WifiScoreReport.java b/service/java/com/android/server/wifi/WifiScoreReport.java index dfdf3cda6..f866436ca 100644 --- a/service/java/com/android/server/wifi/WifiScoreReport.java +++ b/service/java/com/android/server/wifi/WifiScoreReport.java @@ -16,14 +16,18 @@ package com.android.server.wifi; +import android.content.Context; import android.net.NetworkAgent; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.util.Log; +import com.android.internal.R; /** -* Calculate scores for connected wifi networks. + * Class used to calculate scores for connected wifi networks and report it to the associated + * network agent. + * TODO: Add unit tests for this class. */ public class WifiScoreReport { // TODO: switch to WifiScoreReport if it doesn't break any tools @@ -52,68 +56,125 @@ public class WifiScoreReport { private static final int BAD_LINKSPEED_PENALTY = 4; private static final int GOOD_LINKSPEED_BONUS = 4; - + // Device configs. + private final int mThresholdMinimumRssi5; + private final int mThresholdQualifiedRssi5; + private final int mThresholdSaturatedRssi5; + private final int mThresholdMinimumRssi24; + private final int mThresholdQualifiedRssi24; + private final int mThresholdSaturatedRssi24; + private final int mBadLinkSpeed24; + private final int mBadLinkSpeed5; + private final int mGoodLinkSpeed24; + private final int mGoodLinkSpeed5; + private final boolean mEnableWifiCellularHandoverUserTriggeredAdjustment; + + private final WifiConfigManager mWifiConfigManager; + private boolean mVerboseLoggingEnabled = false; + + // Cache of the last score report. private String mReport; - private int mBadLinkspeedcount; - - WifiScoreReport(String report, int badLinkspeedcount) { - mReport = report; - mBadLinkspeedcount = badLinkspeedcount; + private int mBadLinkspeedcount = 0; + private boolean mReportValid = false; + + WifiScoreReport(Context context, WifiConfigManager wifiConfigManager) { + // Fetch all the device configs. + mThresholdMinimumRssi5 = context.getResources().getInteger( + R.integer.config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz); + mThresholdQualifiedRssi5 = context.getResources().getInteger( + R.integer.config_wifi_framework_wifi_score_low_rssi_threshold_5GHz); + mThresholdSaturatedRssi5 = context.getResources().getInteger( + R.integer.config_wifi_framework_wifi_score_good_rssi_threshold_5GHz); + mThresholdMinimumRssi24 = context.getResources().getInteger( + R.integer.config_wifi_framework_wifi_score_bad_rssi_threshold_24GHz); + mThresholdQualifiedRssi24 = context.getResources().getInteger( + R.integer.config_wifi_framework_wifi_score_low_rssi_threshold_24GHz); + mThresholdSaturatedRssi24 = context.getResources().getInteger( + R.integer.config_wifi_framework_wifi_score_good_rssi_threshold_24GHz); + mBadLinkSpeed24 = context.getResources().getInteger( + R.integer.config_wifi_framework_wifi_score_bad_link_speed_24); + mBadLinkSpeed5 = context.getResources().getInteger( + R.integer.config_wifi_framework_wifi_score_bad_link_speed_5); + mGoodLinkSpeed24 = context.getResources().getInteger( + R.integer.config_wifi_framework_wifi_score_good_link_speed_24); + mGoodLinkSpeed5 = context.getResources().getInteger( + R.integer.config_wifi_framework_wifi_score_good_link_speed_5); + mEnableWifiCellularHandoverUserTriggeredAdjustment = context.getResources().getBoolean( + R.bool.config_wifi_framework_cellular_handover_enable_user_triggered_adjustment); + + mWifiConfigManager = wifiConfigManager; } /** - * Method returning the String representation of the score report. + * Method returning the String representation of the last score report. * * @return String score report */ - public String getReport() { + public String getLastReport() { return mReport; } /** - * Method returning the bad link speed count at the time of the current score report. + * Method returning the bad link speed count at the time of the last score report. * * @return int bad linkspeed count */ - public int getBadLinkspeedcount() { + public int getLastBadLinkspeedcount() { return mBadLinkspeedcount; } /** - * Calculate wifi network score based on updated link layer stats and return a new - * WifiScoreReport object. + * Reset the last calculated score. + */ + public void reset() { + mBadLinkspeedcount = 0; + mReport = ""; + mReportValid = false; + } + + /** + * Checks if the last report data is valid or not. This will be cleared when {@link #reset()} is + * invoked. + * + * @return true if valid, false otherwise. + */ + public boolean isLastReportValid() { + return mReportValid; + } + + /** + * Enable/Disable verbose logging in score report generation. + */ + public void enableVerboseLogging(boolean enable) { + mVerboseLoggingEnabled = enable; + } + + /** + * Calculate wifi network score based on updated link layer stats and send the score to provided + * network agent. * * If the score has changed from the previous value, update the WifiNetworkAgent. - * @param wifiInfo WifiInfo information about current network connection - * @param currentConfiguration WifiConfiguration current wifi config - * @param wifiConfigManager WifiConfigManager Object holding current config state - * @param networkAgent NetworkAgent to be notified of new score - * @param lastReport String most recent score report - * @param aggressiveHandover int current aggressiveHandover setting - * @return WifiScoreReport Wifi Score report + * @param wifiInfo WifiInfo instance pointing to the currently connected network. + * @param networkAgent NetworkAgent to be notified of new score. + * @param aggressiveHandover int current aggressiveHandover setting. */ - public static WifiScoreReport calculateScore(WifiInfo wifiInfo, - WifiConfiguration currentConfiguration, - WifiConfigManager wifiConfigManager, - NetworkAgent networkAgent, - WifiScoreReport lastReport, - int aggressiveHandover, - boolean verboseLogging) { + public void calculateAndReportScore( + WifiInfo wifiInfo, NetworkAgent networkAgent, int aggressiveHandover) { StringBuilder sb = new StringBuilder(); int score = STARTING_SCORE; boolean isBadLinkspeed = (wifiInfo.is24GHz() - && wifiInfo.getLinkSpeed() < wifiConfigManager.mBadLinkSpeed24) + && wifiInfo.getLinkSpeed() < mBadLinkSpeed24) || (wifiInfo.is5GHz() && wifiInfo.getLinkSpeed() - < wifiConfigManager.mBadLinkSpeed5); + < mBadLinkSpeed5); boolean isGoodLinkspeed = (wifiInfo.is24GHz() - && wifiInfo.getLinkSpeed() >= wifiConfigManager.mGoodLinkSpeed24) + && wifiInfo.getLinkSpeed() >= mGoodLinkSpeed24) || (wifiInfo.is5GHz() && wifiInfo.getLinkSpeed() - >= wifiConfigManager.mGoodLinkSpeed5); + >= mGoodLinkSpeed5); int badLinkspeedcount = 0; - if (lastReport != null) { - badLinkspeedcount = lastReport.getBadLinkspeedcount(); + if (mReportValid) { + badLinkspeedcount = mBadLinkspeedcount; } if (isBadLinkspeed) { @@ -129,18 +190,19 @@ public class WifiScoreReport { if (isBadLinkspeed) sb.append(" bl(").append(badLinkspeedcount).append(")"); if (isGoodLinkspeed) sb.append(" gl"); + WifiConfiguration currentConfiguration = + mWifiConfigManager.getWifiConfiguration(wifiInfo.getNetworkId()); + ScanDetailCache scanDetailCache = + mWifiConfigManager.getScanDetailCache(currentConfiguration); /** * We want to make sure that we use the 24GHz RSSI thresholds if - * there are 2.4GHz scan results - * otherwise we end up lowering the score based on 5GHz values + * there are 2.4GHz scan results otherwise we end up lowering the score based on 5GHz values * which may cause a switch to LTE before roaming has a chance to try 2.4GHz * We also might unblacklist the configuation based on 2.4GHz * thresholds but joining 5GHz anyhow, and failing over to 2.4GHz because 5GHz is not good */ boolean use24Thresholds = false; boolean homeNetworkBoost = false; - ScanDetailCache scanDetailCache = - wifiConfigManager.getScanDetailCache(currentConfiguration); if (currentConfiguration != null && scanDetailCache != null) { currentConfiguration.setVisibility( scanDetailCache.getVisibility(SCAN_CACHE_VISIBILITY_MS)); @@ -169,14 +231,14 @@ public class WifiScoreReport { boolean is24GHz = use24Thresholds || wifiInfo.is24GHz(); - boolean isBadRSSI = (is24GHz && rssi < wifiConfigManager.mThresholdMinimumRssi24.get()) - || (!is24GHz && rssi < wifiConfigManager.mThresholdMinimumRssi5.get()); - boolean isLowRSSI = (is24GHz && rssi < wifiConfigManager.mThresholdQualifiedRssi24.get()) + boolean isBadRSSI = (is24GHz && rssi < mThresholdMinimumRssi24) + || (!is24GHz && rssi < mThresholdMinimumRssi5); + boolean isLowRSSI = (is24GHz && rssi < mThresholdQualifiedRssi24) || (!is24GHz - && wifiInfo.getRssi() < wifiConfigManager.mThresholdMinimumRssi5.get()); - boolean isHighRSSI = (is24GHz && rssi >= wifiConfigManager.mThresholdSaturatedRssi24.get()) + && wifiInfo.getRssi() < mThresholdMinimumRssi5); + boolean isHighRSSI = (is24GHz && rssi >= mThresholdSaturatedRssi24) || (!is24GHz - && wifiInfo.getRssi() >= wifiConfigManager.mThresholdSaturatedRssi5.get()); + && wifiInfo.getRssi() >= mThresholdSaturatedRssi5); if (isBadRSSI) sb.append(" br"); if (isLowRSSI) sb.append(" lr"); @@ -202,7 +264,7 @@ public class WifiScoreReport { } currentConfiguration.numTicksAtBadRSSI = 0; } - if (wifiConfigManager.mEnableWifiCellularHandoverUserTriggeredAdjustment + if (mEnableWifiCellularHandoverUserTriggeredAdjustment && (currentConfiguration.numUserTriggeredWifiDisableBadRSSI > 0 || currentConfiguration.numUserTriggeredWifiDisableLowRSSI > 0 || currentConfiguration @@ -224,7 +286,7 @@ public class WifiScoreReport { } currentConfiguration.numTicksAtLowRSSI = 0; } - if (wifiConfigManager.mEnableWifiCellularHandoverUserTriggeredAdjustment + if (mEnableWifiCellularHandoverUserTriggeredAdjustment && (currentConfiguration.numUserTriggeredWifiDisableLowRSSI > 0 || currentConfiguration .numUserTriggeredWifiDisableNotHighRSSI > 0)) { @@ -242,7 +304,7 @@ public class WifiScoreReport { } currentConfiguration.numTicksAtNotHighRSSI = 0; } - if (wifiConfigManager.mEnableWifiCellularHandoverUserTriggeredAdjustment + if (mEnableWifiCellularHandoverUserTriggeredAdjustment && currentConfiguration.numUserTriggeredWifiDisableNotHighRSSI > 0) { score = score - USER_DISCONNECT_PENALTY; penalizedDueToUserTriggeredDisconnect = 3; @@ -254,7 +316,7 @@ public class WifiScoreReport { currentConfiguration.numTicksAtNotHighRSSI)); } - if (verboseLogging) { + if (mVerboseLoggingEnabled) { String rssiStatus = ""; if (isBadRSSI) { rssiStatus += " badRSSI "; @@ -275,14 +337,15 @@ public class WifiScoreReport { + " userTriggerdPenalty" + penalizedDueToUserTriggeredDisconnect); } - if ((wifiInfo.txBadRate >= 1) && (wifiInfo.txSuccessRate < MAX_SUCCESS_COUNT_OF_STUCK_LINK) + if ((wifiInfo.txBadRate >= 1) + && (wifiInfo.txSuccessRate < MAX_SUCCESS_COUNT_OF_STUCK_LINK) && (isBadRSSI || isLowRSSI)) { // Link is stuck if (wifiInfo.linkStuckCount < MAX_STUCK_LINK_COUNT) { wifiInfo.linkStuckCount += 1; } sb.append(String.format(" ls+=%d", wifiInfo.linkStuckCount)); - if (verboseLogging) { + if (mVerboseLoggingEnabled) { Log.d(TAG, " bad link -> stuck count =" + Integer.toString(wifiInfo.linkStuckCount)); } @@ -291,7 +354,7 @@ public class WifiScoreReport { wifiInfo.linkStuckCount -= 1; } sb.append(String.format(" ls-=%d", wifiInfo.linkStuckCount)); - if (verboseLogging) { + if (mVerboseLoggingEnabled) { Log.d(TAG, " good link -> stuck count =" + Integer.toString(wifiInfo.linkStuckCount)); } @@ -307,8 +370,8 @@ public class WifiScoreReport { if (isBadLinkspeed) { score -= BAD_LINKSPEED_PENALTY; - if (verboseLogging) { - Log.d(TAG, " isBadLinkspeed ---> count=" + badLinkspeedcount + if (mVerboseLoggingEnabled) { + Log.d(TAG, " isBadLinkspeed ---> count=" + mBadLinkspeedcount + " score=" + Integer.toString(score)); } } else if ((isGoodLinkspeed) && (wifiInfo.txSuccessRate > 5)) { @@ -334,7 +397,7 @@ public class WifiScoreReport { score -= wifiInfo.badRssiCount * BAD_RSSI_COUNT_PENALTY + wifiInfo.lowRssiCount; sb.append(String.format(",%d", score)); - if (verboseLogging) { + if (mVerboseLoggingEnabled) { Log.d(TAG, " badRSSI count" + Integer.toString(wifiInfo.badRssiCount) + " lowRSSI count" + Integer.toString(wifiInfo.lowRssiCount) + " --> score " + Integer.toString(score)); @@ -342,7 +405,7 @@ public class WifiScoreReport { if (isHighRSSI) { score += 5; - if (verboseLogging) Log.d(TAG, " isHighRSSI ---> score=" + score); + if (mVerboseLoggingEnabled) Log.d(TAG, " isHighRSSI ---> score=" + score); } sb.append(String.format(",%d]", score)); @@ -358,7 +421,7 @@ public class WifiScoreReport { //report score if (score != wifiInfo.score) { - if (verboseLogging) { + if (mVerboseLoggingEnabled) { Log.d(TAG, "calculateWifiScore() report new score " + Integer.toString(score)); } wifiInfo.score = score; @@ -366,6 +429,9 @@ public class WifiScoreReport { networkAgent.sendNetworkScore(score); } } - return new WifiScoreReport(sb.toString(), badLinkspeedcount); + + mBadLinkspeedcount = badLinkspeedcount; + mReport = sb.toString(); + mReportValid = true; } } diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 47dca18d1..320fc4aab 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -209,6 +209,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss private final PropertyService mPropertyService; private final BuildProperties mBuildProperties; private final WifiCountryCode mCountryCode; + // Object holding most recent wifi score report and bad Linkspeed count + private final WifiScoreReport mWifiScoreReport; /* Scan results handling */ private List<ScanDetail> mScanResults = new ArrayList<>(); @@ -934,8 +936,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss public WifiStateMachine(Context context, FrameworkFacade facade, Looper looper, UserManager userManager, WifiInjector wifiInjector, - BackupManagerProxy backupManagerProxy, - WifiCountryCode countryCode) { + BackupManagerProxy backupManagerProxy, WifiCountryCode countryCode, + WifiNative wifiNative) { super("WifiStateMachine", looper); mWifiInjector = wifiInjector; mWifiMetrics = mWifiInjector.getWifiMetrics(); @@ -944,7 +946,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss mBuildProperties = wifiInjector.getBuildProperties(); mContext = context; mFacade = facade; - mWifiNative = WifiNative.getWlanNativeInterface(); + mWifiNative = wifiNative; mBackupManagerProxy = backupManagerProxy; // TODO refactor WifiNative use of context out into it's own class @@ -1003,6 +1005,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss mCountryCode = countryCode; + mWifiScoreReport = new WifiScoreReport(mContext, mWifiConfigManager); + mUserWantsSuspendOpt.set(mFacade.getIntegerSetting(mContext, Settings.Global.WIFI_SUSPEND_OPTIMIZATIONS_ENABLED, 1) == 1); @@ -1231,6 +1235,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss configureVerboseHalLogging(mVerboseLoggingEnabled); setSupplicantLogLevel(); mCountryCode.enableVerboseLogging(verbose); + mWifiScoreReport.enableVerboseLogging(mVerboseLoggingEnabled); mWifiDiagnostics.startLogging(mVerboseLoggingEnabled); mWifiMonitor.enableVerboseLogging(verbose); mWifiNative.enableVerboseLogging(verbose); @@ -2499,8 +2504,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss if (report != null) { sb.append(" ").append(report); } - if (mWifiScoreReport != null) { - sb.append(mWifiScoreReport.getReport()); + if (mWifiScoreReport.isLastReportValid()) { + sb.append(mWifiScoreReport.getLastReport()); } break; case CMD_AUTO_CONNECT: @@ -3039,12 +3044,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss mWifiInfo.txSuccessRate = 0; mWifiInfo.txRetriesRate = 0; mWifiInfo.rxSuccessRate = 0; - mWifiScoreReport = null; + mWifiScoreReport.reset(); } - // Object holding most recent wifi score report and bad Linkspeed count - WifiScoreReport mWifiScoreReport = null; - public double getTxPacketRate() { return mWifiInfo.txSuccessRate; } @@ -3355,7 +3357,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss stopIpManager(); /* Reset data structures */ - mWifiScoreReport = null; + mWifiScoreReport.reset(); mWifiInfo.reset(); mIsLinkDebouncing = false; /* Reset roaming parameters */ @@ -4879,7 +4881,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss networkSelectionStatus.setHasEverConnected(true); } // On connect, reset wifiScoreReport - mWifiScoreReport = null; + mWifiScoreReport.reset(); } } @@ -6291,14 +6293,12 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss } // Get Info and continue polling fetchRssiLinkSpeedAndFrequencyNative(); - mWifiScoreReport = - WifiScoreReport.calculateScore(mWifiInfo, - getCurrentWifiConfiguration(), - mWifiConfigManager, - mNetworkAgent, - mWifiScoreReport, - mAggressiveHandover, - mVerboseLoggingEnabled); + // Send the update score to network agent. + WifiConfiguration config = getCurrentWifiConfiguration(); + ScanDetailCache scanDetailCache = + mWifiConfigManager.getScanDetailCache(config); + mWifiScoreReport.calculateAndReportScore( + mWifiInfo, mNetworkAgent, mAggressiveHandover); } sendMessageDelayed(obtainMessage(CMD_RSSI_POLL, mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS); diff --git a/service/java/com/android/server/wifi/util/ScanResultUtil.java b/service/java/com/android/server/wifi/util/ScanResultUtil.java index 3f1e98f11..6bf492615 100644 --- a/service/java/com/android/server/wifi/util/ScanResultUtil.java +++ b/service/java/com/android/server/wifi/util/ScanResultUtil.java @@ -18,7 +18,9 @@ package com.android.server.wifi.util; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; +import android.text.TextUtils; +import com.android.internal.annotations.VisibleForTesting; import com.android.server.wifi.ScanDetail; import com.android.server.wifi.WifiConfigurationUtil; import com.android.server.wifi.hotspot2.NetworkDetail; @@ -78,28 +80,63 @@ public class ScanResultUtil { } /** - * Helper method to check if the provided |scanResult| and |config| have the same - * encryption type. + * Helper method to quote the SSID in Scan result to use for comparing/filling SSID stored in + * WifiConfiguration object. */ - public static boolean doesScanResultEncryptionMatchWithNetwork( + @VisibleForTesting + public static String createQuotedSSID(String ssid) { + return "\"" + ssid + "\""; + } + + /** + * Checks if the provided |scanResult| match with the provided |config|. Essentially checks + * if the network config and scan result have the same SSID and encryption type. + */ + public static boolean doesScanResultMatchWithNetwork( ScanResult scanResult, WifiConfiguration config) { - if (ScanResultUtil.isScanResultForPskNetwork(scanResult) - && WifiConfigurationUtil.isConfigForPskNetwork(config)) { - return true; - } - if (ScanResultUtil.isScanResultForEapNetwork(scanResult) - && WifiConfigurationUtil.isConfigForEapNetwork(config)) { - return true; - } - if (ScanResultUtil.isScanResultForWepNetwork(scanResult) - && WifiConfigurationUtil.isConfigForWepNetwork(config)) { - return true; - } - if (ScanResultUtil.isScanResultForOpenNetwork(scanResult) - && WifiConfigurationUtil.isConfigForOpenNetwork(config)) { - return true; + // Add the double quotes to the scan result SSID for comparison with the network configs. + String configSSID = createQuotedSSID(scanResult.SSID); + if (TextUtils.equals(config.SSID, configSSID)) { + if (ScanResultUtil.isScanResultForPskNetwork(scanResult) + && WifiConfigurationUtil.isConfigForPskNetwork(config)) { + return true; + } + if (ScanResultUtil.isScanResultForEapNetwork(scanResult) + && WifiConfigurationUtil.isConfigForEapNetwork(config)) { + return true; + } + if (ScanResultUtil.isScanResultForWepNetwork(scanResult) + && WifiConfigurationUtil.isConfigForWepNetwork(config)) { + return true; + } + if (ScanResultUtil.isScanResultForOpenNetwork(scanResult) + && WifiConfigurationUtil.isConfigForOpenNetwork(config)) { + return true; + } } return false; } + /** + * Creates a network configuration object using the provided |scanResult|. + * This is used to create ephemeral network configurations. + */ + public static WifiConfiguration createNetworkFromScanResult(ScanResult scanResult) { + WifiConfiguration config = new WifiConfiguration(); + config.SSID = createQuotedSSID(scanResult.SSID); + if (isScanResultForPskNetwork(scanResult)) { + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); + } else if (isScanResultForEapNetwork(scanResult)) { + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP); + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X); + } else if (isScanResultForWepNetwork(scanResult)) { + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); + config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); + config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED); + } else { + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); + } + return config; + } + } diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerNewTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerNewTest.java index 43c446900..ab5da2dff 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerNewTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerNewTest.java @@ -52,6 +52,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; +import java.util.Set; /** * Unit tests for {@link com.android.server.wifi.WifiConfigManagerNew}. @@ -1809,8 +1810,10 @@ public class WifiConfigManagerNewTest { networks.add(WifiConfigurationTestUtil.createPskNetwork()); networks.add(WifiConfigurationTestUtil.createEapNetwork()); networks.add(WifiConfigurationTestUtil.createWepNetwork()); + String deletedEphemeralSSID = "EphemeralSSID"; + Set<String> deletedEphermalSSIDs = new HashSet<>(Arrays.asList(deletedEphemeralSSID)); WifiConfigStoreDataLegacy storeData = - new WifiConfigStoreDataLegacy(networks, new HashSet<String>()); + new WifiConfigStoreDataLegacy(networks, deletedEphermalSSIDs); // New store files not present, so migrate from the old store. when(mWifiConfigStore.areStoresPresent()).thenReturn(false); @@ -1828,6 +1831,7 @@ public class WifiConfigManagerNewTest { mWifiConfigManager.getConfiguredNetworksWithPasswords(); WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate( networks, retrievedNetworks); + assertTrue(mWifiConfigManager.wasEphemeralNetworkDeleted(deletedEphemeralSSID)); } /** @@ -1899,7 +1903,6 @@ public class WifiConfigManagerNewTest { private void setDefaults(WifiConfiguration configuration) { if (configuration.allowedAuthAlgorithms.isEmpty()) { configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); - configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED); } if (configuration.allowedProtocols.isEmpty()) { configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN); diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java index ac879f9b3..1ad5fabf0 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java @@ -344,7 +344,6 @@ public class WifiStateMachineTest { /** uncomment this to enable logs from WifiStateMachines */ // enableDebugLogs(); - TestUtil.installWlanWifiNative(mWifiNative); mWifiMonitor = new MockWifiMonitor(); when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics); when(mWifiInjector.getClock()).thenReturn(mock(Clock.class)); @@ -356,6 +355,7 @@ public class WifiStateMachineTest { when(mWifiInjector.makeWifiDiagnostics(anyObject())).thenReturn( mock(BaseWifiDiagnostics.class)); when(mWifiInjector.makeWificond()).thenReturn(mWificond); + when(mWifiNative.getInterfaceName()).thenReturn("mockWlan"); FrameworkFacade factory = getFrameworkFacade(); Context context = getContext(); @@ -387,7 +387,7 @@ public class WifiStateMachineTest { when(mClientInterface.disableSupplicant()).thenReturn(true); mWsm = new WifiStateMachine(context, factory, mLooper.getLooper(), - mUserManager, mWifiInjector, mBackupManagerProxy, mCountryCode); + mUserManager, mWifiInjector, mBackupManagerProxy, mCountryCode, mWifiNative); mWsmThread = getWsmHandlerThread(mWsm); final AsyncChannel channel = new AsyncChannel(); diff --git a/tests/wifitests/src/com/android/server/wifi/util/ScanResultUtilTest.java b/tests/wifitests/src/com/android/server/wifi/util/ScanResultUtilTest.java index 275a40bcb..7b0369874 100644 --- a/tests/wifitests/src/com/android/server/wifi/util/ScanResultUtilTest.java +++ b/tests/wifitests/src/com/android/server/wifi/util/ScanResultUtilTest.java @@ -16,12 +16,11 @@ package com.android.server.wifi.util; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.*; import android.net.wifi.ScanResult; import android.net.wifi.ScanResult.InformationElement; +import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiSsid; import android.test.suitebuilder.annotation.SmallTest; @@ -85,6 +84,63 @@ public class ScanResultUtilTest { validateScanDetail(input, output); } + @Test + public void testScanResultMatchingWithNetwork() { + final String ssid = "Another SSid"; + WifiConfiguration config = new WifiConfiguration(); + config.SSID = ScanResultUtil.createQuotedSSID(ssid); + ScanResult scanResult = new ScanResult(ssid, "ab:cd:01:ef:45:89", 1245, 0, "", + -78, 2450, 1025, 22, 33, 20, 0, 0, true); + + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); + scanResult.capabilities = ""; + assertTrue(ScanResultUtil.doesScanResultMatchWithNetwork(scanResult, config)); + + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); + config.wepKeys[0] = "45592364648547"; + scanResult.capabilities = "WEP"; + assertTrue(ScanResultUtil.doesScanResultMatchWithNetwork(scanResult, config)); + + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); + scanResult.capabilities = "PSK"; + assertTrue(ScanResultUtil.doesScanResultMatchWithNetwork(scanResult, config)); + + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP); + scanResult.capabilities = "EAP"; + assertTrue(ScanResultUtil.doesScanResultMatchWithNetwork(scanResult, config)); + } + + @Test + public void testNetworkCreationFromScanResult() { + final String ssid = "Another SSid"; + ScanResult scanResult = new ScanResult(ssid, "ab:cd:01:ef:45:89", 1245, 0, "", + -78, 2450, 1025, 22, 33, 20, 0, 0, true); + WifiConfiguration config; + + scanResult.capabilities = ""; + config = ScanResultUtil.createNetworkFromScanResult(scanResult); + assertEquals(config.SSID, ScanResultUtil.createQuotedSSID(ssid)); + assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)); + + scanResult.capabilities = "WEP"; + config = ScanResultUtil.createNetworkFromScanResult(scanResult); + assertEquals(config.SSID, ScanResultUtil.createQuotedSSID(ssid)); + assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)); + assertTrue(config.allowedAuthAlgorithms.get(WifiConfiguration.AuthAlgorithm.OPEN)); + assertTrue(config.allowedAuthAlgorithms.get(WifiConfiguration.AuthAlgorithm.SHARED)); + + scanResult.capabilities = "PSK"; + config = ScanResultUtil.createNetworkFromScanResult(scanResult); + assertEquals(config.SSID, ScanResultUtil.createQuotedSSID(ssid)); + assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)); + + scanResult.capabilities = "EAP"; + config = ScanResultUtil.createNetworkFromScanResult(scanResult); + assertEquals(config.SSID, ScanResultUtil.createQuotedSSID(ssid)); + assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP)); + assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X)); + } + private static InformationElement createIE(int id, byte[] bytes) { InformationElement ie = new InformationElement(); ie.id = id; |