diff options
Diffstat (limited to 'service')
5 files changed, 945 insertions, 857 deletions
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java index eca50d220..799ceb018 100644 --- a/service/java/com/android/server/wifi/WifiConfigManager.java +++ b/service/java/com/android/server/wifi/WifiConfigManager.java @@ -3307,22 +3307,10 @@ public class WifiConfigManager { } void clearBssidBlacklist() { - if (!mWifiStateMachine.useHalBasedAutoJoinOffload()) { - if(DBG) { - Log.d(TAG, "No blacklist allowed without epno enabled"); - } - return; - } mWifiConfigStore.clearBssidBlacklist(); } void blackListBssid(String bssid) { - if (!mWifiStateMachine.useHalBasedAutoJoinOffload()) { - if(DBG) { - Log.d(TAG, "No blacklist allowed without epno enabled"); - } - return; - } mWifiConfigStore.blackListBssid(bssid); } diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java new file mode 100644 index 000000000..4a6e2c239 --- /dev/null +++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java @@ -0,0 +1,830 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.wifi; + +import android.app.ActivityManager; +import android.app.AlarmManager; +import android.content.Context; +import android.net.wifi.ScanResult; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; +import android.net.wifi.WifiScanner; +import android.net.wifi.WifiScanner.PnoSettings; +import android.net.wifi.WifiScanner.ScanSettings; +import android.util.LocalLog; +import android.util.Log; + +import com.android.internal.R; +import com.android.server.wifi.util.ScanDetailUtil; + +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * This class manages all the connectivity related scanning activities. + * + * When the screen is turned on or off, WiFi is connected or disconnected, + * or on-demand, a scan is initiatiated and the scan results are passed + * to QNS for it to make a recommendation on which network to connect to. + */ +public class WifiConnectivityManager { + private static final String TAG = "WifiConnectivityManager"; + + // Periodic scan interval in milli-seconds. This is the scan + // performed when screen is on. + private static final int PERIODIC_SCAN_INTERVAL_MS = 20000; // 20 seconds + // PNO scan interval in milli-seconds. This is the scan + // performed when screen is off. + private static final int PNO_SCAN_INTERVAL_MS = 160000; // 160 seconds + // Maximum number of retries when starting a scan failed + private static final int MAX_SCAN_RESTART_ALLOWED = 5; + // Number of milli-seconds to delay before retry starting + // a previously failed scan + private static final int RESTART_SCAN_DELAY_MS = 2000; // 2 seconds + // When in disconnected mode, a watchdog timer will be fired + // every WATCHDOG_INTERVAL_MS to start a single scan. This is + // to prevent caveat from things like PNO scan. + private static final int WATCHDOG_INTERVAL_MS = 1200000; // 20 minutes + + // WifiStateMachine has a bunch of states. From the + // WifiConnectivityManager's perspective it only cares + // if it is in Connected state, Disconnected state or in + // transition between these two states. + public static final int WIFI_STATE_UNKNOWN = 0; + public static final int WIFI_STATE_CONNECTED = 1; + public static final int WIFI_STATE_DISCONNECTED = 2; + public static final int WIFI_STATE_TRANSITIONING = 3; + + private final WifiStateMachine mStateMachine; + private final WifiScanner mScanner; + private final WifiConfigManager mConfigManager; + private final WifiInfo mWifiInfo; + private final WifiQualifiedNetworkSelector mQualifiedNetworkSelector; + private final AlarmManager mAlarmManager; + private final LocalLog mLocalLog = new LocalLog(ActivityManager.isLowRamDeviceStatic() + ? 1024 : 16384); + private boolean mDbg = false; + private boolean mWifiEnabled = false; + private boolean mForceSelectNetwork = false; + private boolean mScreenOn = false; + private int mWifiState = WIFI_STATE_UNKNOWN; + private boolean mUntrustedConnectionAllowed = false; + private int mScanRestartCount = 0; + private int mSingleScanRestartCount = 0; + // Due to b/28020168, timer based single scan will be scheduled every + // PERIODIC_SCAN_INTERVAL_MS to provide periodic scan. + private boolean mNoBackgroundScan = true; + + // PNO settings + private int mMin5GHzRssi; + private int mMin24GHzRssi; + private int mInitialScoreMax; + private int mCurrentConnectionBonus; + private int mSameNetworkBonus; + private int mSecureBonus; + private int mBand5GHzBonus; + + // A helper to log debugging information in the local log buffer, which can + // be retrieved in bugreport. + private void localLog(String log) { + mLocalLog.log(log); + } + + // A periodic/PNO scan will be rescheduled up to MAX_SCAN_RESTART_ALLOWED times + // if the start scan command failed. An timer is used here to make it a deferred retry. + private final AlarmManager.OnAlarmListener mRestartScanListener = + new AlarmManager.OnAlarmListener() { + public void onAlarm() { + startConnectivityScan(mForceSelectNetwork); + } + }; + + // A single scan will be rescheduled up to MAX_SCAN_RESTART_ALLOWED times + // if the start scan command failed. An timer is used here to make it a deferred retry. + private final AlarmManager.OnAlarmListener mRestartSingleScanListener = + new AlarmManager.OnAlarmListener() { + public void onAlarm() { + startSingleScan(); + } + }; + + // As a watchdog mechanism, a single scan will be scheduled every WATCHDOG_INTERVAL_MS + // if it is in the WIFI_STATE_DISCONNECTED state. + private final AlarmManager.OnAlarmListener mWatchdogListener = + new AlarmManager.OnAlarmListener() { + public void onAlarm() { + watchdogHandler(); + } + }; + + // Due to b/28020168, timer based single scan will be scheduled every + // PERIODIC_SCAN_INTERVAL_MS to provide periodic scan. + private final AlarmManager.OnAlarmListener mPeriodicScanTimerListener = + new AlarmManager.OnAlarmListener() { + public void onAlarm() { + periodicScanTimerHandler(); + } + }; + + // Periodic scan results listener. A periodic scan is initiated when + // screen is on. + private class PeriodicScanListener implements WifiScanner.ScanListener { + private List<ScanDetail> mScanDetails = new ArrayList<ScanDetail>(); + + public void clearScanDetails() { + mScanDetails.clear(); + } + + @Override + public void onSuccess() { + localLog("PeriodicScanListener onSuccess"); + + // reset the count + mScanRestartCount = 0; + } + + @Override + public void onFailure(int reason, String description) { + Log.e(TAG, "PeriodicScanListener onFailure:" + + " reason: " + reason + + " description: " + description); + + // reschedule the scan + if (mScanRestartCount++ < MAX_SCAN_RESTART_ALLOWED) { + scheduleDelayedConnectivityScan(); + } else { + mScanRestartCount = 0; + Log.e(TAG, "Failed to successfully start periodic scan for " + + MAX_SCAN_RESTART_ALLOWED + " times"); + } + } + + @Override + public void onPeriodChanged(int periodInMs) { + localLog("PeriodicScanListener onPeriodChanged: " + + "actual scan period " + periodInMs + "ms"); + } + + @Override + public void onResults(WifiScanner.ScanData[] results) { + localLog("PeriodicScanListener onResults: start QNS"); + + WifiConfiguration candidate = + mQualifiedNetworkSelector.selectQualifiedNetwork(mForceSelectNetwork, + mUntrustedConnectionAllowed, mScanDetails, + mStateMachine.isLinkDebouncing(), mStateMachine.isConnected(), + mStateMachine.isDisconnected(), + mStateMachine.isSupplicantTransientState()); + + if (candidate != null) { + localLog("PeriodicScanListener: QNS candidate-" + candidate.SSID); + + connectToNetwork(candidate); + } + + clearScanDetails(); + } + + @Override + public void onFullResult(ScanResult fullScanResult) { + if (mDbg) { + localLog("PeriodicScanListener onFullResult: " + + fullScanResult.SSID + " capabilities " + + fullScanResult.capabilities); + } + + mScanDetails.add(ScanDetailUtil.toScanDetail(fullScanResult)); + } + } + + private final PeriodicScanListener mPeriodicScanListener = new PeriodicScanListener(); + + // Single scan results listener. A single scan is initiated when + // Disconnected/ConnectedPNO scan found a valid network and woke up + // the system, or by the watchdog timer. + private class SingleScanListener implements WifiScanner.ScanListener { + private List<ScanDetail> mScanDetails = new ArrayList<ScanDetail>(); + + public void clearScanDetails() { + mScanDetails.clear(); + } + + @Override + public void onSuccess() { + localLog("SingleScanListener onSuccess"); + + // reset the count + mSingleScanRestartCount = 0; + } + + @Override + public void onFailure(int reason, String description) { + Log.e(TAG, "SingleScanListener onFailure:" + + " reason: " + reason + + " description: " + description); + + // reschedule the scan + if (mSingleScanRestartCount++ < MAX_SCAN_RESTART_ALLOWED) { + scheduleDelayedSingleScan(); + } else { + mSingleScanRestartCount = 0; + Log.e(TAG, "Failed to successfully start single scan for " + + MAX_SCAN_RESTART_ALLOWED + " times"); + } + } + + @Override + public void onPeriodChanged(int periodInMs) { + localLog("SingleScanListener onPeriodChanged: " + + "actual scan period " + periodInMs + "ms"); + } + + @Override + public void onResults(WifiScanner.ScanData[] results) { + localLog("SingleScanListener onResults: start QNS"); + + WifiConfiguration candidate = + mQualifiedNetworkSelector.selectQualifiedNetwork(mForceSelectNetwork, + mUntrustedConnectionAllowed, mScanDetails, + mStateMachine.isLinkDebouncing(), mStateMachine.isConnected(), + mStateMachine.isDisconnected(), + mStateMachine.isSupplicantTransientState()); + + if (candidate != null) { + localLog("SingleScanListener: QNS candidate-" + candidate.SSID); + connectToNetwork(candidate); + } + } + + @Override + public void onFullResult(ScanResult fullScanResult) { + if (mDbg) { + localLog("SingleScanListener onFullResult: " + + fullScanResult.SSID + " capabilities " + + fullScanResult.capabilities); + } + + mScanDetails.add(ScanDetailUtil.toScanDetail(fullScanResult)); + } + } + + // re-enable this when b/27695292 is fixed + // private final SingleScanListener mSingleScanListener = new SingleScanListener(); + + // PNO scan results listener for both disconected and connected PNO scanning. + // A PNO scan is initiated when screen is off. + private class PnoScanListener implements WifiScanner.PnoScanListener { + private List<ScanDetail> mScanDetails = new ArrayList<ScanDetail>(); + + public void clearScanDetails() { + mScanDetails.clear(); + } + + @Override + public void onSuccess() { + localLog("PnoScanListener onSuccess"); + + // reset the count + mScanRestartCount = 0; + } + + @Override + public void onFailure(int reason, String description) { + Log.e(TAG, "PnoScanListener onFailure:" + + " reason: " + reason + + " description: " + description); + + // reschedule the scan + if (mScanRestartCount++ < MAX_SCAN_RESTART_ALLOWED) { + scheduleDelayedConnectivityScan(); + } else { + mScanRestartCount = 0; + Log.e(TAG, "Failed to successfully start PNO scan for " + + MAX_SCAN_RESTART_ALLOWED + " times"); + } + } + + @Override + public void onPeriodChanged(int periodInMs) { + localLog("PnoScanListener onPeriodChanged: " + + "actual scan period " + periodInMs + "ms"); + } + + // Currently the PNO scan results doesn't include IE, + // which contains information required by QNS. Ignore them + // for now. + @Override + public void onResults(WifiScanner.ScanData[] results) { + } + + @Override + public void onFullResult(ScanResult fullScanResult) { + } + + @Override + public void onPnoNetworkFound(ScanResult[] results) { + localLog("PnoScanListener: onPnoNetworkFound: results len = " + results.length); + + for (ScanResult result: results) { + mScanDetails.add(ScanDetailUtil.toScanDetail(result)); + } + + localLog("PnoScanListener: onPnoNetworkFound: start QNS"); + + WifiConfiguration candidate = + mQualifiedNetworkSelector.selectQualifiedNetwork(mForceSelectNetwork, + mUntrustedConnectionAllowed, mScanDetails, + mStateMachine.isLinkDebouncing(), mStateMachine.isConnected(), + mStateMachine.isDisconnected(), + mStateMachine.isSupplicantTransientState()); + + if (candidate != null) { + localLog("PnoScanListener: OnPnoNetworkFound: QNS candidate-" + candidate.SSID); + connectToNetwork(candidate); + } + } + } + + private final PnoScanListener mPnoScanListener = new PnoScanListener(); + + /** + * WifiConnectivityManager constructor + */ + public WifiConnectivityManager(Context context, WifiStateMachine stateMachine, + WifiScanner scanner, WifiConfigManager configManager, WifiInfo wifiInfo, + WifiQualifiedNetworkSelector qualifiedNetworkSelector) { + mStateMachine = stateMachine; + mScanner = scanner; + mConfigManager = configManager; + mWifiInfo = wifiInfo; + mQualifiedNetworkSelector = qualifiedNetworkSelector; + mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + + mMin5GHzRssi = WifiQualifiedNetworkSelector.MINIMUM_5G_ACCEPT_RSSI; + mMin24GHzRssi = WifiQualifiedNetworkSelector.MINIMUM_2G_ACCEPT_RSSI; + mBand5GHzBonus = WifiQualifiedNetworkSelector.BAND_AWARD_5GHz; + mCurrentConnectionBonus = mConfigManager.currentNetworkBoost.get(); + mSameNetworkBonus = context.getResources().getInteger( + R.integer.config_wifi_framework_SAME_BSSID_AWARD); + mSecureBonus = context.getResources().getInteger( + R.integer.config_wifi_framework_SECURITY_AWARD); + mInitialScoreMax = (mConfigManager.thresholdSaturatedRssi24.get() + + WifiQualifiedNetworkSelector.RSSI_SCORE_OFFSET) + * WifiQualifiedNetworkSelector.RSSI_SCORE_SLOPE; + + Log.i(TAG, "PNO settings:" + " min5GHzRssi " + mMin5GHzRssi + + " min24GHzRssi " + mMin24GHzRssi + + " currentConnectionBonus " + mCurrentConnectionBonus + + " sameNetworkBonus " + mSameNetworkBonus + + " secureNetworkBonus " + mSecureBonus + + " initialScoreMax " + mInitialScoreMax); + + Log.i(TAG, "ConnectivityScanManager initialized "); + } + + /** + * Attempt to connect to a network candidate. + * + * Based on the currently connected network, this menthod determines whether we should + * connect or roam to the network candidate recommended by QNS. + */ + private void connectToNetwork(WifiConfiguration candidate) { + ScanResult scanResultCandidate = candidate.getNetworkSelectionStatus().getCandidate(); + if (scanResultCandidate == null) { + Log.e(TAG, "connectToNetwork: bad candidate - " + candidate + + " scanResult: " + scanResultCandidate); + return; + } + + String targetBssid = scanResultCandidate.BSSID; + String targetAssociationId = candidate.SSID + " : " + targetBssid; + if (targetBssid != null && targetBssid.equals(mWifiInfo.getBSSID())) { + localLog("connectToNetwork: Already connected to" + targetAssociationId); + return; + } + + WifiConfiguration currentConnectedNetwork = mConfigManager + .getWifiConfiguration(mWifiInfo.getNetworkId()); + String currentAssociationId = (currentConnectedNetwork == null) ? "Disconnected" : + (mWifiInfo.getSSID() + " : " + mWifiInfo.getBSSID()); + + if (currentConnectedNetwork != null + && (currentConnectedNetwork.networkId == candidate.networkId + || currentConnectedNetwork.isLinked(candidate))) { + localLog("connectToNetwork: Roaming from " + currentAssociationId + " to " + + targetAssociationId); + mStateMachine.autoRoamToNetwork(candidate.networkId, scanResultCandidate); + } else { + localLog("connectToNetwork: Reconnect from " + currentAssociationId + " to " + + targetAssociationId); + mStateMachine.autoConnectToNetwork(candidate.networkId, scanResultCandidate.BSSID); + } + } + + // Helper for selecting the band for connectivity scan + private int getScanBand() { + int freqBand = mStateMachine.getFrequencyBand(); + if (freqBand == WifiManager.WIFI_FREQUENCY_BAND_5GHZ) { + return WifiScanner.WIFI_BAND_5_GHZ_WITH_DFS; + } else if (freqBand == WifiManager.WIFI_FREQUENCY_BAND_2GHZ) { + return WifiScanner.WIFI_BAND_24_GHZ; + } else { + return WifiScanner.WIFI_BAND_BOTH_WITH_DFS; + } + } + + // Watchdog timer handler + private void watchdogHandler() { + localLog("watchdogHandler"); + + // Schedule the next timer and start a single scan if we are in disconnected state. + // Otherwise, the watchdog timer will be scheduled when entering disconnected + // state. + if (mWifiState == WIFI_STATE_DISCONNECTED) { + Log.i(TAG, "start a single scan from watchdogHandler"); + + scheduleWatchdogTimer(); + startSingleScan(); + } + } + + // Periodic scan timer handler + private void periodicScanTimerHandler() { + localLog("periodicScanTimerHandler"); + + // Schedule the next timer and start a single scan if screen is on. + if (mScreenOn) { + schedulePeriodicScanTimer(); + startSingleScan(); + } + } + + // Start a single scan for watchdog + private void startSingleScan() { + if (!mWifiEnabled) { + return; + } + + ScanSettings settings = new ScanSettings(); + settings.band = getScanBand(); + settings.reportEvents = WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT + | WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN; + settings.numBssidsPerScan = 0; + + //Retrieve the list of hidden networkId's to scan for. + Set<Integer> hiddenNetworkIds = mConfigManager.getHiddenConfiguredNetworkIds(); + if (hiddenNetworkIds != null && hiddenNetworkIds.size() > 0) { + int i = 0; + settings.hiddenNetworkIds = new int[hiddenNetworkIds.size()]; + for (Integer netId : hiddenNetworkIds) { + settings.hiddenNetworkIds[i++] = netId; + } + } + + // re-enable this when b/27695292 is fixed + // mSingleScanListener.clearScanDetails(); + // mScanner.startScan(settings, mSingleScanListener); + SingleScanListener singleScanListener = new SingleScanListener(); + mScanner.startScan(settings, singleScanListener); + } + + // Start a periodic scan when screen is on + private void startPeriodicScan() { + // Due to b/28020168, timer based single scan will be scheduled every + // PERIODIC_SCAN_INTERVAL_MS to provide periodic scan. + if (mNoBackgroundScan) { + startSingleScan(); + schedulePeriodicScanTimer(); + } else { + ScanSettings settings = new ScanSettings(); + settings.band = getScanBand(); + settings.reportEvents = WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT + | WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN; + settings.numBssidsPerScan = 0; + settings.periodInMs = PERIODIC_SCAN_INTERVAL_MS; + + mPeriodicScanListener.clearScanDetails(); + mScanner.startBackgroundScan(settings, mPeriodicScanListener); + } + } + + // Stop a PNO scan + private void stopPnoScan() { + // Initialize PNO settings + PnoSettings pnoSettings = new PnoSettings(); + ArrayList<PnoSettings.PnoNetwork> pnoNetworkList = + mConfigManager.retrieveDisconnectedPnoNetworkList(false); + int listSize = pnoNetworkList.size(); + + pnoSettings.networkList = new PnoSettings.PnoNetwork[listSize]; + pnoSettings.networkList = pnoNetworkList.toArray(pnoSettings.networkList); + + mScanner.stopPnoScan(pnoSettings, mPnoScanListener); + } + + // Start a DisconnectedPNO scan when screen is off and Wifi is disconnected + private void startDisconnectedPnoScan() { + // Initialize PNO settings + PnoSettings pnoSettings = new PnoSettings(); + ArrayList<PnoSettings.PnoNetwork> pnoNetworkList = + mConfigManager.retrieveDisconnectedPnoNetworkList(true); + int listSize = pnoNetworkList.size(); + + if (listSize == 0) { + // No saved network + localLog("No saved network for starting disconnected PNO."); + return; + } + + pnoSettings.networkList = new PnoSettings.PnoNetwork[listSize]; + pnoSettings.networkList = pnoNetworkList.toArray(pnoSettings.networkList); + pnoSettings.min5GHzRssi = mMin5GHzRssi; + pnoSettings.min24GHzRssi = mMin24GHzRssi; + pnoSettings.initialScoreMax = mInitialScoreMax; + pnoSettings.currentConnectionBonus = mCurrentConnectionBonus; + pnoSettings.sameNetworkBonus = mSameNetworkBonus; + pnoSettings.secureBonus = mSecureBonus; + pnoSettings.band5GHzBonus = mBand5GHzBonus; + + // Initialize scan settings + ScanSettings scanSettings = new ScanSettings(); + scanSettings.band = getScanBand(); + scanSettings.reportEvents = WifiScanner.REPORT_EVENT_NO_BATCH; + scanSettings.numBssidsPerScan = 0; + scanSettings.periodInMs = PNO_SCAN_INTERVAL_MS; + // TODO: enable exponential back off scan later to further save energy + // scanSettings.maxPeriodInMs = 8 * scanSettings.periodInMs; + + mPnoScanListener.clearScanDetails(); + + mScanner.startDisconnectedPnoScan(scanSettings, pnoSettings, mPnoScanListener); + } + + // Start a ConnectedPNO scan when screen is off and Wifi is connected + private void startConnectedPnoScan() { + // Disable ConnectedPNO for now due to b/28020168 + if (mNoBackgroundScan) { + return; + } + + // Initialize PNO settings + PnoSettings pnoSettings = new PnoSettings(); + ArrayList<PnoSettings.PnoNetwork> pnoNetworkList = + mConfigManager.retrieveConnectedPnoNetworkList(); + int listSize = pnoNetworkList.size(); + + if (listSize == 0) { + // No saved network + localLog("No saved network for starting connected PNO."); + return; + } + + pnoSettings.networkList = new PnoSettings.PnoNetwork[listSize]; + pnoSettings.networkList = pnoNetworkList.toArray(pnoSettings.networkList); + pnoSettings.min5GHzRssi = mMin5GHzRssi; + pnoSettings.min24GHzRssi = mMin24GHzRssi; + pnoSettings.initialScoreMax = mInitialScoreMax; + pnoSettings.currentConnectionBonus = mCurrentConnectionBonus; + pnoSettings.sameNetworkBonus = mSameNetworkBonus; + pnoSettings.secureBonus = mSecureBonus; + pnoSettings.band5GHzBonus = mBand5GHzBonus; + + // Initialize scan settings + ScanSettings scanSettings = new ScanSettings(); + scanSettings.band = getScanBand(); + scanSettings.reportEvents = WifiScanner.REPORT_EVENT_NO_BATCH; + scanSettings.numBssidsPerScan = 0; + scanSettings.periodInMs = PNO_SCAN_INTERVAL_MS; + // TODO: enable exponential back off scan later to further save energy + // scanSettings.maxPeriodInMs = 8 * scanSettings.periodInMs; + + mPnoScanListener.clearScanDetails(); + + mScanner.startConnectedPnoScan(scanSettings, pnoSettings, mPnoScanListener); + } + + // Set up watchdog timer + private void scheduleWatchdogTimer() { + Log.i(TAG, "scheduleWatchdogTimer"); + + mAlarmManager.set(AlarmManager.RTC_WAKEUP, + System.currentTimeMillis() + WATCHDOG_INTERVAL_MS, + "WifiConnectivityManager Schedule Watchdog Timer", + mWatchdogListener, null); + } + + // Set up periodic scan timer + private void schedulePeriodicScanTimer() { + mAlarmManager.set(AlarmManager.RTC_WAKEUP, + System.currentTimeMillis() + PERIODIC_SCAN_INTERVAL_MS, + "WifiConnectivityManager Schedule Periodic Scan Timer", + mPeriodicScanTimerListener, null); + } + + // Set up timer to start a delayed single scan after RESTART_SCAN_DELAY_MS + private void scheduleDelayedSingleScan() { + localLog("scheduleDelayedSingleScan"); + + mAlarmManager.set(AlarmManager.RTC_WAKEUP, + System.currentTimeMillis() + RESTART_SCAN_DELAY_MS, + "WifiConnectivityManager Restart Single Scan", + mRestartSingleScanListener, null); + } + + // Set up timer to start a delayed scan after RESTART_SCAN_DELAY_MS + private void scheduleDelayedConnectivityScan() { + localLog("scheduleDelayedConnectivityScan"); + + mAlarmManager.set(AlarmManager.RTC_WAKEUP, + System.currentTimeMillis() + RESTART_SCAN_DELAY_MS, + "WifiConnectivityManager Restart Scan", + mRestartScanListener, null); + + } + + // Start a connectivity scan. The scan method is chosen according to + // the current screen state and WiFi state. + private void startConnectivityScan(boolean forceSelectNetwork) { + localLog("startConnectivityScan: screenOn=" + mScreenOn + + " wifiState=" + mWifiState + + " forceSelectNetwork=" + forceSelectNetwork + + " wifiEnabled=" + mWifiEnabled); + + if (!mWifiEnabled) { + return; + } + + // Always stop outstanding connecivity scan if there is any + stopConnectivityScan(); + + // Don't start a connectivity scan while Wifi is in the transition + // between connected and disconnected states. + if (mWifiState != WIFI_STATE_CONNECTED && mWifiState != WIFI_STATE_DISCONNECTED) { + return; + } + + mForceSelectNetwork = forceSelectNetwork; + + if (mScreenOn) { + startPeriodicScan(); + } else { // screenOff + if (mWifiState == WIFI_STATE_CONNECTED) { + startConnectedPnoScan(); + } else { + startDisconnectedPnoScan(); + } + } + } + + // Stop connectivity scan if there is any. + private void stopConnectivityScan() { + // Due to b/28020168, timer based single scan will be scheduled every + // PERIODIC_SCAN_INTERVAL_MS to provide periodic scan. + if (mNoBackgroundScan) { + mAlarmManager.cancel(mPeriodicScanTimerListener); + } else { + mScanner.stopBackgroundScan(mPeriodicScanListener); + } + stopPnoScan(); + mScanRestartCount = 0; + } + + /** + * Handler for screen state (on/off) changes + */ + public void handleScreenStateChanged(boolean screenOn) { + localLog("handleScreenStateChanged: screenOn=" + screenOn); + + mScreenOn = screenOn; + + startConnectivityScan(false); + } + + /** + * Handler for WiFi state (connected/disconnected) changes + */ + public void handleConnectionStateChanged(int state) { + localLog("handleConnectionStateChanged: state=" + state); + + mWifiState = state; + + // Kick off the watchdog timer if entering disconnected state + if (mWifiState == WIFI_STATE_DISCONNECTED) { + scheduleWatchdogTimer(); + } + + startConnectivityScan(false); + } + + /** + * Handler when user toggles whether untrusted connection is allowed + */ + public void setUntrustedConnectionAllowed(boolean allowed) { + Log.i(TAG, "setUntrustedConnectionAllowed: allowed=" + allowed); + + if (mUntrustedConnectionAllowed != allowed) { + mUntrustedConnectionAllowed = allowed; + startConnectivityScan(false); + } + } + + /** + * Handler when user specifies a particular network to connect to + */ + public void connectToUserSelectNetwork(int netId, boolean persistent) { + Log.i(TAG, "connectToUserSelectNetwork: netId=" + netId + + " persist=" + persistent); + + mQualifiedNetworkSelector.userSelectNetwork(netId, persistent); + + // Initiate a scan which will trigger the connection to the user selected + // network when scan result is available. + startConnectivityScan(true); + } + + /** + * Handler for on-demand connectivity scan + */ + public void forceConnectivityScan() { + Log.i(TAG, "forceConnectivityScan"); + + startConnectivityScan(false); + } + + /** + * Track whether a BSSID should be enabled or disabled for QNS + */ + public boolean trackBssid(String bssid, boolean enable) { + Log.i(TAG, "trackBssid: " + (enable ? "enable " : "disable ") + bssid); + + boolean ret = mQualifiedNetworkSelector + .enableBssidForQualityNetworkSelection(bssid, enable); + + if (ret && !enable) { + // Disabling a BSSID can happen when the AP candidate to connect to has + // no capacity for new stations. We start another scan immediately so that QNS + // can give us another candidate to connect to. + startConnectivityScan(false); + } + + return ret; + } + + /** + * Set band preference when doing scan and making connection + */ + public void setUserPreferredBand(int band) { + Log.i(TAG, "User band preference: " + band); + + mQualifiedNetworkSelector.setUserPreferredBand(band); + startConnectivityScan(false); + } + + /** + * Inform WiFi is enabled for connection or not + */ + public void setWifiEnabled(boolean enable) { + Log.i(TAG, "Set WiFi " + (enable ? "enabled" : "disabled")); + + mWifiEnabled = enable; + + if (!mWifiEnabled) { + stopConnectivityScan(); + } + } + + /** + * Enable/disable verbose logging + */ + public void enableVerboseLogging(int verbose) { + mDbg = verbose > 0; + } + + /** + * Dump the local log buffer + */ + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + pw.println("Dump of WifiConnectivityManager"); + pw.println("WifiConnectivityManager - Log Begin ----"); + mLocalLog.dump(fd, pw, args); + pw.println("WifiConnectivityManager - Log End ----"); + } +} diff --git a/service/java/com/android/server/wifi/WifiQualifiedNetworkSelector.java b/service/java/com/android/server/wifi/WifiQualifiedNetworkSelector.java index 8d7648bf0..1601f7361 100644 --- a/service/java/com/android/server/wifi/WifiQualifiedNetworkSelector.java +++ b/service/java/com/android/server/wifi/WifiQualifiedNetworkSelector.java @@ -39,7 +39,11 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -class WifiQualifiedNetworkSelector { +/** + * This class looks at all the connectivity scan results then + * select an network for the phone to connect/roam to. + */ +public class WifiQualifiedNetworkSelector { private WifiConfigManager mWifiConfigManager; private WifiInfo mWifiInfo; private NetworkScoreManager mScoreManager; @@ -67,8 +71,8 @@ class WifiQualifiedNetworkSelector { public static final int MINIMUM_2G_ACCEPT_RSSI = -85; public static final int MINIMUM_5G_ACCEPT_RSSI = -82; - private static final int RSSI_SCORE_SLOPE = 4; - private static final int RSSI_SCORE_OFFSET = 85; + public static final int RSSI_SCORE_SLOPE = 4; + public static final int RSSI_SCORE_OFFSET = 85; public static final int BAND_AWARD_5GHz = 40; public static final int SAME_NETWORK_AWARD = 16; @@ -184,14 +188,6 @@ class WifiQualifiedNetworkSelector { } - void enableNetworkByUser(WifiConfiguration network) { - if (network != null) { - mWifiConfigManager.updateNetworkSelectionStatus(network, - WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE); - mWifiConfigManager.setLatestUserSelectedConfiguration(network); - } - } - /** * check whether current network is good enough we need not consider any potential switch * diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java index 32d0e3645..d31b7b788 100644 --- a/service/java/com/android/server/wifi/WifiServiceImpl.java +++ b/service/java/com/android/server/wifi/WifiServiceImpl.java @@ -40,13 +40,13 @@ import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.database.ContentObserver; import android.net.ConnectivityManager; -import android.net.ip.IpManager; import android.net.DhcpInfo; import android.net.DhcpResults; import android.net.Network; import android.net.NetworkScorerAppManager; import android.net.NetworkUtils; import android.net.Uri; +import android.net.ip.IpManager; import android.net.wifi.IWifiManager; import android.net.wifi.PasspointManagementObjectDefinition; import android.net.wifi.ScanResult; @@ -1914,15 +1914,6 @@ public class WifiServiceImpl extends IWifiManager.Stub { enforceAccessPermission(); return mWifiStateMachine.getEnableAutoJoinWhenAssociated(); } - public void setHalBasedAutojoinOffload(int enabled) { - enforceConnectivityInternalPermission(); - mWifiStateMachine.setHalBasedAutojoinOffload(enabled); - } - - public int getHalBasedAutojoinOffload() { - enforceAccessPermission(); - return mWifiStateMachine.getHalBasedAutojoinOffload(); - } /* Return the Wifi Connection statistics object */ public WifiConnectionStatistics getConnectionStatistics() { diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index b3e6d960a..791a55aef 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -26,7 +26,6 @@ import static android.net.wifi.WifiManager.WIFI_STATE_DISABLING; import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED; import static android.net.wifi.WifiManager.WIFI_STATE_ENABLING; import static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN; -import static android.system.OsConstants.ARPHRD_ETHER; import android.Manifest; import android.app.ActivityManager; @@ -148,8 +147,7 @@ import java.util.concurrent.atomic.AtomicInteger; * * @hide */ -public class WifiStateMachine extends StateMachine implements WifiNative.PnoEventHandler, - WifiNative.WifiRssiEventHandler { +public class WifiStateMachine extends StateMachine implements WifiNative.WifiRssiEventHandler { private static final String NETWORKTYPE = "WIFI"; private static final String NETWORKTYPE_UNTRUSTED = "WIFI_UT"; @@ -186,6 +184,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven private WifiMonitor mWifiMonitor; private WifiNative mWifiNative; private WifiConfigManager mWifiConfigManager; + private WifiConnectivityManager mWifiConnectivityManager; private WifiQualifiedNetworkSelector mWifiQualifiedNetworkSelector; private INetworkManagementService mNwService; private ConnectivityManager mCm; @@ -223,63 +222,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven private ScanDetail mActiveScanDetail; // ScanDetail associated with active network private boolean linkDebouncing = false; - private boolean mHalBasedPnoDriverSupported = false; - - private boolean mHalBasedPnoEnableInDevSettings = false; - - private int mHalFeatureSet = 0; - private static int mPnoResultFound = 0; - private int mCurrentUserId = UserHandle.USER_SYSTEM; - private boolean mAllowUntrustedConnections = false; - - @Override - public void onPnoNetworkFound(ScanResult results[]) { - if (DBG) { - Log.e(TAG, "onPnoNetworkFound event received num = " + results.length); - for (int i = 0; i < results.length; i++) { - Log.e(TAG, results[i].toString()); - } - } - sendMessage(CMD_PNO_NETWORK_FOUND, results.length, 0, results); - } - - /** - * Ignore Pno scan failed events. This is needed for WifiScanner - * TODO(rpius): Remove this once PNO scan logic is removed from WifiStateMachine. - */ - @Override - public void onPnoScanFailed() { - return; - } - - public void processPnoNetworkFound(ScanResult results[]) { - ScanSettings settings = new ScanSettings(); - settings.channelSet = new ArrayList<WifiChannel>(); - StringBuilder sb = new StringBuilder(); - sb.append(""); - for (int i=0; i<results.length; i++) { - WifiChannel channel = new WifiChannel(); - channel.freqMHz = results[i].frequency; - settings.channelSet.add(channel); - sb.append(results[i].SSID).append(" "); - } - - stopPnoOffload(); - - Log.e(TAG, "processPnoNetworkFound starting scan cnt=" + mPnoResultFound); - startScan(PNO_NETWORK_FOUND_SOURCE, mPnoResultFound, settings, null); - mPnoResultFound ++; - //sendMessage(CMD_SCAN_RESULTS_AVAILABLE); - int delay = 30 * 1000; - // reconfigure Pno after 1 minutes if we're still in disconnected state - sendMessageDelayed(CMD_RESTART_AUTOJOIN_OFFLOAD, delay, - mRestartAutoJoinOffloadCounter, " processPnoNetworkFound " + sb.toString(), - (long)delay); - mRestartAutoJoinOffloadCounter++; - } - @Override public void onRssiThresholdBreached(byte curRssi) { if (DBG) { @@ -312,10 +256,10 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven } } public void registerNetworkDisabled(int netId) { - // Restart legacy PNO and autojoin offload if needed - sendMessage(CMD_RESTART_AUTOJOIN_OFFLOAD, 0, - mRestartAutoJoinOffloadCounter, " registerNetworkDisabled " + netId); - mRestartAutoJoinOffloadCounter++; + // Initiate a connectivity scan + if (mWifiConnectivityManager != null) { + mWifiConnectivityManager.forceConnectivityScan(); + } } // Testing various network disconnect cases by sending lots of spurious @@ -323,7 +267,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven private boolean testNetworkDisconnect = false; private boolean mEnableRssiPolling = false; - private boolean mLegacyPnoEnabled = false; private int mRssiPollToken = 0; /* 3 operational states for STA operation: CONNECT_MODE, SCAN_ONLY_MODE, SCAN_ONLY_WIFI_OFF_MODE * In CONNECT_MODE, the STA can scan and connect to an access point @@ -343,7 +286,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven private static final int SET_ALLOW_UNTRUSTED_SOURCE = -4; private static final int ENABLE_WIFI = -5; public static final int DFS_RESTRICTED_SCAN_REQUEST = -6; - public static final int PNO_NETWORK_FOUND_SOURCE = -7; private static final int SCAN_REQUEST_BUFFER_MAX_SIZE = 10; private static final String CUSTOMIZED_SCAN_SETTING = "customized_scan_settings"; @@ -593,9 +535,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven private AlarmManager mAlarmManager; private PendingIntent mScanIntent; - private PendingIntent mPnoIntent; - private int mDisconnectedPnoAlarmCount = 0; /* Tracks current frequency mode */ private AtomicInteger mFrequencyBand = new AtomicInteger(WifiManager.WIFI_FREQUENCY_BAND_AUTO); @@ -836,22 +776,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven static final int CMD_ACCEPT_UNVALIDATED = BASE + 153; - /* used to restart PNO when it was stopped due to association attempt */ - static final int CMD_RESTART_AUTOJOIN_OFFLOAD = BASE + 154; - - static int mRestartAutoJoinOffloadCounter = 0; - - /* used to log if PNO was started */ - static final int CMD_STARTED_PNO_DBG = BASE + 155; - - static final int CMD_PNO_NETWORK_FOUND = BASE + 156; - /* used to log if PNO was started */ static final int CMD_UPDATE_ASSOCIATED_SCAN_PERMISSION = BASE + 158; - /* used to log if GSCAN was started */ - static final int CMD_STARTED_GSCAN_DBG = BASE + 159; - /* used to offload sending IP packet */ static final int CMD_START_IP_PACKET_OFFLOAD = BASE + 160; @@ -1011,33 +938,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven /* Soft ap state */ private State mSoftApState = new SoftApState(); - private class WifiScanListener implements WifiScanner.ScanListener { - @Override - public void onSuccess() { - Log.e(TAG, "WifiScanListener onSuccess"); - }; - @Override - public void onFailure(int reason, String description) { - Log.e(TAG, "WifiScanListener onFailure"); - }; - @Override - public void onPeriodChanged(int periodInMs) { - Log.e(TAG, "WifiScanListener onPeriodChanged period=" + periodInMs); - } - @Override - public void onResults(WifiScanner.ScanData[] results) { - Log.e(TAG, "WifiScanListener onResults2 " + results.length); - } - @Override - public void onFullResult(ScanResult fullScanResult) { - Log.e(TAG, "WifiScanListener onFullResult " + fullScanResult.toString()); - } - - WifiScanListener() {} - } - - WifiScanListener mWifiScanListener = new WifiScanListener(); - public static class SimAuthRequestData { int networkId; int protocol; @@ -1069,10 +969,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven private static final String ACTION_START_SCAN = "com.android.server.WifiManager.action.START_SCAN"; - private static final int PNO_START_REQUEST = 0; - private static final String ACTION_START_PNO = - "com.android.server.WifiManager.action.START_PNO"; - /** * Keep track of whether WIFI is running. */ @@ -1102,7 +998,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven private static final int sFrameworkMinScanIntervalSaneValue = 10000; - private boolean mPnoEnabled; private long mGScanStartTimeMilli; private long mGScanPeriodMilli; @@ -1173,7 +1068,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); mScanIntent = getPrivateBroadcast(ACTION_START_SCAN, SCAN_REQUEST); - mPnoIntent = getPrivateBroadcast(ACTION_START_PNO, PNO_START_REQUEST); // Make sure the interval is not configured less than 10 seconds int period = mContext.getResources().getInteger( @@ -1218,18 +1112,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven }, new IntentFilter(ACTION_START_SCAN)); - mContext.registerReceiver( - new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - sendMessage(CMD_RESTART_AUTOJOIN_OFFLOAD, 0, - mRestartAutoJoinOffloadCounter, "pno alarm"); - if (DBG) - logd("PNO START ALARM sent"); - } - }, - new IntentFilter(ACTION_START_PNO)); - IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_SCREEN_ON); @@ -1448,29 +1330,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven mWifiConfigManager.enableVerboseLogging(mVerboseLoggingLevel); mSupplicantStateTracker.enableVerboseLogging(mVerboseLoggingLevel); mWifiQualifiedNetworkSelector.enableVerboseLogging(mVerboseLoggingLevel); - } - - public void setHalBasedAutojoinOffload(int enabled) { - // Shoult be used for debug only, triggered form developper settings - // enabling HAl based PNO dynamically is not safe and not a normal operation - mHalBasedPnoEnableInDevSettings = enabled > 0; - mWifiConfigManager.enableHalBasedPno.set(mHalBasedPnoEnableInDevSettings); - mWifiConfigManager.enableSsidWhitelist.set(mHalBasedPnoEnableInDevSettings); - sendMessage(CMD_DISCONNECT); - } - - int getHalBasedAutojoinOffload() { - return mHalBasedPnoEnableInDevSettings ? 1 : 0; - } - - boolean useHalBasedAutoJoinOffload() { - // all three settings need to be true: - // - developper settings switch - // - driver support - // - config option - return mHalBasedPnoEnableInDevSettings - && mHalBasedPnoDriverSupported - && mWifiConfigManager.enableHalBasedPno.get(); + if (mWifiConnectivityManager != null) { + mWifiConnectivityManager.enableVerboseLogging(mVerboseLoggingLevel); + } } boolean allowFullBandScanAndAssociated() { @@ -1516,31 +1378,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven // we want to throttle the GScan Stop->Start transition static final long SCAN_PERMISSION_UPDATE_THROTTLE_MILLI = 20000; void updateAssociatedScanPermission() { - - if (useHalBasedAutoJoinOffload()) { - boolean allowed = allowFullBandScanAndAssociated(); - - long now = System.currentTimeMillis(); - if (mConnectedModeGScanOffloadStarted && !allowed) { - if (DBG) { - Log.e(TAG, " useHalBasedAutoJoinOffload stop offload"); - } - stopPnoOffload(); - stopGScan(" useHalBasedAutoJoinOffload"); - } - if (!mConnectedModeGScanOffloadStarted && allowed) { - if ((now - mLastScanPermissionUpdate) > SCAN_PERMISSION_UPDATE_THROTTLE_MILLI) { - // Re-enable Gscan offload, this will trigger periodic scans and allow firmware - // to look for 5GHz BSSIDs and better networks - if (DBG) { - Log.e(TAG, " useHalBasedAutoJoinOffload restart offload"); - } - startGScanConnectedModeOffload("updatePermission " - + (now - mLastScanPermissionUpdate) + "ms"); - mLastScanPermissionUpdate = now; - } - } - } } private int mAggressiveHandover = 0; @@ -1865,9 +1702,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven } else { mWifiInfo.updatePacketRates(stats); } - if (useHalBasedAutoJoinOffload()) { - sendMessage(CMD_UPDATE_ASSOCIATED_SCAN_PERMISSION); - } return stats; } @@ -2224,6 +2058,10 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven return false; } + public boolean isLinkDebouncing() { + return linkDebouncing; + } + /** * Get status information for the current connection, if any. * @@ -2492,43 +2330,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven } /** - * Convert WifiScanner.PnoNetwork List to WifiNative.PnoNetwork List - * TODO(rpius): Remove this once WifiScanner starts PNO scanning. - */ - private List<WifiNative.PnoNetwork> convertPnoNetworkListToNative( - List<WifiScanner.PnoSettings.PnoNetwork> pnoNetworkList) { - List<WifiNative.PnoNetwork> nativePnoNetworkList = new ArrayList<>(); - for (WifiScanner.PnoSettings.PnoNetwork pnoNetwork : pnoNetworkList) { - WifiNative.PnoNetwork nativePnoNetwork = new WifiNative.PnoNetwork(); - nativePnoNetwork.ssid = pnoNetwork.ssid; - nativePnoNetwork.networkId = pnoNetwork.networkId; - nativePnoNetwork.priority = pnoNetwork.priority; - nativePnoNetwork.flags = pnoNetwork.flags; - nativePnoNetwork.auth_bit_field = pnoNetwork.authBitField; - nativePnoNetworkList.add(nativePnoNetwork); - } - return nativePnoNetworkList; - } - - void enableBackgroundScan(boolean enable) { - if (enable) { - mWifiConfigManager.enableAllNetworks(); - // Now enable all the networks in wpa_supplicant. These will be - // disabled when we connect to a network after PNO. - mWifiConfigManager.enableAllNetworksNative(); - } - List<WifiScanner.PnoSettings.PnoNetwork> pnoList = - mWifiConfigManager.retrieveDisconnectedPnoNetworkList(enable); - boolean ret = - mWifiNative.enableBackgroundScan(enable, convertPnoNetworkListToNative(pnoList)); - if (ret) { - mLegacyPnoEnabled = enable; - } else { - Log.e(TAG, " Fail to set up pno, want " + enable + " now " + mLegacyPnoEnabled); - } - } - - /** * Blacklist a BSSID. This will avoid the AP if there are * alternate APs to connect * @@ -2729,7 +2530,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven pw.println("mUserWantsSuspendOpt " + mUserWantsSuspendOpt); pw.println("mSuspendOptNeedsDisabled " + mSuspendOptNeedsDisabled); pw.println("Supplicant status " + mWifiNative.status(true)); - pw.println("mLegacyPnoEnabled " + mLegacyPnoEnabled); if (mCountryCode.getCurrentCountryCode() != null) { pw.println("CurrentCountryCode " + mCountryCode.getCurrentCountryCode()); } else { @@ -2769,6 +2569,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven mWifiLogger.dump(fd, pw, args); mWifiQualifiedNetworkSelector.dump(fd, pw, args); dumpIpManager(fd, pw, args); + if (mWifiConnectivityManager != null) { + mWifiConnectivityManager.dump(fd, pw, args); + } } public void handleUserSwitch(int userId) { @@ -2822,32 +2625,11 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven } sb.append(" ").append(printTime()); switch (msg.what) { - case CMD_STARTED_GSCAN_DBG: - case CMD_STARTED_PNO_DBG: - sb.append(" "); - sb.append(Integer.toString(msg.arg1)); - sb.append(" "); - sb.append(Integer.toString(msg.arg2)); - if (msg.obj != null) { - sb.append(" " + (String)msg.obj); - } - break; - case CMD_RESTART_AUTOJOIN_OFFLOAD: - sb.append(" "); - sb.append(Integer.toString(msg.arg1)); - sb.append(" "); - sb.append(Integer.toString(msg.arg2)); - sb.append("/").append(Integer.toString(mRestartAutoJoinOffloadCounter)); - if (msg.obj != null) { - sb.append(" " + (String)msg.obj); - } - break; case CMD_UPDATE_ASSOCIATED_SCAN_PERMISSION: sb.append(" "); sb.append(Integer.toString(msg.arg1)); sb.append(" "); sb.append(Integer.toString(msg.arg2)); - sb.append(" halAllowed=").append(useHalBasedAutoJoinOffload()); sb.append(" scanAllowed=").append(allowFullBandScanAndAssociated()); sb.append(" autojoinAllowed="); sb.append(mWifiConfigManager.enableAutoJoinWhenAssociated.get()); @@ -2858,20 +2640,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven sb.append("/").append(mWifiConfigManager.maxRxPacketForFullScans); sb.append(" -> ").append(mConnectedModeGScanOffloadStarted); break; - case CMD_PNO_NETWORK_FOUND: - sb.append(" "); - sb.append(Integer.toString(msg.arg1)); - sb.append(" "); - sb.append(Integer.toString(msg.arg2)); - if (msg.obj != null) { - ScanResult[] results = (ScanResult[])msg.obj; - for (int i = 0; i < results.length; i++) { - sb.append(" ").append(results[i].SSID).append(" "); - sb.append(results[i].frequency); - sb.append(" ").append(results[i].level); - } - } - break; case CMD_START_SCAN: now = System.currentTimeMillis(); sb.append(" "); @@ -3379,224 +3147,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven return sb.toString(); } - private void stopPnoOffload() { - - // clear the PNO list - if (!mWifiNative.resetPnoList()) { - Log.e(TAG, "Failed to stop pno"); - } - - } - - private boolean startGScanConnectedModeOffload(String reason) { - if (DBG) { - if (reason == null) { - reason = ""; - } - logd("startGScanConnectedModeOffload " + reason); - } - stopGScan("startGScanConnectedModeOffload " + reason); - if (!mScreenOn) return false; - - if (USE_PAUSE_SCANS) { - mWifiNative.pauseScan(); - } - mPnoEnabled = configurePno(); - if (mPnoEnabled == false) { - if (USE_PAUSE_SCANS) { - mWifiNative.restartScan(); - } - return false; - } - if (!startConnectedGScan(reason)) { - if (USE_PAUSE_SCANS) { - mWifiNative.restartScan(); - } - return false; - } - if (USE_PAUSE_SCANS) { - mWifiNative.restartScan(); - } - mConnectedModeGScanOffloadStarted = true; - if (DBG) { - logd("startGScanConnectedModeOffload success"); - } - return true; - } - - private boolean startGScanDisconnectedModeOffload(String reason) { - if (DBG) { - logd("startGScanDisconnectedModeOffload " + reason); - } - stopGScan("startGScanDisconnectedModeOffload " + reason); - if (USE_PAUSE_SCANS) { - mWifiNative.pauseScan(); - } - mPnoEnabled = configurePno(); - if (mPnoEnabled == false) { - if (USE_PAUSE_SCANS) { - mWifiNative.restartScan(); - } - return false; - } - if (!startDisconnectedGScan(reason)) { - if (USE_PAUSE_SCANS) { - mWifiNative.restartScan(); - } - return false; - } - if (USE_PAUSE_SCANS) { - mWifiNative.restartScan(); - } - return true; - } - - private boolean configurePno() { - if (!useHalBasedAutoJoinOffload()) return false; - - if (mWifiScanner == null) { - log("configurePno: mWifiScanner is null "); - return true; - } - - List<WifiNative.PnoNetwork> llist = null; - //TODO: add getPnoList in WifiQualifiedNetworkSelector - //mWifiAutoJoinController.getPnoList(getCurrentWifiConfiguration()); - if (llist == null || llist.size() == 0) { - stopPnoOffload(); - log("configurePno: empty PNO list "); - return true; - } - if (DBG) { - log("configurePno: got llist size " + llist.size()); - } - - // first program the network we want to look for thru the pno API - WifiNative.PnoNetwork[] list = - (WifiNative.PnoNetwork[]) llist.toArray(new WifiNative.PnoNetwork[0]); - - if (!mWifiNative.setPnoList(list, WifiStateMachine.this)) { - Log.e(TAG, "Failed to set pno, length = " + list.length); - return false; - } - - if (true) { - StringBuilder sb = new StringBuilder(); - for (WifiNative.PnoNetwork network : list) { - sb.append("[").append(network.ssid).append(" auth=").append(network.auth_bit_field); - sb.append(" flags="); - sb.append(network.flags); - sb.append("] "); - - } - sendMessage(CMD_STARTED_PNO_DBG, 1, (int)mGScanPeriodMilli, sb.toString()); - } - return true; - } - - final static int DISCONNECTED_SHORT_SCANS_DURATION_MILLI = 2 * 60 * 1000; - final static int CONNECTED_SHORT_SCANS_DURATION_MILLI = 2 * 60 * 1000; - - private boolean startConnectedGScan(String reason) { - // send a scan background request so as to kick firmware - // 5GHz roaming and autojoin - // We do this only if screen is on - WifiScanner.ScanSettings settings; - - if (mPnoEnabled) { - settings = new WifiScanner.ScanSettings(); - settings.band = WifiScanner.WIFI_BAND_BOTH; - long now = System.currentTimeMillis(); - - if (!mScreenOn || (mGScanStartTimeMilli!= 0 && now > mGScanStartTimeMilli - && ((now - mGScanStartTimeMilli) > CONNECTED_SHORT_SCANS_DURATION_MILLI))) { - settings.periodInMs = mWifiConfigManager.wifiAssociatedLongScanIntervalMilli.get(); - } else { - mGScanStartTimeMilli = now; - settings.periodInMs = mWifiConfigManager.wifiAssociatedShortScanIntervalMilli.get(); - // if we start offload with short interval, then reconfigure it after a given - // duration of time so as to reduce the scan frequency - int delay = 30 * 1000 + CONNECTED_SHORT_SCANS_DURATION_MILLI; - sendMessageDelayed(CMD_RESTART_AUTOJOIN_OFFLOAD, delay, - mRestartAutoJoinOffloadCounter, " startConnectedGScan " + reason, - (long)delay); - mRestartAutoJoinOffloadCounter++; - } - mGScanPeriodMilli = settings.periodInMs; - settings.reportEvents = WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL; - if (DBG) { - log("startConnectedScan: settings band="+ settings.band - + " period=" + settings.periodInMs); - } - - mWifiScanner.startBackgroundScan(settings, mWifiScanListener); - if (true) { - sendMessage(CMD_STARTED_GSCAN_DBG, 1, (int)mGScanPeriodMilli, reason); - } - } - return true; - } - - private boolean startDisconnectedGScan(String reason) { - // send a scan background request so as to kick firmware - // PNO - // This is done in both screen On and screen Off modes - WifiScanner.ScanSettings settings; - - if (mWifiScanner == null) { - log("startDisconnectedGScan: no wifi scanner"); - return false; - } - - if (mPnoEnabled) { - settings = new WifiScanner.ScanSettings(); - settings.band = WifiScanner.WIFI_BAND_BOTH; - long now = System.currentTimeMillis(); - - - if (!mScreenOn || (mGScanStartTimeMilli != 0 && now > mGScanStartTimeMilli - && ((now - mGScanStartTimeMilli) > DISCONNECTED_SHORT_SCANS_DURATION_MILLI))) { - settings.periodInMs = - mWifiConfigManager.wifiDisconnectedLongScanIntervalMilli.get(); - } else { - settings.periodInMs = - mWifiConfigManager.wifiDisconnectedShortScanIntervalMilli.get(); - mGScanStartTimeMilli = now; - // if we start offload with short interval, then reconfigure it after a given - // duration of time so as to reduce the scan frequency - int delay = 30 * 1000 + DISCONNECTED_SHORT_SCANS_DURATION_MILLI; - sendMessageDelayed(CMD_RESTART_AUTOJOIN_OFFLOAD, delay, - mRestartAutoJoinOffloadCounter, " startDisconnectedGScan " + reason, - (long)delay); - mRestartAutoJoinOffloadCounter++; - } - mGScanPeriodMilli = settings.periodInMs; - settings.reportEvents = WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL; - if (DBG) { - log("startDisconnectedScan: settings band="+ settings.band - + " period=" + settings.periodInMs); - } - mWifiScanner.startBackgroundScan(settings, mWifiScanListener); - if (true) { - sendMessage(CMD_STARTED_GSCAN_DBG, 1, (int)mGScanPeriodMilli, reason); - } - } - return true; - } - - private boolean stopGScan(String reason) { - mGScanStartTimeMilli = 0; - mGScanPeriodMilli = 0; - if (mWifiScanner != null) { - mWifiScanner.stopBackgroundScan(mWifiScanListener); - } - mConnectedModeGScanOffloadStarted = false; - if (true) { - sendMessage(CMD_STARTED_GSCAN_DBG, 0, 0, reason); - } - return true; - } - private void handleScreenStateChanged(boolean screenOn) { mScreenOn = screenOn; if (DBG) { @@ -3621,61 +3171,11 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven mOnTimeScreenStateChange = mOnTime; lastScreenStateChangeTimeStamp = lastLinkLayerStatsUpdate; - cancelDelayedScan(); - mWifiMetrics.setScreenState(screenOn); - if (screenOn) { - enableBackgroundScan(false); - setScanAlarm(false); - clearBlacklist(); - - fullBandConnectedTimeIntervalMilli - = mWifiConfigManager.wifiAssociatedShortScanIntervalMilli.get(); - // In either Disconnectedstate or ConnectedState, - // start the scan alarm so as to enable autojoin - if (getCurrentState() == mConnectedState - && allowFullBandScanAndAssociated()) { - if (useHalBasedAutoJoinOffload()) { - startGScanConnectedModeOffload("screenOnConnected"); - } else { - // Scan after 500ms - startDelayedScan(500, null, null); - } - } else if (getCurrentState() == mDisconnectedState) { - if (useHalBasedAutoJoinOffload()) { - startGScanDisconnectedModeOffload("screenOnDisconnected"); - } else { - // Scan after 500ms - startDelayedScan(500, null, null); - } - } - } else { - if (getCurrentState() == mDisconnectedState) { - // Screen Off and Disconnected and chipset doesn't support scan offload - // => start scan alarm - // Screen Off and Disconnected and chipset does support scan offload - // => will use scan offload (i.e. background scan) - if (useHalBasedAutoJoinOffload()) { - startGScanDisconnectedModeOffload("screenOffDisconnected"); - } else { - if (!mBackgroundScanSupported) { - setScanAlarm(true); - } else { - if (!mIsScanOngoing) { - enableBackgroundScan(true); - } - } - } - } else { - enableBackgroundScan(false); - if (useHalBasedAutoJoinOffload()) { - // don't try stop Gscan if it is not enabled - stopGScan("ScreenOffStop(enableBackground=" + mLegacyPnoEnabled + ") "); - } - } + if (mWifiConnectivityManager != null) { + mWifiConnectivityManager.handleScreenStateChanged(screenOn); } - if (DBG) logd("backgroundScan enabled=" + mLegacyPnoEnabled); if (DBG) log("handleScreenStateChanged Exit: " + screenOn); } @@ -3696,7 +3196,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven if (mWifiNative.setBand(band)) { mFrequencyBand.set(band); - mWifiQualifiedNetworkSelector.setUserPreferredBand(band); + if (mWifiConnectivityManager != null) { + mWifiConnectivityManager.setUserPreferredBand(band); + } if (DBG) { logd("done set frequency band " + band); } @@ -3862,24 +3364,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven // just try to reconnect to the same SSID by triggering a roam // The third parameter 1 means roam not from network selection but debouncing sendMessage(CMD_AUTO_ROAM, mLastNetworkId, 1, null); - } else { - WifiConfiguration candidate = - mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, - mAllowUntrustedConnections, mScanResults, linkDebouncing, isConnected(), - isDisconnected(), isSupplicantTransientState()); - tryToConnectToNetwork(candidate); - } - } - - /** - * Set whether connections to untrusted connections are allowed. - */ - void setAllowUntrustedConnections(boolean allow) { - boolean changed = (mAllowUntrustedConnections != allow); - mAllowUntrustedConnections = allow; - if (changed) { - // Trigger a scan so as to reattempt autojoin - startScanForUntrustedSettingChange(); } } @@ -4747,7 +4231,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven if (!networkRequest.networkCapabilities.hasCapability( NetworkCapabilities.NET_CAPABILITY_TRUSTED)) { if (++mUntrustedReqCount == 1) { - setAllowUntrustedConnections(true); + if (mWifiConnectivityManager != null) { + mWifiConnectivityManager.setUntrustedConnectionAllowed(true); + } } } } @@ -4757,7 +4243,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven if (!networkRequest.networkCapabilities.hasCapability( NetworkCapabilities.NET_CAPABILITY_TRUSTED)) { if (--mUntrustedReqCount == 0) { - setAllowUntrustedConnections(false); + if (mWifiConnectivityManager != null) { + mWifiConnectivityManager.setUntrustedConnectionAllowed(false); + } } } } @@ -4908,9 +4396,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven case CMD_DISCONNECTING_WATCHDOG_TIMER: case CMD_ROAM_WATCHDOG_TIMER: case CMD_DISABLE_EPHEMERAL_NETWORK: - case CMD_RESTART_AUTOJOIN_OFFLOAD: - case CMD_STARTED_PNO_DBG: - case CMD_STARTED_GSCAN_DBG: case CMD_UPDATE_ASSOCIATED_SCAN_PERMISSION: messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD; break; @@ -5065,11 +4550,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven mWifiApConfigStore = mFacade.makeApConfigStore(mContext, mBackupManagerProxy); } - - if (mWifiConfigManager.enableHalBasedPno.get()) { - // make sure developer Settings are in sync with the config option - mHalBasedPnoEnableInDevSettings = true; - } } @Override public boolean processMessage(Message message) { @@ -5504,6 +4984,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven if (mWifiScanner == null) { mWifiScanner = (WifiScanner) mContext.getSystemService(Context.WIFI_SCANNING_SERVICE); + mWifiConnectivityManager = new WifiConnectivityManager(mContext, + WifiStateMachine.this, mWifiScanner, mWifiConfigManager, mWifiInfo, + mWifiQualifiedNetworkSelector); } mWifiLogger.startLogging(DBG); @@ -5572,19 +5055,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, WIFI_STATE_ENABLED); mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); - mHalFeatureSet = mWifiNative.getSupportedFeatureSet(); - if ((mHalFeatureSet & WifiManager.WIFI_FEATURE_HAL_EPNO) - == WifiManager.WIFI_FEATURE_HAL_EPNO) { - mHalBasedPnoDriverSupported = true; - } - // Enable link layer stats gathering mWifiNative.setWifiLinkLayerStats("wlan0", 1); - - if (DBG) { - logd("Driverstarted State enter done, epno=" + mHalBasedPnoDriverSupported - + " feature=" + mHalFeatureSet); - } } @Override @@ -5839,8 +5311,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven } else { mWifiConfigManager.enableAllNetworks(); } - // start a scan to trigger Quality network selection - startScan(ENABLE_WIFI, 0, null, null); // Loose last selection choice since user toggled WiFi mWifiConfigManager. @@ -6106,12 +5576,22 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven @Override public void enter() { + // 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() { + // Inform WifiConnectivityManager that Wifi is disabled + if (mWifiConnectivityManager != null) { + mWifiConnectivityManager.setWifiEnabled(false); + } // Inform metrics that Wifi is being disabled (Toggled, airplane enabled, etc) mWifiMetrics.setWifiState(WifiMetricsProto.WifiLog.WIFI_DISABLED); } @@ -6138,8 +5618,10 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven } if (bssid != null) { // If we have a BSSID, tell configStore to black list it - didBlackListBSSID = mWifiQualifiedNetworkSelector - .enableBssidForQualityNetworkSelection(bssid, false); + if (mWifiConnectivityManager != null) { + didBlackListBSSID = mWifiConnectivityManager.trackBssid(bssid, + false); + } } mWifiConfigManager.updateNetworkSelectionStatus(mTargetNetworkId, @@ -6263,8 +5745,10 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven mWifiConfigManager.updateLastConnectUid(config, message.sendingUid); boolean persist = mWifiConfigManager .checkConfigOverridePermission(message.sendingUid); - mWifiQualifiedNetworkSelector - .userSelectNetwork(res, persist); + if (mWifiConnectivityManager != null) { + mWifiConnectivityManager.connectToUserSelectNetwork(res, + persist); + } // Remember time of last connection attempt lastConnectAttemptTimestamp = System.currentTimeMillis(); @@ -6326,7 +5810,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven // disable other only means select this network, does not mean all other // networks need to be disabled if (disableOthers) { - mWifiQualifiedNetworkSelector.enableNetworkByUser(config); // Remember time of last connection attempt lastConnectAttemptTimestamp = System.currentTimeMillis(); mWifiConnectionStatistics.numWifiManagerJoinAttempt++; @@ -6335,7 +5818,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven autoRoamSetBSSID(netId, "any"); int uid = message.sendingUid; - mWifiQualifiedNetworkSelector.enableNetworkByUser(config); + mWifiConfigManager.updateNetworkSelectionStatus(config, + WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE); + mWifiConfigManager.setLatestUserSelectedConfiguration(config); ok = mWifiConfigManager.enableNetwork(netId, disableOthers, uid); if (!ok) { messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL; @@ -6471,11 +5956,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven mWifiNative.disconnect(); break; case CMD_RECONNECT: - WifiConfiguration candidate = - mWifiQualifiedNetworkSelector.selectQualifiedNetwork(true, - mAllowUntrustedConnections, mScanResults, linkDebouncing, - isConnected(), isDisconnected(), isSupplicantTransientState()); - tryToConnectToNetwork(candidate); + if (mWifiConnectivityManager != null) { + mWifiConnectivityManager.forceConnectivityScan(); + } break; case CMD_REASSOCIATE: lastConnectAttemptTimestamp = System.currentTimeMillis(); @@ -6607,18 +6090,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven transitionTo(mRoamingState); } else if (didDisconnect) { transitionTo(mDisconnectingState); - } else { - /* Already in disconnected state, nothing to change */ - if (!mScreenOn && mLegacyPnoEnabled && mBackgroundScanSupported) { - int delay = 60 * 1000; - if (DBG) { - logd("Starting PNO alarm: " + delay); - } - mAlarmManager.set(AlarmManager.RTC_WAKEUP, - System.currentTimeMillis() + delay, - mPnoIntent); - } - mRestartAutoJoinOffloadCounter++; } } else { loge("Failed to connect config: " + config + " netId: " + netId); @@ -6734,7 +6205,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven mWifiConfigManager.setAndEnableLastSelectedConfiguration(netId); - mWifiQualifiedNetworkSelector.userSelectNetwork(netId, persist); + if (mWifiConnectivityManager != null) { + mWifiConnectivityManager.connectToUserSelectNetwork(netId, persist); + } didDisconnect = false; if (mLastNetworkId != WifiConfiguration.INVALID_NETWORK_ID && mLastNetworkId != netId) { @@ -6870,13 +6343,11 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven mWifiConfigManager.updateLastConnectUid(config, message.sendingUid); mWifiConfigManager.writeKnownNetworkHistory(); } - //Fixme, CMD_AUTO_SAVE_NETWORK can be cleaned - mWifiQualifiedNetworkSelector.userSelectNetwork( - result.getNetworkId(), persistConnect); - candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(true, - mAllowUntrustedConnections, mScanResults, linkDebouncing, - isConnected(), isDisconnected(), isSupplicantTransientState()); - tryToConnectToNetwork(candidate); + + if (mWifiConnectivityManager != null) { + mWifiConnectivityManager.connectToUserSelectNetwork( + result.getNetworkId(), persistConnect); + } } else { loge("Failed to save network"); messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL; @@ -6997,9 +6468,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven handleNetworkDisconnect(); transitionTo(mDisconnectedState); break; - case CMD_PNO_NETWORK_FOUND: - processPnoNetworkFound((ScanResult[]) message.obj); - break; case CMD_ADD_PASSPOINT_MO: res = mWifiConfigManager.addPasspointManagementObject((String) message.obj); replyToMessage(message, message.what, res); @@ -7897,8 +7365,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven mLastBssid = (String) message.obj; mWifiInfo.setBSSID(mLastBssid); mWifiInfo.setNetworkId(mLastNetworkId); - mWifiQualifiedNetworkSelector.enableBssidForQualityNetworkSelection( - mLastBssid, true); + if (mWifiConnectivityManager != null) { + mWifiConnectivityManager.trackBssid(mLastBssid, true); + } sendNetworkStateChangeBroadcast(mLastBssid); // Successful framework roam! (probably) @@ -7976,20 +7445,12 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven + " mScreenOn=" + mScreenOn + " scanperiod=" + Integer.toString( - mWifiConfigManager.wifiAssociatedShortScanIntervalMilli.get()) - + " useGscan=" + mHalBasedPnoDriverSupported + "/" - + mWifiConfigManager.enableHalBasedPno.get() - + " mHalBasedPnoEnableInDevSettings " + mHalBasedPnoEnableInDevSettings); - } - if (mScreenOn - && getEnableAutoJoinWhenAssociated()) { - if (useHalBasedAutoJoinOffload()) { - startGScanConnectedModeOffload("connectedEnter"); - } else { - // restart scan alarm - startDelayedScan(mWifiConfigManager.wifiAssociatedShortScanIntervalMilli.get(), - null, null); - } + mWifiConfigManager.wifiAssociatedShortScanIntervalMilli.get())); + } + + if (mWifiConnectivityManager != null) { + mWifiConnectivityManager.handleConnectionStateChanged( + WifiConnectivityManager.WIFI_STATE_CONNECTED); } registerConnected(); lastConnectAttemptTimestamp = 0; @@ -8020,35 +7481,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven logStateAndMessage(message, this); switch (message.what) { - case CMD_RESTART_AUTOJOIN_OFFLOAD: - if ( (int)message.arg2 < mRestartAutoJoinOffloadCounter ) { - messageHandlingStatus = MESSAGE_HANDLING_STATUS_OBSOLETE; - return HANDLED; - } - /* If we are still in Disconnected state after having discovered a valid - * network this means autojoin didnt managed to associate to the network, - * then restart PNO so as we will try associating to it again. - */ - if (useHalBasedAutoJoinOffload()) { - if (mGScanStartTimeMilli == 0) { - // If offload is not started, then start it... - startGScanConnectedModeOffload("connectedRestart"); - } else { - // If offload is already started, then check if we need to increase - // the scan period and restart the Gscan - long now = System.currentTimeMillis(); - if (mGScanStartTimeMilli != 0 && now > mGScanStartTimeMilli - && ((now - mGScanStartTimeMilli) - > DISCONNECTED_SHORT_SCANS_DURATION_MILLI) - && (mGScanPeriodMilli - < mWifiConfigManager - .wifiDisconnectedLongScanIntervalMilli.get())) - { - startConnectedGScan("Connected restart gscan"); - } - } - } - break; case CMD_UPDATE_ASSOCIATED_SCAN_PERMISSION: updateAssociatedScanPermission(); break; @@ -8299,7 +7731,11 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven @Override public void exit() { logd("WifiStateMachine: Leaving Connected state"); - setScanAlarm(false); + if (mWifiConnectivityManager != null) { + mWifiConnectivityManager.handleConnectionStateChanged( + WifiConnectivityManager.WIFI_STATE_TRANSITIONING); + } + mLastDriverRoamAttempt = 0; mWhiteListedSsids = null; } @@ -8313,7 +7749,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven if (DBG) { logd(" Enter DisconnectingState State scan interval " + mWifiConfigManager.wifiDisconnectedShortScanIntervalMilli.get() - + " mLegacyPnoEnabled= " + mLegacyPnoEnabled + " screenOn=" + mScreenOn); } @@ -8378,41 +7813,15 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven if (DBG) { logd(" Enter DisconnectedState scan interval " + mWifiConfigManager.wifiDisconnectedShortScanIntervalMilli.get() - + " mLegacyPnoEnabled= " + mLegacyPnoEnabled - + " screenOn=" + mScreenOn - + " useGscan=" + mHalBasedPnoDriverSupported + "/" - + mWifiConfigManager.enableHalBasedPno.get()); + + " screenOn=" + mScreenOn); } /** clear the roaming state, if we were roaming, we failed */ mAutoRoaming = false; - if (useHalBasedAutoJoinOffload()) { - startGScanDisconnectedModeOffload("disconnectedEnter"); - } else { - if (mScreenOn) { - /** - * screen lit and => start scan immediately - */ - startScan(UNKNOWN_SCAN_SOURCE, 0, null, null); - } else { - /** - * screen dark and PNO supported => scan alarm disabled - */ - if (mBackgroundScanSupported) { - /* If a regular scan result is pending, do not initiate background - * scan until the scan results are returned. This is needed because - * initiating a background scan will cancel the regular scan and - * scan results will not be returned until background scanning is - * cleared - */ - if (!mIsScanOngoing) { - enableBackgroundScan(true); - } - } else { - setScanAlarm(true); - } - } + if (mWifiConnectivityManager != null) { + mWifiConnectivityManager.handleConnectionStateChanged( + WifiConnectivityManager.WIFI_STATE_DISCONNECTED); } /** @@ -8427,7 +7836,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven } mDisconnectedTimeStamp = System.currentTimeMillis(); - mDisconnectedPnoAlarmCount = 0; } @Override public boolean processMessage(Message message) { @@ -8510,100 +7918,13 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven + " -> obsolete"); return HANDLED; } - /* Disable background scan temporarily during a regular scan */ - enableBackgroundScan(false); + handleScanRequest(message); ret = HANDLED; } else { - - /* - * The SCAN request is not handled in this state and - * would eventually might/will get handled in the - * parent's state. The PNO, if already enabled had to - * get disabled before the SCAN trigger. Hence, stop - * the PNO if already enabled in this state, though the - * SCAN request is not handled(PNO disable before the - * SCAN trigger in any other state is not the right - * place to issue). - */ - - enableBackgroundScan(false); ret = NOT_HANDLED; } break; - case CMD_RESTART_AUTOJOIN_OFFLOAD: - if ( (int)message.arg2 < mRestartAutoJoinOffloadCounter ) { - messageHandlingStatus = MESSAGE_HANDLING_STATUS_OBSOLETE; - return HANDLED; - } - /* If we are still in Disconnected state after having discovered a valid - * network this means autojoin didnt managed to associate to the network, - * then restart PNO so as we will try associating to it again. - */ - if (useHalBasedAutoJoinOffload()) { - if (mGScanStartTimeMilli == 0) { - // If offload is not started, then start it... - startGScanDisconnectedModeOffload("disconnectedRestart"); - } else { - // If offload is already started, then check if we need to increase - // the scan period and restart the Gscan - long now = System.currentTimeMillis(); - if (mGScanStartTimeMilli != 0 && now > mGScanStartTimeMilli - && ((now - mGScanStartTimeMilli) - > DISCONNECTED_SHORT_SCANS_DURATION_MILLI) - && (mGScanPeriodMilli - < mWifiConfigManager - .wifiDisconnectedLongScanIntervalMilli.get())) - { - startDisconnectedGScan("disconnected restart gscan"); - } - } - } else { - // If we are still disconnected for a short while after having found a - // network thru PNO, then something went wrong, and for some reason we - // couldn't join this network. - // It might be due to a SW bug in supplicant or the wifi stack, or an - // interoperability issue, or we try to join a bad bss and failed - // In that case we want to restart pno so as to make sure that we will - // attempt again to join that network. - if (!mScreenOn && !mIsScanOngoing && mBackgroundScanSupported) { - enableBackgroundScan(false); - enableBackgroundScan(true); - } - return HANDLED; - } - break; - case WifiMonitor.SCAN_RESULTS_EVENT: - case WifiMonitor.SCAN_FAILED_EVENT: - /* Re-enable background scan when a pending scan result is received */ - if (!mScreenOn && mIsScanOngoing - && mBackgroundScanSupported - && !useHalBasedAutoJoinOffload()) { - enableBackgroundScan(true); - } else if (!mScreenOn - && !mIsScanOngoing - && mBackgroundScanSupported - && !useHalBasedAutoJoinOffload()) { - // We receive scan results from legacy PNO, hence restart the PNO alarm - int delay; - if (mDisconnectedPnoAlarmCount < 1) { - delay = 30 * 1000; - } else if (mDisconnectedPnoAlarmCount < 3) { - delay = 60 * 1000; - } else { - delay = 360 * 1000; - } - mDisconnectedPnoAlarmCount++; - if (DBG) { - logd("Starting PNO alarm " + delay); - } - mAlarmManager.set(AlarmManager.RTC_WAKEUP, - System.currentTimeMillis() + delay, - mPnoIntent); - } - /* Handled in parent state */ - ret = NOT_HANDLED; - break; case WifiP2pServiceImpl.P2P_CONNECTION_CHANGED: NetworkInfo info = (NetworkInfo) message.obj; mP2pConnected.set(info.isConnected()); @@ -8623,13 +7944,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven // scanning at the normal period. This is necessary because scanning might // have been disabled altogether if WIFI_SCAN_INTERVAL_WHEN_P2P_CONNECTED_MS // was set to zero. - if (useHalBasedAutoJoinOffload()) { - startGScanDisconnectedModeOffload("p2pRestart"); - } else { - startDelayedScan( - mWifiConfigManager.wifiDisconnectedShortScanIntervalMilli.get(), + startDelayedScan( + mWifiConfigManager.wifiDisconnectedShortScanIntervalMilli.get(), null, null); - } } break; case CMD_RECONNECT: @@ -8654,11 +7971,10 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven @Override public void exit() { - mDisconnectedPnoAlarmCount = 0; - /* No need for a background scan upon exit from a disconnected state */ - enableBackgroundScan(false); - setScanAlarm(false); - mAlarmManager.cancel(mPnoIntent); + if (mWifiConnectivityManager != null) { + mWifiConnectivityManager.handleConnectionStateChanged( + WifiConnectivityManager.WIFI_STATE_TRANSITIONING); + } } } @@ -9205,6 +8521,26 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven } /** + * Automatically connect to the network specified + * + * @param networkId ID of the network to connect to + * @param bssid BSSID of the network + */ + public void autoConnectToNetwork(int networkId, String bssid) { + sendMessage(CMD_AUTO_CONNECT, networkId, 0, bssid); + } + + /** + * Automatically roam to the network specified + * + * @param networkId ID of the network to roam to + * @param scanResult scan result which identifies the network to roam to + */ + public void autoRoamToNetwork(int networkId, ScanResult scanResult) { + sendMessage(CMD_AUTO_ROAM, networkId, 0, scanResult); + } + + /** * @param reason reason code from supplicant on network disconnected event * @return true if this is a suspicious disconnect */ @@ -9289,57 +8625,4 @@ public class WifiStateMachine extends StateMachine implements WifiNative.PnoEven return TextUtils.join(" ", attributes); } - - /** - * Try to connect to the network of candidate. According to the current connected network, this - * API determines whether no action, disconnect and connect, or roaming. - * - * @param candidate the candidate network to connect to - */ - private void tryToConnectToNetwork(WifiConfiguration candidate) { - if (candidate == null) { - if (DBG) { - Log.d(TAG, "Try to connect to null, give up"); - } - return; - } - - ScanResult scanResultCandidate = candidate.getNetworkSelectionStatus().getCandidate(); - if (scanResultCandidate == null) { - Log.e(TAG, "tryToConnectToNetwork: bad candidate. Network:" + candidate - + " scanresult: " + scanResultCandidate); - return; - } - - String targetBssid = scanResultCandidate.BSSID; - String targetAssociationId = candidate.SSID + " : " + targetBssid; - if (targetBssid != null && targetBssid.equals(mWifiInfo.getBSSID())) { - if (DBG) { - Log.d(TAG, "tryToConnectToNetwork: Already connect to" + targetAssociationId); - } - return; - } - - WifiConfiguration currentConnectedNetwork = mWifiConfigManager - .getWifiConfiguration(mWifiInfo.getNetworkId()); - String currentAssociationId = (currentConnectedNetwork == null) ? "Disconnected" : - (mWifiInfo.getSSID() + " : " + mWifiInfo.getBSSID()); - - if (currentConnectedNetwork != null - && (currentConnectedNetwork.networkId == candidate.networkId - || currentConnectedNetwork.isLinked(candidate))) { - if (DBG) { - Log.d(TAG, "tryToConnectToNetwork: Roaming from " + currentAssociationId + " to " - + targetAssociationId); - } - sendMessage(CMD_AUTO_ROAM, candidate.networkId, 0, scanResultCandidate); - } else { - if (DBG) { - Log.d(TAG, "tryToConnectToNetwork: Reconnect from " + currentAssociationId + " to " - + targetAssociationId); - } - - sendMessage(CMD_AUTO_CONNECT, candidate.networkId, 0, scanResultCandidate.BSSID); - } - } } |