summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOscar Shu <xshu@google.com>2020-02-27 01:44:08 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2020-02-27 01:44:08 +0000
commit2d7d6154fd751d28114cc63af2af6963b125dc75 (patch)
tree7b67844e25c5163878e50a309db6cf3424e232a1
parentdd457ab2f2f359415e4ea0893a4b09136ece8223 (diff)
parent560f74b8c633834ad952a44a2a650ad63b618f83 (diff)
Merge changes from topic "duplicateScansHighMovement-rvc-dev" into rvc-dev
* changes: High movement - trigger delayed partial scan Re-trigger scan to confirm network in HIGH_MVMT
-rw-r--r--service/java/com/android/server/wifi/WifiCandidates.java30
-rw-r--r--service/java/com/android/server/wifi/WifiConnectivityManager.java154
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkSelector.java27
-rw-r--r--service/res/values/config.xml12
-rw-r--r--service/res/values/overlayable.xml3
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiCandidatesTest.java10
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java199
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java134
8 files changed, 472 insertions, 97 deletions
diff --git a/service/java/com/android/server/wifi/WifiCandidates.java b/service/java/com/android/server/wifi/WifiCandidates.java
index 8879dce5f..d62ef00ca 100644
--- a/service/java/com/android/server/wifi/WifiCandidates.java
+++ b/service/java/com/android/server/wifi/WifiCandidates.java
@@ -30,9 +30,12 @@ import com.android.wifi.resources.R;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.StringJoiner;
+import java.util.stream.Collectors;
/**
* Candidates for network selection
@@ -40,10 +43,19 @@ import java.util.StringJoiner;
public class WifiCandidates {
private static final String TAG = "WifiCandidates";
- WifiCandidates(@NonNull WifiScoreCard wifiScoreCard, @NonNull Context context) {
+ public WifiCandidates(@NonNull WifiScoreCard wifiScoreCard, @NonNull Context context) {
+ this(wifiScoreCard, context, Collections.EMPTY_LIST);
+ }
+
+ public WifiCandidates(@NonNull WifiScoreCard wifiScoreCard, @NonNull Context context,
+ @NonNull List<Candidate> candidates) {
mWifiScoreCard = Preconditions.checkNotNull(wifiScoreCard);
mContext = context;
+ for (Candidate c : candidates) {
+ mCandidates.put(c.getKey(), c);
+ }
}
+
private final WifiScoreCard mWifiScoreCard;
private final Context mContext;
@@ -356,7 +368,7 @@ public class WifiCandidates {
}
}
- private final Map<Key, CandidateImpl> mCandidates = new ArrayMap<>();
+ private final Map<Key, Candidate> mCandidates = new ArrayMap<>();
private int mCurrentNetworkId = -1;
@Nullable private MacAddress mCurrentBssid = null;
@@ -420,10 +432,10 @@ public class WifiCandidates {
double lastSelectionWeightBetweenZeroAndOne,
boolean isMetered,
int predictedThroughputMbps) {
- CandidateImpl old = mCandidates.get(key);
+ Candidate old = mCandidates.get(key);
if (old != null) {
// check if we want to replace this old candidate
- if (nominatorId > old.mNominatorId) return false;
+ if (nominatorId > old.getNominatorId()) return false;
remove(old);
}
WifiScoreCard.PerBssid perBssid = mWifiScoreCard.lookupBssid(
@@ -495,7 +507,7 @@ public class WifiCandidates {
*/
public Collection<Collection<Candidate>> getGroupedCandidates() {
Map<Integer, Collection<Candidate>> candidatesForNetworkId = new ArrayMap<>();
- for (CandidateImpl candidate : mCandidates.values()) {
+ for (Candidate candidate : mCandidates.values()) {
Collection<Candidate> cc = candidatesForNetworkId.get(candidate.getNetworkConfigId());
if (cc == null) {
cc = new ArrayList<>(2); // Guess 2 bssids per network
@@ -507,6 +519,14 @@ public class WifiCandidates {
}
/**
+ * Return a copy of the Candidates.
+ */
+ public List<Candidate> getCandidates() {
+ return mCandidates.entrySet().stream().map(entry -> entry.getValue())
+ .collect(Collectors.toList());
+ }
+
+ /**
* Make a choice from among the candidates, using the provided scorer.
*
* @return the chosen scored candidate, or ScoredCandidate.NONE.
diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java
index 14abdfe99..86cf26698 100644
--- a/service/java/com/android/server/wifi/WifiConnectivityManager.java
+++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java
@@ -34,6 +34,7 @@ import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.Process;
import android.os.WorkSource;
+import android.util.ArrayMap;
import android.util.LocalLog;
import android.util.Log;
@@ -52,7 +53,9 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
/**
* This class manages all the connectivity related scanning activities.
@@ -71,6 +74,8 @@ public class WifiConnectivityManager {
"WifiConnectivityManager Restart Single Scan";
public static final String RESTART_CONNECTIVITY_SCAN_TIMER_TAG =
"WifiConnectivityManager Restart Scan";
+ public static final String DELAYED_PARTIAL_SCAN_TIMER_TAG =
+ "WifiConnectivityManager Schedule Delayed Partial Scan Timer";
private static final long RESET_TIME_STAMP = Long.MIN_VALUE;
// Constants to indicate whether a scan should start immediately or
@@ -130,6 +135,8 @@ public class WifiConnectivityManager {
// Log tag for this class
private static final String TAG = "WifiConnectivityManager";
+ private static final String ALL_SINGLE_SCAN_LISTENER = "AllSingleScanListener";
+ private static final String PNO_SCAN_LISTENER = "PnoScanListener";
private final Context mContext;
private final ClientModeImpl mStateMachine;
@@ -168,6 +175,7 @@ public class WifiConnectivityManager {
private long mLastPeriodicSingleScanTimeStamp = RESET_TIME_STAMP;
private boolean mPnoScanStarted = false;
private boolean mPeriodicScanTimerSet = false;
+ private boolean mDelayedPartialScanTimerSet = false;
// Device configs
private boolean mWaitForFullBandScanResults = false;
@@ -186,6 +194,11 @@ public class WifiConnectivityManager {
private int mCurrentSingleScanScheduleIndex;
private int mPnoScanIntervalMs;
private WifiChannelUtilization mWifiChannelUtilization;
+ // Cached WifiCandidates used in high mobility state to avoid connecting to APs that are
+ // moving relative to the user.
+ private CachedWifiCandidates mCachedWifiCandidates = null;
+ private @DeviceMobilityState int mDeviceMobilityState =
+ WifiManager.DEVICE_MOBILITY_STATE_UNKNOWN;
// A helper to log debugging information in the local log buffer, which can
// be retrieved in bugreport.
@@ -235,6 +248,33 @@ public class WifiConnectivityManager {
}
};
+ private final AlarmManager.OnAlarmListener mDelayedPartialScanTimerListener =
+ new AlarmManager.OnAlarmListener() {
+ public void onAlarm() {
+ if (mCachedWifiCandidates == null
+ || mCachedWifiCandidates.frequencies == null
+ || mCachedWifiCandidates.frequencies.size() == 0) {
+ return;
+ }
+ ScanSettings settings = new ScanSettings();
+ settings.type = WifiScanner.SCAN_TYPE_HIGH_ACCURACY;
+ settings.band = getScanBand(false);
+ settings.reportEvents = WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT
+ | WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN;
+ settings.numBssidsPerScan = 0;
+ int index = 0;
+ settings.channels =
+ new WifiScanner.ChannelSpec[mCachedWifiCandidates.frequencies.size()];
+ for (Integer freq : mCachedWifiCandidates.frequencies) {
+ settings.channels[index++] = new WifiScanner.ChannelSpec(freq);
+ }
+ SingleScanListener singleScanListener = new SingleScanListener(false);
+ mScanner.startScan(settings, new HandlerExecutor(mEventHandler),
+ singleScanListener, WIFI_WORK_SOURCE);
+ mWifiMetrics.incrementConnectivityOneshotScanCount();
+ }
+ };
+
/**
* Handles 'onResult' callbacks for the Periodic, Single & Pno ScanListener.
* Executes selection of potential network candidates, initiation of connection attempt to that
@@ -243,7 +283,8 @@ public class WifiConnectivityManager {
* @return true - if a candidate is selected by WifiNetworkSelector
* false - if no candidate is selected by WifiNetworkSelector
*/
- private boolean handleScanResults(List<ScanDetail> scanDetails, String listenerName) {
+ private boolean handleScanResults(List<ScanDetail> scanDetails, String listenerName,
+ boolean isFullScan) {
mWifiChannelUtilization.refreshChannelStatsAndChannelUtilization(
mStateMachine.getWifiLinkLayerStats(), WifiChannelUtilization.UNKNOWN_FREQ);
@@ -259,10 +300,17 @@ public class WifiConnectivityManager {
localLog(listenerName + " onResults: start network selection");
- WifiConfiguration candidate =
- mNetworkSelector.selectNetwork(scanDetails, bssidBlocklist, mWifiInfo,
- mStateMachine.isConnected(), mStateMachine.isDisconnected(),
- mUntrustedConnectionAllowed);
+ List<WifiCandidates.Candidate> candidates = mNetworkSelector.getCandidatesFromScan(
+ scanDetails, bssidBlocklist, mWifiInfo, mStateMachine.isConnected(),
+ mStateMachine.isDisconnected(), mUntrustedConnectionAllowed);
+
+ if (mDeviceMobilityState == WifiManager.DEVICE_MOBILITY_STATE_HIGH_MVMT
+ && mContext.getResources().getBoolean(
+ R.bool.config_wifiHighMovementNetworkSelectionOptimizationEnabled)) {
+ candidates = filterCandidatesHighMovement(candidates, listenerName, isFullScan);
+ }
+
+ WifiConfiguration candidate = mNetworkSelector.selectNetwork(candidates);
mWifiLastResortWatchdog.updateAvailableNetworks(
mNetworkSelector.getConnectableScanDetails());
mWifiMetrics.countScanResults(scanDetails);
@@ -279,6 +327,57 @@ public class WifiConnectivityManager {
}
}
+ private List<WifiCandidates.Candidate> filterCandidatesHighMovement(
+ List<WifiCandidates.Candidate> candidates, String listenerName, boolean isFullScan) {
+ boolean isNotPartialScan = isFullScan || listenerName.equals(PNO_SCAN_LISTENER);
+ if (candidates == null || candidates.isEmpty()) {
+ // No connectable networks nearby or network selection is unnecessary
+ if (isNotPartialScan) {
+ mCachedWifiCandidates = new CachedWifiCandidates(mClock.getElapsedSinceBootMillis(),
+ null);
+ }
+ return null;
+ }
+
+ long minimumTimeBetweenScansMs = mContext.getResources().getInteger(
+ R.integer.config_wifiHighMovementNetworkSelectionOptimizationScanDelayMs);
+ if (mCachedWifiCandidates != null && mCachedWifiCandidates.candidateRssiMap != null) {
+ // cached candidates are too recent, wait for next scan
+ if (mClock.getElapsedSinceBootMillis() - mCachedWifiCandidates.timeSinceBootMs
+ < minimumTimeBetweenScansMs) {
+ return null;
+ }
+
+ int rssiDelta = mContext.getResources().getInteger(R.integer
+ .config_wifiHighMovementNetworkSelectionOptimizationRssiDelta);
+ List<WifiCandidates.Candidate> filteredCandidates = candidates.stream().filter(
+ item -> mCachedWifiCandidates.candidateRssiMap.containsKey(item.getKey())
+ && Math.abs(mCachedWifiCandidates.candidateRssiMap.get(item.getKey())
+ - item.getScanRssi()) < rssiDelta)
+ .collect(Collectors.toList());
+
+ if (!filteredCandidates.isEmpty()) {
+ if (isNotPartialScan) {
+ mCachedWifiCandidates =
+ new CachedWifiCandidates(mClock.getElapsedSinceBootMillis(),
+ candidates);
+ }
+ return filteredCandidates;
+ }
+ }
+
+ // Either no cached candidates, or all candidates got filtered out.
+ // Update the cached candidates here and schedule a delayed partial scan.
+ if (isNotPartialScan) {
+ mCachedWifiCandidates = new CachedWifiCandidates(mClock.getElapsedSinceBootMillis(),
+ candidates);
+ localLog("Found " + candidates.size() + " candidates at high mobility state. "
+ + "Re-doing scan to confirm network quality.");
+ scheduleDelayedPartialScan(minimumTimeBetweenScansMs);
+ }
+ return null;
+ }
+
/**
* Set whether bluetooth is in the connected state
*/
@@ -286,6 +385,27 @@ public class WifiConnectivityManager {
mNetworkSelector.setBluetoothConnected(isBluetoothConnected);
}
+ private class CachedWifiCandidates {
+ public final long timeSinceBootMs;
+ public final Map<WifiCandidates.Key, Integer> candidateRssiMap;
+ public final Set<Integer> frequencies;
+
+ CachedWifiCandidates(long timeSinceBootMs, List<WifiCandidates.Candidate> candidates) {
+ this.timeSinceBootMs = timeSinceBootMs;
+ if (candidates == null) {
+ this.candidateRssiMap = null;
+ this.frequencies = null;
+ } else {
+ this.candidateRssiMap = new ArrayMap<WifiCandidates.Key, Integer>();
+ this.frequencies = new HashSet<Integer>();
+ for (WifiCandidates.Candidate c : candidates) {
+ candidateRssiMap.put(c.getKey(), c.getScanRssi());
+ frequencies.add(c.getFrequency());
+ }
+ }
+ }
+ }
+
// All single scan results listener.
//
// Note: This is the listener for all the available single scan results,
@@ -344,7 +464,8 @@ public class WifiConnectivityManager {
Log.i(TAG, "Number of scan results ignored due to single radio chain scan: "
+ mNumScanResultsIgnoredDueToSingleRadioChain);
}
- boolean wasConnectAttempted = handleScanResults(mScanDetails, "AllSingleScanListener");
+ boolean wasConnectAttempted = handleScanResults(mScanDetails,
+ ALL_SINGLE_SCAN_LISTENER, isFullBandScanResults);
clearScanDetails();
// Update metrics to see if a single scan detected a valid network
@@ -521,7 +642,7 @@ public class WifiConnectivityManager {
}
boolean wasConnectAttempted;
- wasConnectAttempted = handleScanResults(mScanDetails, "PnoScanListener");
+ wasConnectAttempted = handleScanResults(mScanDetails, PNO_SCAN_LISTENER, false);
clearScanDetails();
mScanRestartCount = 0;
@@ -1057,6 +1178,8 @@ public class WifiConnectivityManager {
* @param newState the new device mobility state
*/
public void setDeviceMobilityState(@DeviceMobilityState int newState) {
+ mDeviceMobilityState = newState;
+ localLog("Device mobility state changed. state=" + newState);
mWifiChannelUtilization.setDeviceMobilityState(newState);
int newPnoScanIntervalMs = deviceMobilityStateToPnoScanIntervalMs(newState);
if (newPnoScanIntervalMs < 0) {
@@ -1202,6 +1325,22 @@ public class WifiConnectivityManager {
mWatchdogListener, mEventHandler);
}
+ // Schedules a delayed partial scan, which will scan the frequencies in mCachedWifiCandidates.
+ private void scheduleDelayedPartialScan(long delayMillis) {
+ mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ mClock.getElapsedSinceBootMillis() + delayMillis, DELAYED_PARTIAL_SCAN_TIMER_TAG,
+ mDelayedPartialScanTimerListener, mEventHandler);
+ mDelayedPartialScanTimerSet = true;
+ }
+
+ // Cancel the delayed partial scan timer.
+ private void cancelDelayedPartialScan() {
+ if (mDelayedPartialScanTimerSet) {
+ mAlarmManager.cancel(mDelayedPartialScanTimerListener);
+ mDelayedPartialScanTimerSet = false;
+ }
+ }
+
// Set up periodic scan timer
private void schedulePeriodicScanTimer(int intervalMs) {
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
@@ -1281,6 +1420,7 @@ public class WifiConnectivityManager {
// Due to b/28020168, timer based single scan will be scheduled
// to provide periodic scan in an exponential backoff fashion.
cancelPeriodicScanTimer();
+ cancelDelayedPartialScan();
stopPnoScan();
mScanRestartCount = 0;
}
diff --git a/service/java/com/android/server/wifi/WifiNetworkSelector.java b/service/java/com/android/server/wifi/WifiNetworkSelector.java
index dc8ac7843..60f79896b 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSelector.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSelector.java
@@ -662,6 +662,7 @@ public class WifiNetworkSelector {
return candidate;
}
+
/**
* Cleans up state that should go away when wifi is disabled.
*/
@@ -670,7 +671,7 @@ public class WifiNetworkSelector {
}
/**
- * Select the best network from the ones in range. Scan detail cache is also updated here.
+ * Returns the list of Candidates from networks in range.
*
* @param scanDetails List of ScanDetail for all the APs in range
* @param bssidBlacklist Blacklisted BSSIDs
@@ -678,11 +679,10 @@ public class WifiNetworkSelector {
* @param connected True if the device is connected
* @param disconnected True if the device is disconnected
* @param untrustedNetworkAllowed True if untrusted networks are allowed for connection
- * @return Configuration of the selected network, or Null if nothing
+ * @return list of valid Candidate(s)
*/
- @Nullable
- public WifiConfiguration selectNetwork(List<ScanDetail> scanDetails,
- Set<String> bssidBlacklist, WifiInfo wifiInfo,
+ public List<WifiCandidates.Candidate> getCandidatesFromScan(
+ List<ScanDetail> scanDetails, Set<String> bssidBlacklist, WifiInfo wifiInfo,
boolean connected, boolean disconnected, boolean untrustedNetworkAllowed) {
mFilteredNetworks.clear();
mConnectableNetworks.clear();
@@ -770,18 +770,31 @@ public class WifiNetworkSelector {
}
});
}
-
if (mConnectableNetworks.size() != wifiCandidates.size()) {
localLog("Connectable: " + mConnectableNetworks.size()
+ " Candidates: " + wifiCandidates.size());
}
+ return wifiCandidates.getCandidates();
+ }
+
+ /**
+ * Using the registered Scorers, choose the best network from the list of Candidate(s).
+ * The ScanDetailCache is also updated here.
+ * @param candidates - Candidates to perferm network selection on.
+ * @return WifiConfiguration - the selected network, or null.
+ */
+ @NonNull
+ public WifiConfiguration selectNetwork(List<WifiCandidates.Candidate> candidates) {
+ if (candidates == null || candidates.size() == 0) {
+ return null;
+ }
+ WifiCandidates wifiCandidates = new WifiCandidates(mWifiScoreCard, mContext, candidates);
final WifiCandidates.CandidateScorer activeScorer = getActiveCandidateScorer();
// Update the NetworkSelectionStatus in the configs for the current candidates
// This is needed for the legacy user connect choice, at least
Collection<Collection<WifiCandidates.Candidate>> groupedCandidates =
wifiCandidates.getGroupedCandidates();
for (Collection<WifiCandidates.Candidate> group : groupedCandidates) {
-
WifiCandidates.ScoredCandidate choice = activeScorer.scoreCandidates(group);
if (choice == null) continue;
ScanDetail scanDetail = getScanDetailForCandidateKey(choice.candidateKey);
diff --git a/service/res/values/config.xml b/service/res/values/config.xml
index fbab4df31..31156f359 100644
--- a/service/res/values/config.xml
+++ b/service/res/values/config.xml
@@ -369,6 +369,18 @@
<!-- Suspend optimization. -->
<bool translatable="false" name="config_wifiSuspendOptimizationsEnabled">true</bool>
+ <!-- Network selection optimization at DEVICE_MOBILITY_STATE_HIGH_MVMT -->
+ <bool translatable="false" name="config_wifiHighMovementNetworkSelectionOptimizationEnabled">true</bool>
+
+ <!-- Duration for the delayed scan used to verify access points are staying relatively stationary
+ to the device at high mobility state. (default = 10 seconds) -->
+ <integer translatable="false" name="config_wifiHighMovementNetworkSelectionOptimizationScanDelayMs">10000</integer>
+
+ <!-- When config_wifiHighMovementNetworkSelectionOptimizationEnabled is true, BSSIDs with RSSI
+ from 2 consecutive scans that differ in either direction by more than this threshold will be
+ filtered out from network selection. (default = 10 dBs) -->
+ <integer translatable="false" name="config_wifiHighMovementNetworkSelectionOptimizationRssiDelta">10</integer>
+
<!-- The interval in milliseconds at which wifi rtt ranging requests will be throttled when
they are coming from the background apps (default = 30 mins). -->
<integer translatable="false" name="config_wifiRttBackgroundExecGapMs">1800000</integer>
diff --git a/service/res/values/overlayable.xml b/service/res/values/overlayable.xml
index 1aa8f12bc..b1c06a1e9 100644
--- a/service/res/values/overlayable.xml
+++ b/service/res/values/overlayable.xml
@@ -117,6 +117,9 @@
<item type="bool" name="config_wifiPnoFrequencyCullingEnabled" />
<item type="bool" name="config_wifiPnoRecencySortingEnabled" />
<item type="bool" name="config_wifiSuspendOptimizationsEnabled" />
+ <item type="bool" name="config_wifiHighMovementNetworkSelectionOptimizationEnabled" />
+ <item type="integer" name="config_wifiHighMovementNetworkSelectionOptimizationScanDelayMs" />
+ <item type="integer" name="config_wifiHighMovementNetworkSelectionOptimizationRssiDelta" />
<item type="integer" name="config_wifiRttBackgroundExecGapMs" />
<item type="integer" name="config_wifiPollRssiIntervalMilliseconds" />
<item type="bool" name="config_wifiSaeUpgradeEnabled" />
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiCandidatesTest.java b/tests/wifitests/src/com/android/server/wifi/WifiCandidatesTest.java
index 9cf47cb74..4b64f71a6 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiCandidatesTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiCandidatesTest.java
@@ -113,6 +113,16 @@ public class WifiCandidatesTest extends WifiBaseTest {
}
/**
+ * Test retrieving the list of candidates.
+ */
+ @Test
+ public void testGetCandidates() {
+ assertTrue(mWifiCandidates.add(mScanDetail1, mConfig1, 2, 0.0, false, 100));
+ assertNotNull(mWifiCandidates.getCandidates());
+ assertEquals(1, mWifiCandidates.getCandidates().size());
+ }
+
+ /**
* Make sure we catch SSID mismatch due to quoting error
*/
@Test
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
index 2f231519b..3c37cdfee 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
@@ -21,6 +21,7 @@ import static com.android.server.wifi.WifiConfigurationTestUtil.generateWifiConf
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.argThat;
import android.app.test.MockAnswerUtil.AnswerWithArguments;
import android.app.test.TestAlarmManager;
@@ -55,6 +56,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatcher;
import org.mockito.Captor;
import org.mockito.InOrder;
import org.mockito.Mock;
@@ -131,6 +133,12 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
resources.setIntArray(
R.array.config_wifiSingleSavedNetworkConnectedScanIntervalScheduleSec,
SCHEDULE_EMPTY);
+ resources.setInteger(
+ R.integer.config_wifiHighMovementNetworkSelectionOptimizationScanDelayMs,
+ HIGH_MVMT_SCAN_DELAY_MS);
+ resources.setInteger(
+ R.integer.config_wifiHighMovementNetworkSelectionOptimizationRssiDelta,
+ HIGH_MVMT_RSSI_DELTA);
}
/**
@@ -169,7 +177,9 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
@Mock private WifiScoreCard mWifiScoreCard;
@Mock private WifiScoreCard.PerNetwork mPerNetwork;
@Mock private WifiScoreCard.PerNetwork mPerNetwork1;
-
+ @Mock WifiCandidates.Candidate mCandidate1;
+ @Mock WifiCandidates.Candidate mCandidate2;
+ private List<WifiCandidates.Candidate> mCandidateList;
@Captor ArgumentCaptor<ScanResult> mCandidateScanResultCaptor;
@Captor ArgumentCaptor<ArrayList<String>> mBssidBlacklistCaptor;
@Captor ArgumentCaptor<ArrayList<String>> mSsidWhitelistCaptor;
@@ -182,6 +192,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
private static final String CANDIDATE_SSID = "\"AnSsid\"";
private static final String CANDIDATE_BSSID = "6c:f3:7f:ae:8c:f3";
private static final String INVALID_SCAN_RESULT_BSSID = "6c:f3:7f:ae:8c:f4";
+ private static final int TEST_FREQUENCY = 2420;
private static final long CURRENT_SYSTEM_TIME_MS = 1000;
private static final int MAX_BSSID_BLACKLIST_SIZE = 16;
private static final int[] VALID_CONNECTED_SINGLE_SCAN_SCHEDULE = {10, 30, 50};
@@ -196,6 +207,8 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
private static final int TEST_FREQUENCY_1 = 2412;
private static final int TEST_FREQUENCY_2 = 5180;
private static final int TEST_FREQUENCY_3 = 5240;
+ private static final int HIGH_MVMT_SCAN_DELAY_MS = 10000;
+ private static final int HIGH_MVMT_RSSI_DELTA = 10;
Context mockContext() {
Context context = mock(Context.class);
@@ -302,8 +315,25 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
candidate.getNetworkSelectionStatus().setCandidate(candidateScanResult);
when(mWifiConfigManager.getConfiguredNetwork(CANDIDATE_NETWORK_ID)).thenReturn(candidate);
- when(ns.selectNetwork(anyObject(), anyObject(), anyObject(), anyBoolean(),
- anyBoolean(), anyBoolean())).thenReturn(candidate);
+ WifiCandidates.Key key = mock(WifiCandidates.Key.class);
+ when(mCandidate1.getKey()).thenReturn(key);
+ when(mCandidate1.getScanRssi()).thenReturn(-40);
+ when(mCandidate1.getFrequency()).thenReturn(TEST_FREQUENCY);
+ when(mCandidate2.getKey()).thenReturn(key);
+ when(mCandidate2.getScanRssi()).thenReturn(-60);
+ mCandidateList = new ArrayList<WifiCandidates.Candidate>();
+ mCandidateList.add(mCandidate1);
+ when(ns.getCandidatesFromScan(any(), any(), any(), anyBoolean(), anyBoolean(),
+ anyBoolean())).thenReturn(mCandidateList);
+ when(ns.selectNetwork(any()))
+ .then(new AnswerWithArguments() {
+ public WifiConfiguration answer(List<WifiCandidates.Candidate> candidateList) {
+ if (candidateList == null) {
+ return null;
+ }
+ return candidate;
+ }
+ });
return ns;
}
@@ -579,8 +609,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
*/
@Test
public void pnoRetryForLowRssiNetwork() {
- when(mWifiNS.selectNetwork(anyObject(), anyObject(), anyObject(), anyBoolean(),
- anyBoolean(), anyBoolean())).thenReturn(null);
+ when(mWifiNS.selectNetwork(any())).thenReturn(null);
// Set screen to off
mWifiConnectivityManager.handleScreenStateChanged(false);
@@ -634,8 +663,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
@Test
public void watchdogBitePnoGoodIncrementsMetrics() {
// Qns returns no candidate after watchdog single scan.
- when(mWifiNS.selectNetwork(anyObject(), anyObject(), anyObject(), anyBoolean(),
- anyBoolean(), anyBoolean())).thenReturn(null);
+ when(mWifiNS.selectNetwork(any())).thenReturn(null);
// Set screen to off
mWifiConnectivityManager.handleScreenStateChanged(false);
@@ -653,6 +681,130 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
}
/**
+ * Verify that 2 scans that are sufficiently far apart are required to initiate a connection
+ * when the high mobility scanning optimization is enabled.
+ */
+ @Test
+ public void testHighMovementNetworkSelection() {
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
+ // Enable high movement optimization
+ mResources.setBoolean(R.bool.config_wifiHighMovementNetworkSelectionOptimizationEnabled,
+ true);
+ mWifiConnectivityManager.setDeviceMobilityState(
+ WifiManager.DEVICE_MOBILITY_STATE_HIGH_MVMT);
+
+ // Set WiFi to disconnected state to trigger scan
+ mWifiConnectivityManager.handleConnectionStateChanged(
+ WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+ mLooper.dispatchAll();
+
+ // Verify there is no connection due to currently having no cached candidates.
+ verify(mClientModeImpl, never()).startConnectToNetwork(
+ CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
+
+ // Move time forward but do not cross HIGH_MVMT_SCAN_DELAY_MS yet.
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(HIGH_MVMT_SCAN_DELAY_MS - 1L);
+ // Set WiFi to disconnected state to trigger scan
+ mWifiConnectivityManager.handleConnectionStateChanged(
+ WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+ mLooper.dispatchAll();
+
+ // Verify we still don't connect because not enough time have passed since the candidates
+ // were cached.
+ verify(mClientModeImpl, never()).startConnectToNetwork(
+ CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
+
+ // Move time past HIGH_MVMT_SCAN_DELAY_MS.
+ when(mClock.getElapsedSinceBootMillis()).thenReturn((long) HIGH_MVMT_SCAN_DELAY_MS);
+ // Set WiFi to disconnected state to trigger scan
+ mWifiConnectivityManager.handleConnectionStateChanged(
+ WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+ mLooper.dispatchAll();
+
+ // Verify a candidate if found this time.
+ verify(mClientModeImpl).startConnectToNetwork(
+ CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
+ }
+
+ /**
+ * Verify that the device is initiating partial scans to verify AP stability in the high
+ * movement mobility state.
+ */
+ @Test
+ public void testHighMovementTriggerPartialScan() {
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
+ // Enable high movement optimization
+ mResources.setBoolean(R.bool.config_wifiHighMovementNetworkSelectionOptimizationEnabled,
+ true);
+ mWifiConnectivityManager.setDeviceMobilityState(
+ WifiManager.DEVICE_MOBILITY_STATE_HIGH_MVMT);
+
+ // Set WiFi to disconnected state to trigger scan
+ mWifiConnectivityManager.handleConnectionStateChanged(
+ WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+ mLooper.dispatchAll();
+ // Verify there is no connection due to currently having no cached candidates.
+ verify(mClientModeImpl, never()).startConnectToNetwork(
+ CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
+
+ // Move time forward and verify that a delayed partial scan is scheduled.
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(HIGH_MVMT_SCAN_DELAY_MS + 1L);
+ mAlarmManager.dispatch(WifiConnectivityManager.DELAYED_PARTIAL_SCAN_TIMER_TAG);
+ mLooper.dispatchAll();
+
+ verify(mWifiScanner).startScan((ScanSettings) argThat(new WifiPartialScanSettingMatcher()),
+ any(), any(), any());
+ }
+
+ private class WifiPartialScanSettingMatcher implements ArgumentMatcher<ScanSettings> {
+ @Override
+ public boolean matches(ScanSettings scanSettings) {
+ return scanSettings.band == WifiScanner.WIFI_BAND_UNSPECIFIED
+ && scanSettings.channels[0].frequency == TEST_FREQUENCY;
+ }
+ }
+
+ /**
+ * Verify that in the high movement mobility state, when the RSSI delta of a BSSID from
+ * 2 consecutive scans becomes greater than a threshold, the candidate get ignored from
+ * network selection.
+ */
+ @Test
+ public void testHighMovementRssiFilter() {
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
+ // Enable high movement optimization
+ mResources.setBoolean(R.bool.config_wifiHighMovementNetworkSelectionOptimizationEnabled,
+ true);
+ mWifiConnectivityManager.setDeviceMobilityState(
+ WifiManager.DEVICE_MOBILITY_STATE_HIGH_MVMT);
+
+ // Set WiFi to disconnected state to trigger scan
+ mWifiConnectivityManager.handleConnectionStateChanged(
+ WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+ mLooper.dispatchAll();
+
+ // Verify there is no connection due to currently having no cached candidates.
+ verify(mClientModeImpl, never()).startConnectToNetwork(
+ CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
+
+ // Move time past HIGH_MVMT_SCAN_DELAY_MS.
+ when(mClock.getElapsedSinceBootMillis()).thenReturn((long) HIGH_MVMT_SCAN_DELAY_MS);
+
+ // Mock the current Candidate to have RSSI over the filter threshold
+ mCandidateList.clear();
+ mCandidateList.add(mCandidate2);
+
+ // Set WiFi to disconnected state to trigger scan
+ mWifiConnectivityManager.handleConnectionStateChanged(
+ WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+ mLooper.dispatchAll();
+
+ // Verify connect is not started.
+ verify(mClientModeImpl, never()).startConnectToNetwork(
+ CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
+ }
+
+ /**
* {@link OpenNetworkNotifier} handles scan results on network selection.
*
* Expected behavior: ONA handles scan results
@@ -660,8 +812,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
@Test
public void wifiDisconnected_noConnectionCandidate_openNetworkNotifierScanResultsHandled() {
// no connection candidate selected
- when(mWifiNS.selectNetwork(anyObject(), anyObject(), anyObject(), anyBoolean(),
- anyBoolean(), anyBoolean())).thenReturn(null);
+ when(mWifiNS.selectNetwork(any())).thenReturn(null);
List<ScanDetail> expectedOpenNetworks = new ArrayList<>();
expectedOpenNetworks.add(
@@ -1652,9 +1803,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
candidateScanResult.SSID = CANDIDATE_SSID;
candidateScanResult.BSSID = CANDIDATE_BSSID;
candidate.getNetworkSelectionStatus().setCandidate(candidateScanResult);
-
- when(mWifiNS.selectNetwork(anyObject(), anyObject(), anyObject(), anyBoolean(),
- anyBoolean(), anyBoolean())).thenReturn(candidate);
+ when(mWifiNS.selectNetwork(any())).thenReturn(candidate);
// Set screen to on
mWifiConnectivityManager.handleScreenStateChanged(true);
@@ -1706,9 +1855,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
candidateScanResult.SSID = CANDIDATE_SSID;
candidateScanResult.BSSID = CANDIDATE_BSSID;
candidate.getNetworkSelectionStatus().setCandidate(candidateScanResult);
-
- when(mWifiNS.selectNetwork(anyObject(), anyObject(), anyObject(), anyBoolean(),
- anyBoolean(), anyBoolean())).thenReturn(candidate);
+ when(mWifiNS.selectNetwork(any())).thenReturn(candidate);
// Set screen to on
mWifiConnectivityManager.handleScreenStateChanged(true);
@@ -1796,9 +1943,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// Set up the scan result BSSID to be different from the config specified one.
candidateScanResult.BSSID = INVALID_SCAN_RESULT_BSSID;
candidate.getNetworkSelectionStatus().setCandidate(candidateScanResult);
-
- when(mWifiNS.selectNetwork(anyObject(), anyObject(), anyObject(), anyBoolean(),
- anyBoolean(), anyBoolean())).thenReturn(candidate);
+ when(mWifiNS.selectNetwork(any())).thenReturn(candidate);
// Set screen to on
mWifiConnectivityManager.handleScreenStateChanged(true);
@@ -1836,9 +1981,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// Set up the scan result BSSID to be different from the config specified one.
candidateScanResult.BSSID = INVALID_SCAN_RESULT_BSSID;
candidate.getNetworkSelectionStatus().setCandidate(candidateScanResult);
-
- when(mWifiNS.selectNetwork(anyObject(), anyObject(), anyObject(), anyBoolean(),
- anyBoolean(), anyBoolean())).thenReturn(candidate);
+ when(mWifiNS.selectNetwork(any())).thenReturn(candidate);
// Set WiFi to connected state
mWifiConnectivityManager.handleConnectionStateChanged(
@@ -1924,8 +2067,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mResources.setBoolean(
R.bool.config_wifi_framework_use_single_radio_chain_scan_results_network_selection,
false);
- when(mWifiNS.selectNetwork(any(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean()))
- .thenReturn(null);
+ when(mWifiNS.selectNetwork(any())).thenReturn(null);
mWifiConnectivityManager = createConnectivityManager();
mScanData = createScanDataWithDifferentRadioChainInfos();
@@ -1933,13 +2075,13 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// Capture scan details which were sent to network selector.
final List<ScanDetail> capturedScanDetails = new ArrayList<>();
doAnswer(new AnswerWithArguments() {
- public WifiConfiguration answer(
+ public List<WifiCandidates.Candidate> answer(
List<ScanDetail> scanDetails, Set<String> bssidBlacklist, WifiInfo wifiInfo,
boolean connected, boolean disconnected, boolean untrustedNetworkAllowed)
throws Exception {
capturedScanDetails.addAll(scanDetails);
return null;
- }}).when(mWifiNS).selectNetwork(
+ }}).when(mWifiNS).getCandidatesFromScan(
any(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean());
mWifiConnectivityManager.setTrustedConnectionAllowed(true);
@@ -1980,8 +2122,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mResources.setBoolean(
R.bool.config_wifi_framework_use_single_radio_chain_scan_results_network_selection,
true);
- when(mWifiNS.selectNetwork(any(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean()))
- .thenReturn(null);
+ when(mWifiNS.selectNetwork(any())).thenReturn(null);
mWifiConnectivityManager = createConnectivityManager();
mScanData = createScanDataWithDifferentRadioChainInfos();
@@ -1989,13 +2130,13 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// Capture scan details which were sent to network selector.
final List<ScanDetail> capturedScanDetails = new ArrayList<>();
doAnswer(new AnswerWithArguments() {
- public WifiConfiguration answer(
+ public List<WifiCandidates.Candidate> answer(
List<ScanDetail> scanDetails, Set<String> bssidBlacklist, WifiInfo wifiInfo,
boolean connected, boolean disconnected, boolean untrustedNetworkAllowed)
throws Exception {
capturedScanDetails.addAll(scanDetails);
return null;
- }}).when(mWifiNS).selectNetwork(
+ }}).when(mWifiNS).getCandidatesFromScan(
any(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean());
mWifiConnectivityManager.setTrustedConnectionAllowed(true);
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
index 0b91ea675..dcef7e11f 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
@@ -292,8 +292,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
freqs, caps, levels, securities, mWifiConfigManager, mClock);
List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
HashSet<String> blacklist = new HashSet<String>();
- WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
- blacklist, mWifiInfo, false, true, false);
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, false, true, false);
+ WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
assertEquals("Expect null configuration", null, candidate);
assertTrue(mWifiNetworkSelector.getConnectableScanDetails().isEmpty());
}
@@ -322,8 +323,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
freqs, caps, levels, securities, mWifiConfigManager, mClock);
List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
HashSet<String> blacklist = new HashSet<String>();
- WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
- blacklist, mWifiInfo, false, true, false);
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, false, true, false);
+ WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
assertEquals("Expect null configuration", null, candidate);
assertTrue(mWifiNetworkSelector.getConnectableScanDetails().isEmpty());
}
@@ -353,15 +355,17 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
freqs, caps, levels, securities, mWifiConfigManager, mClock);
List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
HashSet<String> blacklist = new HashSet<String>();
- WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
- blacklist, mWifiInfo, false, true, false);
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, false, true, false);
+ WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime()
+ WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS - 2000);
// Do another network selection with CMI in CONNECTED state.
- candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
- blacklist, mWifiInfo, true, false, false);
+ candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, true, false, false);
+ candidate = mWifiNetworkSelector.selectNetwork(candidates);
assertEquals("Expect null configuration", null, candidate);
assertTrue(mWifiNetworkSelector.getConnectableScanDetails().isEmpty());
@@ -395,16 +399,18 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
HashSet<String> blacklist = new HashSet<String>();
- WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
- blacklist, mWifiInfo, false, true, false);
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, false, true, false);
+ WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[0], candidate);
when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime()
+ WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS - 2000);
// Do another network selection with CMI in DISCONNECTED state.
- candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
- blacklist, mWifiInfo, false, true, false);
+ candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, false, true, false);
+ candidate = mWifiNetworkSelector.selectNetwork(candidates);
ScanResult chosenScanResult = scanDetails.get(0).getScanResult();
WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[0], candidate);
@@ -439,7 +445,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
// connect to test1
- mWifiNetworkSelector.selectNetwork(scanDetails, blacklist, mWifiInfo, false, true, false);
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, false, true, false);
+ WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
when(mWifiInfo.getSupplicantState()).thenReturn(SupplicantState.COMPLETED);
when(mWifiInfo.getNetworkId()).thenReturn(0);
when(mWifiInfo.getBSSID()).thenReturn(bssids[0]);
@@ -452,8 +460,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
+ WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS + 2000);
// Do another network selection.
- WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
- blacklist, mWifiInfo, true, false, false);
+ candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, true, false, false);
+ candidate = mWifiNetworkSelector.selectNetwork(candidates);
ScanResult chosenScanResult = scanDetails.get(0).getScanResult();
WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
@@ -487,7 +496,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
// connect to test1
- mWifiNetworkSelector.selectNetwork(scanDetails, blacklist, mWifiInfo, false, true, false);
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, false, true, false);
+ WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
when(mWifiInfo.getSupplicantState()).thenReturn(SupplicantState.COMPLETED);
when(mWifiInfo.getNetworkId()).thenReturn(0);
when(mWifiInfo.getBSSID()).thenReturn(bssids[0]);
@@ -507,8 +518,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
savedConfigs[0].numNoInternetAccessReports = 5;
// Do another network selection.
- WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
- blacklist, mWifiInfo, true, false, false);
+ candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, true, false, false);
+ candidate = mWifiNetworkSelector.selectNetwork(candidates);
ScanResult chosenScanResult = scanDetails.get(0).getScanResult();
WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
@@ -537,8 +549,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
// Do network selection.
- mWifiNetworkSelector.selectNetwork(scanDetails,
- blacklist, mWifiInfo, true, false, false);
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, true, false, false);
+ WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
verify(mWifiMetrics).incrementNetworkSelectionFilteredBssidCount(0);
verify(mWifiConfigManager).getConfiguredNetworks();
@@ -571,8 +584,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
HashSet<String> blacklist = new HashSet<String>();
blacklist.add(bssids[0]);
- WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
- blacklist, mWifiInfo, false, true, false);
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, false, true, false);
+ WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
verify(mWifiMetrics).incrementNetworkSelectionFilteredBssidCount(1);
assertEquals("Expect null configuration", null, candidate);
assertTrue(mWifiNetworkSelector.getConnectableScanDetails().isEmpty());
@@ -603,8 +617,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
freqs, caps, levels, securities, mWifiConfigManager, mClock);
List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
HashSet<String> blacklist = new HashSet<String>();
- WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
- blacklist, mWifiInfo, false, true, false);
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, false, true, false);
+ WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
when(mWifiInfo.getSupplicantState()).thenReturn(SupplicantState.COMPLETED);
when(mWifiInfo.getNetworkId()).thenReturn(0);
@@ -625,8 +640,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
int[] levelsNew = {mThresholdMinimumRssi2G + 40};
scanDetails = WifiNetworkSelectorTestUtil.buildScanDetails(ssidsNew, bssidsNew,
freqsNew, capsNew, levelsNew, mClock);
- candidate = mWifiNetworkSelector.selectNetwork(scanDetails, blacklist, mWifiInfo,
- true, false, false);
+ candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, true, false, false);
+ candidate = mWifiNetworkSelector.selectNetwork(candidates);
// The second network selection is skipped since current connected network is
// missing from the scan results.
@@ -714,8 +730,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
.setCandidate(scanDetailsAndConfigs.getScanDetails().get(1).getScanResult());
// With no user choice set, networkSelectorChoice should be chosen.
- WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
- blacklist, mWifiInfo, false, true, false);
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, false, true, false);
+ WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
ArgumentCaptor<Integer> nominatorIdCaptor = ArgumentCaptor.forClass(int.class);
verify(mWifiMetrics, atLeastOnce()).setNominatorForNetwork(eq(candidate.networkId),
@@ -733,8 +750,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
assertTrue(mWifiNetworkSelector.setUserConnectChoice(userChoice.networkId));
// After user connect choice is set, userChoice should override networkSelectorChoice.
- candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
- blacklist, mWifiInfo, false, true, false);
+ candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, false, true, false);
+ candidate = mWifiNetworkSelector.selectNetwork(candidates);
verify(mWifiMetrics, atLeastOnce()).setNominatorForNetwork(eq(candidate.networkId),
nominatorIdCaptor.capture());
@@ -780,8 +798,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
userChoice.getNetworkSelectionStatus()
.setCandidate(scanDetailsAndConfigs.getScanDetails().get(1).getScanResult());
- WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
- blacklist, mWifiInfo, false, true, false);
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, false, true, false);
+ WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
ArgumentCaptor<Integer> nominatorIdCaptor = ArgumentCaptor.forClass(int.class);
verify(mWifiMetrics, atLeastOnce()).setNominatorForNetwork(eq(candidate.networkId),
@@ -979,8 +998,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
HashSet<String> blacklist = new HashSet<String>();
// DummyNetworkNominator always return the first network in the scan results
// for connection, so this should connect to the first network.
- WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
- blacklist, mWifiInfo, false, true, true);
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, false, true, true);
+ WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
assertNotNull("Result should be not null", candidate);
WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
scanDetails.get(0).getScanResult(), candidate);
@@ -1002,8 +1022,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime()
+ WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS + 2000);
- candidate = mWifiNetworkSelector.selectNetwork(scanDetails, blacklist, mWifiInfo,
- true, false, false);
+ candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, true, false, false);
+ candidate = mWifiNetworkSelector.selectNetwork(candidates);
// DummyNetworkNominator always return the first network in the scan results
// for connection, so if network selection is performed, the first network should
@@ -1036,7 +1057,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
ssids, bssids, freqs, caps, levels, mClock);
HashSet<String> blacklist = new HashSet<>();
- mWifiNetworkSelector.selectNetwork(scanDetails, blacklist, mWifiInfo, false, true, false);
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, false, true, false);
+ WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
List<ScanDetail> expectedOpenUnsavedNetworks = new ArrayList<>();
expectedOpenUnsavedNetworks.add(scanDetails.get(1));
assertEquals("Expect open unsaved networks",
@@ -1066,8 +1089,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
ssids, bssids, freqs, caps, levels, mClock);
HashSet<String> blacklist = new HashSet<>();
- mWifiNetworkSelector.selectNetwork(
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
unSavedScanDetails, blacklist, mWifiInfo, false, true, false);
+ WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
assertEquals("Expect open unsaved networks",
unSavedScanDetails,
mWifiNetworkSelector.getFilteredScanDetailsForOpenUnsavedNetworks());
@@ -1077,8 +1101,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
freqs, caps, levels, securities, mWifiConfigManager, mClock);
List<ScanDetail> savedScanDetails = scanDetailsAndConfigs.getScanDetails();
- mWifiNetworkSelector.selectNetwork(
+ candidates = mWifiNetworkSelector.getCandidatesFromScan(
savedScanDetails, blacklist, mWifiInfo, false, true, false);
+ candidate = mWifiNetworkSelector.selectNetwork(candidates);
// Saved networks are filtered out.
assertTrue(mWifiNetworkSelector.getFilteredScanDetailsForOpenUnsavedNetworks().isEmpty());
}
@@ -1103,7 +1128,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
HashSet<String> blacklist = new HashSet<>();
blacklist.add(bssids[0]);
- mWifiNetworkSelector.selectNetwork(scanDetails, blacklist, mWifiInfo, false, true, false);
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, false, true, false);
+ WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
List<ScanDetail> expectedOpenUnsavedNetworks = new ArrayList<>();
expectedOpenUnsavedNetworks.add(scanDetails.get(1));
assertEquals("Expect open unsaved networks",
@@ -1130,7 +1157,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
ssids, bssids, freqs, caps, levels, mClock);
HashSet<String> blacklist = new HashSet<>();
- mWifiNetworkSelector.selectNetwork(scanDetails, blacklist, mWifiInfo, false, true, false);
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, false, true, false);
+ WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
assertTrue(mWifiNetworkSelector.getFilteredScanDetailsForOpenUnsavedNetworks().isEmpty());
}
@@ -1168,7 +1197,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
ssids, bssids, freqs, caps, levels, mClock);
HashSet<String> blacklist = new HashSet<>();
- mWifiNetworkSelector.selectNetwork(scanDetails, blacklist, mWifiInfo, false, true, false);
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, false, true, false);
+ WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
List<ScanDetail> expectedOpenUnsavedNetworks = new ArrayList<>();
expectedOpenUnsavedNetworks.add(scanDetails.get(1));
expectedOpenUnsavedNetworks.add(scanDetails.get(2));
@@ -1200,7 +1231,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
ssids, bssids, freqs, caps, levels, mClock);
HashSet<String> blacklist = new HashSet<>();
- mWifiNetworkSelector.selectNetwork(scanDetails, blacklist, mWifiInfo, false, true, false);
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, false, true, false);
+ WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
List<ScanDetail> expectedOpenUnsavedNetworks = new ArrayList<>();
expectedOpenUnsavedNetworks.add(scanDetails.get(1));
assertEquals("Expect open unsaved networks",
@@ -1225,9 +1258,10 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
mWifiNetworkSelector.registerCandidateScorer(mCandidateScorer);
- WifiConfiguration selected = mWifiNetworkSelector.selectNetwork(
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
setUpTwoNetworks(-35, -40),
EMPTY_BLACKLIST, mWifiInfo, false, true, true);
+ WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
verify(mCandidateScorer, atLeastOnce()).scoreCandidates(any());
}
@@ -1344,7 +1378,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"};
int[] levels = {mThresholdMinimumRssi2G + 1, mThresholdMinimumRssi5G + 1};
int[] securities = {SECURITY_EAP, SECURITY_EAP};
- HashSet<String> blackList = new HashSet<>();
+ HashSet<String> blacklist = new HashSet<>();
ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
freqs, caps, levels, securities, mWifiConfigManager, mClock);
@@ -1357,8 +1391,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
.thenReturn(existingConfig);
mWifiNetworkSelector.registerNetworkNominator(
new DummyNetworkNominator(0, DUMMY_NOMINATOR_ID_2));
- WifiConfiguration candidate = mWifiNetworkSelector
- .selectNetwork(scanDetails, blackList, mWifiInfo, false, true, true);
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, false, true, true);
+ WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
// Check if the wifiConfig is updated with the latest
verify(mWifiConfigManager).addOrUpdateNetwork(existingConfig,
existingConfig.creatorUid, existingConfig.creatorName);
@@ -1395,8 +1430,9 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
freqs, caps, levels, securities, mWifiConfigManager, mClock, iesByteStream);
List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
- WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
- blacklist, mWifiInfo, false, true, false);
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blacklist, mWifiInfo, false, true, false);
+ WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
assertEquals("Expect null configuration", null, candidate);
assertTrue(mWifiNetworkSelector.getConnectableScanDetails().isEmpty());
}