WCM: forced connectivity scan
WCM starts a full band single scan when user forces a connectivity
scan and wait for the full band scan results to make network
selection.
Bug: 30897947
Test: unit tests and manual test
Change-Id: Ie220c25dd60a0534afbf33f62691f32515f7062b
diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java
index 1c6ba64..49a2842 100644
--- a/service/java/com/android/server/wifi/WifiConnectivityManager.java
+++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java
@@ -150,6 +150,7 @@
private long mLastPeriodicSingleScanTimeStamp = RESET_TIME_STAMP;
private boolean mPnoScanStarted = false;
private boolean mPeriodicScanTimerSet = false;
+ private boolean mWaitForFullBandScanResults = false;
// PNO settings
private int mMin5GHzRssi;
@@ -325,9 +326,21 @@
public void onResults(WifiScanner.ScanData[] results) {
if (!mWifiEnabled || !mWifiConnectivityManagerEnabled) {
clearScanDetails();
+ mWaitForFullBandScanResults = false;
return;
}
+ // Full band scan results only.
+ if (mWaitForFullBandScanResults) {
+ if (!results[0].isAllChannelsScanned()) {
+ localLog("AllSingleScanListener waiting for full band scan results.");
+ clearScanDetails();
+ return;
+ } else {
+ mWaitForFullBandScanResults = false;
+ }
+ }
+
boolean wasConnectAttempted = handleScanResults(mScanDetails, "AllSingleScanListener");
clearScanDetails();
@@ -1078,7 +1091,8 @@
public void forceConnectivityScan() {
Log.i(TAG, "forceConnectivityScan");
- startConnectivityScan(SCAN_IMMEDIATELY);
+ mWaitForFullBandScanResults = true;
+ startSingleScan(true);
}
/**
@@ -1122,6 +1136,7 @@
stopConnectivityScan();
resetLastPeriodicSingleScanTimeStamp();
mLastConnectionAttemptBssid = null;
+ mWaitForFullBandScanResults = false;
} else if (mWifiConnectivityManagerEnabled) {
startConnectivityScan(SCAN_IMMEDIATELY);
}
@@ -1139,6 +1154,7 @@
stopConnectivityScan();
resetLastPeriodicSingleScanTimeStamp();
mLastConnectionAttemptBssid = null;
+ mWaitForFullBandScanResults = false;
} else if (mWifiEnabled) {
startConnectivityScan(SCAN_IMMEDIATELY);
}
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 5425181..a66a68f 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -5607,8 +5607,11 @@
config, disableOthers, message.sendingUid);
if (!ok) {
messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
- } else if (disableOthers) {
- mTargetNetworkId = netId;
+ } else {
+ if (disableOthers) {
+ mTargetNetworkId = netId;
+ }
+ mWifiConnectivityManager.forceConnectivityScan();
}
replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
index b1f88ec..281ffa1 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
@@ -33,6 +33,7 @@
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiScanner.PnoScanListener;
import android.net.wifi.WifiScanner.PnoSettings;
+import android.net.wifi.WifiScanner.ScanData;
import android.net.wifi.WifiScanner.ScanListener;
import android.net.wifi.WifiScanner.ScanSettings;
import android.net.wifi.WifiSsid;
@@ -71,6 +72,7 @@
mWifiStateMachine = mockWifiStateMachine();
mWifiConfigManager = mockWifiConfigManager();
mWifiInfo = getWifiInfo();
+ mScanData = mockScanData();
mWifiScanner = mockWifiScanner();
mWifiQNS = mockWifiQualifiedNetworkSelector();
mWifiConnectivityManager = new WifiConnectivityManager(mContext, mWifiStateMachine,
@@ -96,6 +98,7 @@
private WifiQualifiedNetworkSelector mWifiQNS;
private WifiStateMachine mWifiStateMachine;
private WifiScanner mWifiScanner;
+ private ScanData mScanData;
private WifiConfigManager mWifiConfigManager;
private WifiInfo mWifiInfo;
private Clock mClock = mock(Clock.class);
@@ -128,6 +131,14 @@
return context;
}
+ ScanData mockScanData() {
+ ScanData scanData = mock(ScanData.class);
+
+ when(scanData.isAllChannelsScanned()).thenReturn(true);
+
+ return scanData;
+ }
+
WifiScanner mockWifiScanner() {
WifiScanner scanner = mock(WifiScanner.class);
ArgumentCaptor<ScanListener> allSingleScanListenerCaptor =
@@ -135,9 +146,8 @@
doNothing().when(scanner).registerScanListener(allSingleScanListenerCaptor.capture());
- // dummy scan results. QNS PeriodicScanListener bulids scanDetails from
- // the fullScanResult and doesn't really use results
- final WifiScanner.ScanData[] scanDatas = new WifiScanner.ScanData[1];
+ ScanData[] scanDatas = new ScanData[1];
+ scanDatas[0] = mScanData;
// do a synchronous answer for the ScanListener callbacks
doAnswer(new AnswerWithArguments() {
@@ -756,8 +766,9 @@
currentTimeStamp += 2000;
when(mClock.elapsedRealtime()).thenReturn(currentTimeStamp);
- // Force a connectivity scan
- mWifiConnectivityManager.forceConnectivityScan();
+ // Allow untrusted networks so WifiConnectivityManager starts a periodic scan
+ // immediately.
+ mWifiConnectivityManager.setUntrustedConnectionAllowed(true);
// Get the second periodic scan actual time stamp. Note, this scan is not
// started from the AlarmManager.
@@ -944,4 +955,41 @@
verify(mWifiStateMachine).autoConnectToNetwork(
CANDIDATE_NETWORK_ID, CANDIDATE_BSSID);
}
+
+ /**
+ * Verify that a forced connectivity scan waits for full band scan
+ * results.
+ *
+ * Expected behavior: WifiConnectivityManager doesn't invoke
+ * WifiStateMachine.autoConnectToNetwork() when full band scan
+ * results are not available.
+ */
+ @Test
+ public void waitForFullBandScanResults() {
+ // Set WiFi to connected state.
+ mWifiConnectivityManager.handleConnectionStateChanged(
+ WifiConnectivityManager.WIFI_STATE_CONNECTED);
+
+ // Set up as partial scan results.
+ when(mScanData.isAllChannelsScanned()).thenReturn(false);
+
+ // Force a connectivity scan which enables WifiConnectivityManager
+ // to wait for full band scan results.
+ mWifiConnectivityManager.forceConnectivityScan();
+
+ // No roaming because no full band scan results.
+ verify(mWifiStateMachine, times(0)).autoConnectToNetwork(
+ CANDIDATE_NETWORK_ID, CANDIDATE_BSSID);
+
+ // Set up as full band scan results.
+ when(mScanData.isAllChannelsScanned()).thenReturn(true);
+
+ // Force a connectivity scan which enables WifiConnectivityManager
+ // to wait for full band scan results.
+ mWifiConnectivityManager.forceConnectivityScan();
+
+ // Roaming attempt because full band scan results are available.
+ verify(mWifiStateMachine).autoConnectToNetwork(
+ CANDIDATE_NETWORK_ID, CANDIDATE_BSSID);
+ }
}