summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorMitchell Wills <mwills@google.com>2015-11-03 17:16:09 -0800
committerRoshan Pius <rpius@google.com>2016-03-09 20:05:08 -0800
commit8adb4e72f58e3e25918f33e0b2687e6acc14c47d (patch)
tree207b349128f3f634b883efe5c187a7191eb12fa4 /tests
parent01fb5b27ba32f180080f2b2b12adbc5c803611ce (diff)
Refactor WifiScanner support for oneshot scans
Seperate oneshot scans so they are no longer implemented using background scans and make WifiStateMachine use WifiScanner for single scans. This changes requires a few parts: 1. Implement single scan logic in WifiScanningServiceImpl for merging and executing scan requests using the single scan native interface. 2. Writing tests for the new code in 1 3. Make supplicant start scans by using WifiScanner and when it recieves callbacks dispatch scan complete/failure messages. 4. Enable HalWifiScannerImpl and SupplicantWifiScannerImpl to listen to supplicant scan events now that WifiStateMachine does not. Bug: 26525037 Bug: 26895774 Change-Id: I7d03b43bbd2be396b3c772bc4bae681acce8eb7b
Diffstat (limited to 'tests')
-rw-r--r--tests/wifitests/src/com/android/server/wifi/BaseWifiScannerImplTest.java1
-rw-r--r--tests/wifitests/src/com/android/server/wifi/HalWifiScannerTest.java12
-rw-r--r--tests/wifitests/src/com/android/server/wifi/MultiClientSchedulerTest.java43
-rw-r--r--tests/wifitests/src/com/android/server/wifi/ScanResults.java27
-rw-r--r--tests/wifitests/src/com/android/server/wifi/ScanTestUtil.java36
-rw-r--r--tests/wifitests/src/com/android/server/wifi/SupplicantWifiScannerTest.java11
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiScanningServiceTest.java460
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java62
8 files changed, 581 insertions, 71 deletions
diff --git a/tests/wifitests/src/com/android/server/wifi/BaseWifiScannerImplTest.java b/tests/wifitests/src/com/android/server/wifi/BaseWifiScannerImplTest.java
index baf317280..6d4edb40d 100644
--- a/tests/wifitests/src/com/android/server/wifi/BaseWifiScannerImplTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/BaseWifiScannerImplTest.java
@@ -199,7 +199,6 @@ public abstract class BaseWifiScannerImplTest {
WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
ScanResults results = ScanResults.create(0, 2400, 2450, 2450);
- Set<Integer> expectedScan = createFreqSet(2400, 2450);
InOrder order = inOrder(eventHandler, mWifiNative);
diff --git a/tests/wifitests/src/com/android/server/wifi/HalWifiScannerTest.java b/tests/wifitests/src/com/android/server/wifi/HalWifiScannerTest.java
index 3ef073ce6..11acea80d 100644
--- a/tests/wifitests/src/com/android/server/wifi/HalWifiScannerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/HalWifiScannerTest.java
@@ -18,13 +18,10 @@ package com.android.server.wifi;
import static com.android.server.wifi.ScanTestUtil.setupMockChannels;
-import android.os.Handler;
import android.test.suitebuilder.annotation.SmallTest;
import org.junit.Before;
-import java.lang.reflect.Field;
-
/**
* Unit tests for {@link com.android.server.wifi.HalWifiScannerImpl}.
*/
@@ -38,14 +35,5 @@ public class HalWifiScannerTest extends BaseWifiScannerImplTest {
new int[]{5150, 5175},
new int[]{5600, 5650});
mScanner = new HalWifiScannerImpl(mWifiNative, mLooper.getLooper());
-
- // TODO remove this once HalWifiScannerImpl wifi monitor registration is enabled
- Field eventHandlerField = HalWifiScannerImpl.class.getDeclaredField("mEventHandler");
- eventHandlerField.setAccessible(true);
- Handler eventHandler = (Handler) eventHandlerField.get(mScanner);
- WifiMonitor.getInstance().registerHandler(mWifiNative.getInterfaceName(),
- WifiMonitor.SCAN_FAILED_EVENT, eventHandler);
- WifiMonitor.getInstance().registerHandler(mWifiNative.getInterfaceName(),
- WifiMonitor.SCAN_RESULTS_EVENT, eventHandler);
}
}
diff --git a/tests/wifitests/src/com/android/server/wifi/MultiClientSchedulerTest.java b/tests/wifitests/src/com/android/server/wifi/MultiClientSchedulerTest.java
index f0e8e95b8..86db34cb6 100644
--- a/tests/wifitests/src/com/android/server/wifi/MultiClientSchedulerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/MultiClientSchedulerTest.java
@@ -16,6 +16,8 @@
package com.android.server.wifi;
+import static com.android.server.wifi.ScanTestUtil.NativeScanSettingsBuilder;
+import static com.android.server.wifi.ScanTestUtil.assertNativeScanSettingsEquals;
import static com.android.server.wifi.ScanTestUtil.channelsToSpec;
import static com.android.server.wifi.ScanTestUtil.createRequest;
@@ -465,36 +467,23 @@ public class MultiClientSchedulerTest {
mScheduler.updateSchedule(requests);
WifiNative.ScanSettings schedule = mScheduler.getSchedule();
- assertEquals("base_period_ms", computeExpectedPeriod(settings.periodInMs),
- schedule.base_period_ms);
- assertBuckets(schedule, 1);
+ int expectedPeriod = computeExpectedPeriod(settings.periodInMs);
+ NativeScanSettingsBuilder expectedBuilder = new NativeScanSettingsBuilder()
+ .withBasePeriod(expectedPeriod)
+ .withMaxApPerScan(settings.numBssidsPerScan == 0
+ ? DEFAULT_MAX_AP_PER_SCAN
+ : settings.numBssidsPerScan)
+ .withMaxScansToCache(settings.maxScansToCache == 0
+ ? DEFAULT_MAX_BATCH
+ : settings.maxScansToCache);
- if (settings.numBssidsPerScan == 0) {
- assertEquals("bssids per scan", DEFAULT_MAX_AP_PER_SCAN, schedule.max_ap_per_scan);
- } else {
- assertEquals("bssids per scan", settings.numBssidsPerScan, schedule.max_ap_per_scan);
- }
- if (settings.maxScansToCache == 0) {
- assertEquals("scans to cache", DEFAULT_MAX_BATCH,
- schedule.report_threshold_num_scans);
- } else {
- assertEquals("scans to cache", settings.maxScansToCache,
- schedule.report_threshold_num_scans);
- }
- assertEquals("reportEvents", settings.reportEvents, schedule.buckets[0].report_events);
- assertEquals("period", computeExpectedPeriod(settings.periodInMs),
- schedule.buckets[0].period_ms);
if (settings.band == WifiScanner.WIFI_BAND_UNSPECIFIED) {
- assertEquals("band", settings.band, schedule.buckets[0].band);
- assertEquals("channels", getAllChannels(settings),
- getAllChannels(schedule.buckets[0]));
- }
- else {
- assertEquals("band", settings.band, schedule.buckets[0].band);
- assertEquals("num_channels", 0, schedule.buckets[0].num_channels);
- assertTrue("channels", schedule.buckets[0].channels == null
- || schedule.buckets[0].channels.length == 0);
+ expectedBuilder.addBucketWithChannels(expectedPeriod, settings.reportEvents,
+ settings.channels);
+ } else {
+ expectedBuilder.addBucketWithBand(expectedPeriod, settings.reportEvents, settings.band);
}
+ assertNativeScanSettingsEquals(expectedBuilder.build(), schedule);
}
private void assertBuckets(WifiNative.ScanSettings schedule, int numBuckets) {
diff --git a/tests/wifitests/src/com/android/server/wifi/ScanResults.java b/tests/wifitests/src/com/android/server/wifi/ScanResults.java
index f628cac93..9c452fb21 100644
--- a/tests/wifitests/src/com/android/server/wifi/ScanResults.java
+++ b/tests/wifitests/src/com/android/server/wifi/ScanResults.java
@@ -26,6 +26,7 @@ import java.math.BigInteger;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Random;
@@ -38,6 +39,32 @@ public class ScanResults {
private final ScanData mScanData;
private final ScanResult[] mScanResults;
+ private ScanResults(ArrayList<ScanDetail> scanDetails, ScanData scanData,
+ ScanResult[] scanResults) {
+ mScanDetails.addAll(scanDetails);
+ mScanData = scanData;
+ mScanResults = scanResults;
+ }
+
+ /**
+ * Merge the results contained in a number of ScanResults into a single ScanResults
+ */
+ public static ScanResults merge(ScanResults... others) {
+ ArrayList<ScanDetail> scanDetails = new ArrayList<>();
+ ArrayList<ScanResult> scanDataResults = new ArrayList<>();
+ ArrayList<ScanResult> rawScanResults = new ArrayList<>();
+ for (ScanResults other : others) {
+ scanDetails.addAll(other.getScanDetailArrayList());
+ scanDataResults.addAll(Arrays.asList(other.getScanData().getResults()));
+ rawScanResults.addAll(Arrays.asList(other.getRawScanResults()));
+ }
+ Collections.sort(scanDataResults, SCAN_RESULT_RSSI_COMPARATOR);
+ int id = others[0].getScanData().getId();
+ return new ScanResults(scanDetails, new ScanData(id, 0, scanDataResults
+ .toArray(new ScanResult[scanDataResults.size()])),
+ rawScanResults.toArray(new ScanResult[rawScanResults.size()]));
+ }
+
private static String generateBssid(Random r) {
return String.format("%02X:%02X:%02X:%02X:%02X:%02X",
r.nextInt(256), r.nextInt(256), r.nextInt(256),
diff --git a/tests/wifitests/src/com/android/server/wifi/ScanTestUtil.java b/tests/wifitests/src/com/android/server/wifi/ScanTestUtil.java
index de46dff42..34793cd8f 100644
--- a/tests/wifitests/src/com/android/server/wifi/ScanTestUtil.java
+++ b/tests/wifitests/src/com/android/server/wifi/ScanTestUtil.java
@@ -171,6 +171,42 @@ public class ScanTestUtil {
}
}
+ /**
+ * Compute the expected native scan settings that are expected for the given
+ * WifiScanner.ScanSettings.
+ */
+ public static WifiNative.ScanSettings computeSingleScanNativeSettings(
+ WifiScanner.ScanSettings requestSettings) {
+ int reportEvents = requestSettings.reportEvents | WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN;
+ NativeScanSettingsBuilder builder = new NativeScanSettingsBuilder()
+ .withBasePeriod(0)
+ .withMaxApPerScan(0)
+ .withMaxPercentToCache(0)
+ .withMaxScansToCache(0);
+ if (requestSettings.band == WifiScanner.WIFI_BAND_UNSPECIFIED) {
+ builder.addBucketWithChannels(0, reportEvents, requestSettings.channels);
+ } else {
+ builder.addBucketWithBand(0, reportEvents, requestSettings.band);
+ }
+
+ return builder.build();
+ }
+
+ /**
+ * Compute the expected native scan settings that are expected for the given channels.
+ */
+ public static WifiNative.ScanSettings createSingleScanNativeSettingsForChannels(
+ int reportEvents, WifiScanner.ChannelSpec... channels) {
+ int actualReportEvents = reportEvents | WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN;
+ return new NativeScanSettingsBuilder()
+ .withBasePeriod(0)
+ .withMaxApPerScan(0)
+ .withMaxPercentToCache(0)
+ .withMaxScansToCache(0)
+ .addBucketWithChannels(0, actualReportEvents, channels)
+ .build();
+ }
+
public static Set<Integer> createFreqSet(int... elements) {
Set<Integer> set = new HashSet<>();
for (int e : elements) {
diff --git a/tests/wifitests/src/com/android/server/wifi/SupplicantWifiScannerTest.java b/tests/wifitests/src/com/android/server/wifi/SupplicantWifiScannerTest.java
index 72e9da5ec..f3adb119e 100644
--- a/tests/wifitests/src/com/android/server/wifi/SupplicantWifiScannerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/SupplicantWifiScannerTest.java
@@ -31,14 +31,12 @@ import static org.mockito.Mockito.when;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiSsid;
-import android.os.Handler;
import android.test.suitebuilder.annotation.SmallTest;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InOrder;
-import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
@@ -53,15 +51,6 @@ public class SupplicantWifiScannerTest extends BaseWifiScannerImplTest {
public void setup() throws Exception {
mScanner = new SupplicantWifiScannerImpl(mContext, mWifiNative,
mLooper.getLooper());
-
- // TODO remove this once SupplicantWifiScannerImpl wifi monitor registration is enabled
- Field eventHandlerField = SupplicantWifiScannerImpl.class.getDeclaredField("mEventHandler");
- eventHandlerField.setAccessible(true);
- Handler eventHandler = (Handler) eventHandlerField.get(mScanner);
- WifiMonitor.getInstance().registerHandler(mWifiNative.getInterfaceName(),
- WifiMonitor.SCAN_FAILED_EVENT, eventHandler);
- WifiMonitor.getInstance().registerHandler(mWifiNative.getInterfaceName(),
- WifiMonitor.SCAN_RESULTS_EVENT, eventHandler);
}
@Test
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiScanningServiceTest.java b/tests/wifitests/src/com/android/server/wifi/WifiScanningServiceTest.java
index 853c895bd..3d4055a52 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiScanningServiceTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiScanningServiceTest.java
@@ -16,13 +16,19 @@
package com.android.server.wifi;
+import static com.android.server.wifi.ScanTestUtil.NativeScanSettingsBuilder;
import static com.android.server.wifi.ScanTestUtil.assertNativeScanSettingsEquals;
import static com.android.server.wifi.ScanTestUtil.assertScanDatasEquals;
+import static com.android.server.wifi.ScanTestUtil.channelsToSpec;
+import static com.android.server.wifi.ScanTestUtil.computeSingleScanNativeSettings;
import static com.android.server.wifi.ScanTestUtil.createRequest;
+import static com.android.server.wifi.ScanTestUtil.createSingleScanNativeSettingsForChannels;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@@ -54,6 +60,7 @@ import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.mockito.internal.matchers.CapturingMatcher;
/**
* Unit tests for {@link com.android.server.wifi.WifiScanningServiceImpl}.
@@ -63,6 +70,7 @@ public class WifiScanningServiceTest {
public static final String TAG = "WifiScanningServiceTest";
@Mock Context mContext;
+ MockAlarmManager mAlarmManager;
@Mock WifiScannerImpl mWifiScannerImpl;
@Mock WifiScannerImpl.WifiScannerImplFactory mWifiScannerImplFactory;
@Mock IBatteryStats mBatteryStats;
@@ -73,6 +81,10 @@ public class WifiScanningServiceTest {
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
+ mAlarmManager = new MockAlarmManager();
+ when(mContext.getSystemService(Context.ALARM_SERVICE))
+ .thenReturn(mAlarmManager.getAlarmManager());
+
ChannelHelper channelHelper = new PresetKnownBandsChannelHelper(
new int[]{2400, 2450},
new int[]{5150, 5175},
@@ -117,9 +129,22 @@ public class WifiScanningServiceTest {
return messageCaptor.getValue();
}
+ private Message verifyHandleMessageAndGetMessage(InOrder order, Handler handler,
+ final int what) {
+ CapturingMatcher<Message> messageMatcher = new CapturingMatcher<Message>() {
+ public boolean matches(Object argument) {
+ Message message = (Message) argument;
+ return message.what == what;
+ }
+ };
+ order.verify(handler).handleMessage(argThat(messageMatcher));
+ return messageMatcher.getLastValue();
+ }
+
private void verifyScanResultsRecieved(InOrder order, Handler handler, int listenerId,
WifiScanner.ScanData... expected) {
- Message scanResultMessage = verifyHandleMessageAndGetMessage(order, handler);
+ Message scanResultMessage = verifyHandleMessageAndGetMessage(order, handler,
+ WifiScanner.CMD_SCAN_RESULT);
assertScanResultsMessage(listenerId, expected, scanResultMessage);
}
@@ -131,12 +156,29 @@ public class WifiScanningServiceTest {
((WifiScanner.ParcelableScanData) scanResultMessage.obj).getResults());
}
+ private void verifySingleScanCompletedRecieved(InOrder order, Handler handler, int listenerId) {
+ Message completedMessage = verifyHandleMessageAndGetMessage(order, handler,
+ WifiScanner.CMD_SINGLE_SCAN_COMPLETED);
+ assertSingleScanCompletedMessage(listenerId, completedMessage);
+ }
+
+ private void assertSingleScanCompletedMessage(int listenerId, Message completedMessage) {
+ assertEquals("what", WifiScanner.CMD_SINGLE_SCAN_COMPLETED, completedMessage.what);
+ assertEquals("listenerId", listenerId, completedMessage.arg2);
+ }
+
private void sendBackgroundScanRequest(BidirectionalAsyncChannel controlChannel,
int scanRequestId, WifiScanner.ScanSettings settings) {
controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_START_BACKGROUND_SCAN, 0,
scanRequestId, settings));
}
+ private void sendSingleScanRequest(BidirectionalAsyncChannel controlChannel,
+ int scanRequestId, WifiScanner.ScanSettings settings) {
+ controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_START_SINGLE_SCAN, 0,
+ scanRequestId, settings));
+ }
+
private void verifySuccessfulResponse(InOrder order, Handler handler, int arg2) {
Message response = verifyHandleMessageAndGetMessage(order, handler);
assertSuccessfulResponse(arg2, response);
@@ -174,6 +216,18 @@ public class WifiScanningServiceTest {
}
}
+ private WifiNative.ScanEventHandler verifyStartSingleScan(InOrder order,
+ WifiNative.ScanSettings expected) {
+ ArgumentCaptor<WifiNative.ScanSettings> scanSettingsCaptor =
+ ArgumentCaptor.forClass(WifiNative.ScanSettings.class);
+ ArgumentCaptor<WifiNative.ScanEventHandler> scanEventHandlerCaptor =
+ ArgumentCaptor.forClass(WifiNative.ScanEventHandler.class);
+ order.verify(mWifiScannerImpl).startSingleScan(scanSettingsCaptor.capture(),
+ scanEventHandlerCaptor.capture());
+ assertNativeScanSettingsEquals(expected, scanSettingsCaptor.getValue());
+ return scanEventHandlerCaptor.getValue();
+ }
+
private void verifyStartBackgroundScan(InOrder order, WifiNative.ScanSettings expected) {
ArgumentCaptor<WifiNative.ScanSettings> scanSettingsCaptor =
ArgumentCaptor.forClass(WifiNative.ScanSettings.class);
@@ -182,6 +236,7 @@ public class WifiScanningServiceTest {
assertNativeScanSettingsEquals(expected, scanSettingsCaptor.getValue());
}
+ private static final int MAX_AP_PER_SCAN = 16;
private void startServiceAndLoadDriver() {
mWifiScanningServiceImpl.startService();
when(mWifiScannerImpl.getScanCapabilities(any(WifiNative.ScanCapabilities.class)))
@@ -189,7 +244,7 @@ public class WifiScanningServiceTest {
public boolean answer(WifiNative.ScanCapabilities capabilities) {
capabilities.max_scan_cache_size = Integer.MAX_VALUE;
capabilities.max_scan_buckets = 8;
- capabilities.max_ap_cache_per_scan = 16;
+ capabilities.max_ap_cache_per_scan = MAX_AP_PER_SCAN;
capabilities.max_rssi_sample_size = 8;
capabilities.max_scan_reporting_threshold = 10;
capabilities.max_hotlist_bssids = 0;
@@ -209,7 +264,7 @@ public class WifiScanningServiceTest {
@Test
public void construct() throws Exception {
- verifyNoMoreInteractions(mContext, mWifiScannerImpl, mWifiScannerImpl,
+ verifyNoMoreInteractions(mWifiScannerImpl, mWifiScannerImpl,
mWifiScannerImplFactory, mBatteryStats);
}
@@ -253,4 +308,403 @@ public class WifiScanningServiceTest {
verifyFailedResponse(order, handler, 0, WifiScanner.REASON_INVALID_REQUEST,
"Invalid request");
}
+
+ private void doSuccessfulSingleScan(WifiScanner.ScanSettings requestSettings,
+ WifiNative.ScanSettings nativeSettings, ScanResults results) {
+ int requestId = 12;
+ startServiceAndLoadDriver();
+
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder order = inOrder(handler, mWifiScannerImpl);
+
+ when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ any(WifiNative.ScanEventHandler.class))).thenReturn(true);
+
+ sendSingleScanRequest(controlChannel, requestId, requestSettings);
+
+ mLooper.dispatchAll();
+ WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(order, nativeSettings);
+ verifySuccessfulResponse(order, handler, requestId);
+
+ when(mWifiScannerImpl.getLatestSingleScanResults())
+ .thenReturn(results.getScanData());
+ eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
+
+ mLooper.dispatchAll();
+ verifyScanResultsRecieved(order, handler, requestId, results.getScanData());
+ verifySingleScanCompletedRecieved(order, handler, requestId);
+ verifyNoMoreInteractions(handler);
+ }
+
+ /**
+ * Do a single scan for a band and verify that it is successful.
+ */
+ @Test
+ public void sendSingleScanBandRequest() throws Exception {
+ WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings),
+ ScanResults.create(0, 2400, 5150, 5175));
+ }
+
+ /**
+ * Do a single scan for a list of channels and verify that it is successful.
+ */
+ @Test
+ public void sendSingleScanChannelsRequest() throws Exception {
+ WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings),
+ ScanResults.create(0, 2400, 5150, 5175));
+ }
+
+ /**
+ * Do a single scan, which the hardware fails to start, and verify that a failure response is
+ * delivered.
+ */
+ @Test
+ public void sendSingleScanRequestWhichFailsToStart() throws Exception {
+ WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ int requestId = 33;
+
+ startServiceAndLoadDriver();
+
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder order = inOrder(handler, mWifiScannerImpl);
+
+ // scan fails
+ when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ any(WifiNative.ScanEventHandler.class))).thenReturn(false);
+
+ sendSingleScanRequest(controlChannel, requestId, requestSettings);
+
+ mLooper.dispatchAll();
+ // Scan is successfully queue, but then fails to execute
+ ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
+ order.verify(handler, times(2)).handleMessage(messageCaptor.capture());
+ assertSuccessfulResponse(requestId, messageCaptor.getAllValues().get(0));
+ assertFailedResponse(requestId, WifiScanner.REASON_UNSPECIFIED,
+ "Failed to start single scan", messageCaptor.getAllValues().get(1));
+ }
+
+ /**
+ * Do a single scan, which successfully starts, but fails partway through and verify that a
+ * failure response is delivered.
+ */
+ @Test
+ public void sendSingleScanRequestWhichFailsAfterStart() throws Exception {
+ WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ int requestId = 33;
+
+ startServiceAndLoadDriver();
+
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder order = inOrder(handler, mWifiScannerImpl);
+
+ // successful start
+ when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ any(WifiNative.ScanEventHandler.class))).thenReturn(true);
+
+ sendSingleScanRequest(controlChannel, requestId, requestSettings);
+
+ // Scan is successfully queue
+ mLooper.dispatchAll();
+ WifiNative.ScanEventHandler eventHandler =
+ verifyStartSingleScan(order, computeSingleScanNativeSettings(requestSettings));
+ verifySuccessfulResponse(order, handler, requestId);
+
+ // but then fails to execute
+ eventHandler.onScanStatus(WifiNative.WIFI_SCAN_FAILED);
+ mLooper.dispatchAll();
+ verifyFailedResponse(order, handler, requestId,
+ WifiScanner.REASON_UNSPECIFIED, "Scan failed");
+ }
+
+ // TODO Add more single scan tests
+ // * disable wifi while scanning
+ // * disable wifi while scanning with pending scan
+
+ /**
+ * Send a single scan request and then a second one after the first completes.
+ */
+ @Test
+ public void sendSingleScanRequestAfterPreviousCompletes() {
+ WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ int requestId1 = 12;
+ ScanResults results1 = ScanResults.create(0, 2400);
+
+
+ WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ int requestId2 = 13;
+ ScanResults results2 = ScanResults.create(0, 2450);
+
+
+ startServiceAndLoadDriver();
+
+ when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ any(WifiNative.ScanEventHandler.class))).thenReturn(true);
+
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder order = inOrder(handler, mWifiScannerImpl);
+
+ // Run scan 1
+ sendSingleScanRequest(controlChannel, requestId1, requestSettings1);
+
+ mLooper.dispatchAll();
+ WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(order,
+ computeSingleScanNativeSettings(requestSettings1));
+ verifySuccessfulResponse(order, handler, requestId1);
+
+ // dispatch scan 1 results
+ when(mWifiScannerImpl.getLatestSingleScanResults())
+ .thenReturn(results1.getScanData());
+ eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
+
+ mLooper.dispatchAll();
+ verifyScanResultsRecieved(order, handler, requestId1, results1.getScanData());
+ verifySingleScanCompletedRecieved(order, handler, requestId1);
+
+ // Run scan 2
+ sendSingleScanRequest(controlChannel, requestId2, requestSettings2);
+
+ mLooper.dispatchAll();
+ WifiNative.ScanEventHandler eventHandler2 = verifyStartSingleScan(order,
+ computeSingleScanNativeSettings(requestSettings2));
+ verifySuccessfulResponse(order, handler, requestId2);
+
+ // dispatch scan 2 results
+ when(mWifiScannerImpl.getLatestSingleScanResults())
+ .thenReturn(results2.getScanData());
+ eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
+
+ mLooper.dispatchAll();
+ verifyScanResultsRecieved(order, handler, requestId2, results2.getScanData());
+ verifySingleScanCompletedRecieved(order, handler, requestId2);
+ }
+
+ /**
+ * Send a single scan request and then a second one before the first completes.
+ * Verify that both are scheduled and succeed.
+ */
+ @Test
+ public void sendSingleScanRequestWhilePreviousScanRunning() {
+ WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ int requestId1 = 12;
+ ScanResults results1 = ScanResults.create(0, 2400);
+
+ WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ int requestId2 = 13;
+ ScanResults results2 = ScanResults.create(0, 2450);
+
+
+ startServiceAndLoadDriver();
+
+ when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ any(WifiNative.ScanEventHandler.class))).thenReturn(true);
+
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder handlerOrder = inOrder(handler);
+ InOrder nativeOrder = inOrder(mWifiScannerImpl);
+
+ // Run scan 1
+ sendSingleScanRequest(controlChannel, requestId1, requestSettings1);
+
+ mLooper.dispatchAll();
+ WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(nativeOrder,
+ computeSingleScanNativeSettings(requestSettings1));
+ verifySuccessfulResponse(handlerOrder, handler, requestId1);
+
+ // Queue scan 2 (will not run because previous is in progress)
+ sendSingleScanRequest(controlChannel, requestId2, requestSettings2);
+ mLooper.dispatchAll();
+ verifySuccessfulResponse(handlerOrder, handler, requestId2);
+
+ // dispatch scan 1 results
+ when(mWifiScannerImpl.getLatestSingleScanResults())
+ .thenReturn(results1.getScanData());
+ eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
+
+ mLooper.dispatchAll();
+ verifyScanResultsRecieved(handlerOrder, handler, requestId1, results1.getScanData());
+ verifySingleScanCompletedRecieved(handlerOrder, handler, requestId1);
+
+ // now that the first scan completed we expect the second one to start
+ WifiNative.ScanEventHandler eventHandler2 = verifyStartSingleScan(nativeOrder,
+ computeSingleScanNativeSettings(requestSettings2));
+
+ // dispatch scan 2 results
+ when(mWifiScannerImpl.getLatestSingleScanResults())
+ .thenReturn(results2.getScanData());
+ eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
+
+ mLooper.dispatchAll();
+ verifyScanResultsRecieved(handlerOrder, handler, requestId2, results2.getScanData());
+ verifySingleScanCompletedRecieved(handlerOrder, handler, requestId2);
+ }
+
+
+
+ /**
+ * Send a single scan request and then two more before the first completes.
+ * Verify that the first completes and the second two are merged.
+ */
+ @Test
+ public void sendMultipleSingleScanRequestWhilePreviousScanRunning() {
+ WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ int requestId1 = 12;
+ ScanResults results1 = ScanResults.create(0, 2400);
+
+ WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ int requestId2 = 13;
+ ScanResults results2 = ScanResults.create(0, 2450, 5175, 2450);
+
+ WifiScanner.ScanSettings requestSettings3 = createRequest(channelsToSpec(5150), 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ int requestId3 = 15;
+ ScanResults results3 = ScanResults.create(0, 5150, 5150, 5150, 5150);
+
+ WifiNative.ScanSettings nativeSettings2and3 = createSingleScanNativeSettingsForChannels(
+ WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, channelsToSpec(2450, 5175, 5150));
+ ScanResults results2and3 = ScanResults.merge(results2, results3);
+
+
+ startServiceAndLoadDriver();
+
+ when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ any(WifiNative.ScanEventHandler.class))).thenReturn(true);
+
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder handlerOrder = inOrder(handler);
+ InOrder nativeOrder = inOrder(mWifiScannerImpl);
+
+ // Run scan 1
+ sendSingleScanRequest(controlChannel, requestId1, requestSettings1);
+
+ mLooper.dispatchAll();
+ WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(nativeOrder,
+ computeSingleScanNativeSettings(requestSettings1));
+ verifySuccessfulResponse(handlerOrder, handler, requestId1);
+
+ // Queue scan 2 (will not run because previous is in progress)
+ sendSingleScanRequest(controlChannel, requestId2, requestSettings2);
+ mLooper.dispatchAll();
+ verifySuccessfulResponse(handlerOrder, handler, requestId2);
+
+ // Queue scan 3 (will not run because previous is in progress)
+ sendSingleScanRequest(controlChannel, requestId3, requestSettings3);
+ mLooper.dispatchAll();
+ verifySuccessfulResponse(handlerOrder, handler, requestId3);
+
+ // dispatch scan 1 results
+ when(mWifiScannerImpl.getLatestSingleScanResults())
+ .thenReturn(results1.getScanData());
+ eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
+
+ mLooper.dispatchAll();
+ verifyScanResultsRecieved(handlerOrder, handler, requestId1, results1.getScanData());
+ verifySingleScanCompletedRecieved(handlerOrder, handler, requestId1);
+
+ // now that the first scan completed we expect the second and third ones to start
+ WifiNative.ScanEventHandler eventHandler2and3 = verifyStartSingleScan(nativeOrder,
+ nativeSettings2and3);
+
+ // dispatch scan 2 and 3 results
+ when(mWifiScannerImpl.getLatestSingleScanResults())
+ .thenReturn(results2and3.getScanData());
+ eventHandler2and3.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
+
+ mLooper.dispatchAll();
+
+ // unfortunatally the order that these events are dispatched is dependant on the order which
+ // they are iterated through internally
+ ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
+ handlerOrder.verify(handler, times(4)).handleMessage(messageCaptor.capture());
+ int firstListenerId = messageCaptor.getAllValues().get(0).arg2;
+ assertTrue(firstListenerId + " was neither " + requestId2 + " nor " + requestId3,
+ firstListenerId == requestId2 || firstListenerId == requestId3);
+ if (firstListenerId == requestId2) {
+ assertScanResultsMessage(requestId2,
+ new WifiScanner.ScanData[] {results2.getScanData()},
+ messageCaptor.getAllValues().get(0));
+ assertSingleScanCompletedMessage(requestId2, messageCaptor.getAllValues().get(1));
+ assertScanResultsMessage(requestId3,
+ new WifiScanner.ScanData[] {results3.getScanData()},
+ messageCaptor.getAllValues().get(2));
+ assertSingleScanCompletedMessage(requestId3, messageCaptor.getAllValues().get(3));
+ } else {
+ assertScanResultsMessage(requestId3,
+ new WifiScanner.ScanData[] {results3.getScanData()},
+ messageCaptor.getAllValues().get(0));
+ assertSingleScanCompletedMessage(requestId3, messageCaptor.getAllValues().get(1));
+ assertScanResultsMessage(requestId2,
+ new WifiScanner.ScanData[] {results2.getScanData()},
+ messageCaptor.getAllValues().get(2));
+ assertSingleScanCompletedMessage(requestId2, messageCaptor.getAllValues().get(3));
+ }
+ }
+
+ private void doSuccessfulBackgroundScan(WifiScanner.ScanSettings requestSettings,
+ WifiNative.ScanSettings nativeSettings) {
+ startServiceAndLoadDriver();
+
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder order = inOrder(handler, mWifiScannerImpl);
+
+ when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class),
+ any(WifiNative.ScanEventHandler.class))).thenReturn(true);
+
+ sendBackgroundScanRequest(controlChannel, 12, requestSettings);
+ mLooper.dispatchAll();
+ verifyStartBackgroundScan(order, nativeSettings);
+ verifySuccessfulResponse(order, handler, 12);
+ verifyNoMoreInteractions(handler);
+ }
+
+ /**
+ * Do a background scan for a band and verify that it is successful.
+ */
+ @Test
+ public void sendBackgroundScanBandRequest() throws Exception {
+ WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 20000,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ WifiNative.ScanSettings nativeSettings = new NativeScanSettingsBuilder()
+ .withBasePeriod(20000)
+ .withMaxApPerScan(MAX_AP_PER_SCAN)
+ .withMaxScansToCache(WifiScanningScheduler.DEFAULT_MAX_SCANS_TO_BATCH)
+ .addBucketWithBand(20000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
+ WifiScanner.WIFI_BAND_BOTH)
+ .build();
+ doSuccessfulBackgroundScan(requestSettings, nativeSettings);
+ }
+
+ /**
+ * Do a background scan for a list of channels and verify that it is successful.
+ */
+ @Test
+ public void sendBackgroundScanChannelsRequest() throws Exception {
+ WifiScanner.ScanSettings requestSettings = createRequest(channelsToSpec(5150), 20000,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ WifiNative.ScanSettings nativeSettings = new NativeScanSettingsBuilder()
+ .withBasePeriod(20000)
+ .withMaxApPerScan(MAX_AP_PER_SCAN)
+ .withMaxScansToCache(WifiScanningScheduler.DEFAULT_MAX_SCANS_TO_BATCH)
+ .addBucketWithChannels(20000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 5150)
+ .build();
+ doSuccessfulBackgroundScan(requestSettings, nativeSettings);
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
index f868c522b..2663b0c8e 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
@@ -45,6 +45,7 @@ import android.net.wifi.ScanResult;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
+import android.net.wifi.WifiScanner;
import android.net.wifi.WifiSsid;
import android.net.wifi.p2p.IWifiP2pManager;
import android.os.BatteryStats;
@@ -81,6 +82,7 @@ import com.android.server.wifi.p2p.WifiP2pServiceImpl;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -92,8 +94,10 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* Unit tests for {@link com.android.server.wifi.WifiStateMachine}.
@@ -234,6 +238,8 @@ public class WifiStateMachineTest {
when(context.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(
mock(ConnectivityManager.class));
+ when(context.getSystemService(Context.WIFI_SCANNING_SERVICE)).thenReturn(mWifiScanner);
+
return context;
}
@@ -281,7 +287,7 @@ public class WifiStateMachineTest {
ScanDetail detail = new ScanDetail(nd, sWifiSsid, sBSSID, "", rssi, sFreq,
Long.MAX_VALUE, /* needed so that scan results aren't rejected because
there older than scan start */
- null, null);
+ ie, new ArrayList<String>());
return detail;
}
@@ -312,6 +318,7 @@ public class WifiStateMachineTest {
WifiConfigManager mWifiConfigManager;
@Mock WifiNative mWifiNative;
+ @Mock WifiScanner mWifiScanner;
@Mock SupplicantStateTracker mSupplicantStateTracker;
@Mock WifiMetrics mWifiMetrics;
@Mock UserManager mUserManager;
@@ -743,6 +750,36 @@ public class WifiStateMachineTest {
forgetNetworkAndVerifyFailure();
}
+ private void verifyScan(int band, int reportEvents, Set<Integer> configuredNetworkIds) {
+ ArgumentCaptor<WifiScanner.ScanSettings> scanSettingsCaptor =
+ ArgumentCaptor.forClass(WifiScanner.ScanSettings.class);
+ ArgumentCaptor<WifiScanner.ScanListener> scanListenerCaptor =
+ ArgumentCaptor.forClass(WifiScanner.ScanListener.class);
+ verify(mWifiScanner).startScan(scanSettingsCaptor.capture(), scanListenerCaptor.capture());
+ WifiScanner.ScanSettings actualSettings = scanSettingsCaptor.getValue();
+ assertEquals("band", band, actualSettings.band);
+ assertEquals("reportEvents", reportEvents, actualSettings.reportEvents);
+
+ if (configuredNetworkIds == null) {
+ configuredNetworkIds = new HashSet<>();
+ }
+ Set<Integer> actualConfiguredNetworkIds = new HashSet<>();
+ if (actualSettings.hiddenNetworkIds != null) {
+ for (int i = 0; i < actualSettings.hiddenNetworkIds.length; ++i) {
+ actualConfiguredNetworkIds.add(actualSettings.hiddenNetworkIds[i]);
+ }
+ }
+ assertEquals("configured networks", configuredNetworkIds, actualConfiguredNetworkIds);
+
+ when(mWifiNative.getScanResults()).thenReturn(getMockScanResults());
+ mWsm.sendMessage(WifiMonitor.SCAN_RESULTS_EVENT);
+
+ mLooper.dispatchAll();
+
+ List<ScanResult> reportedResults = mWsm.syncGetScanResultsList();
+ assertEquals(8, reportedResults.size());
+ }
+
@Test
public void scan() throws Exception {
addNetworkAndVerifySuccess();
@@ -751,14 +788,9 @@ public class WifiStateMachineTest {
mWsm.startScan(-1, 0, null, null);
mLooper.dispatchAll();
- verify(mWifiNative).scan(null, mWifiConfigManager.getHiddenConfiguredNetworkIds());
-
- when(mWifiNative.getScanResults()).thenReturn(getMockScanResults());
- mWsm.sendMessage(WifiMonitor.SCAN_RESULTS_EVENT);
- mLooper.dispatchAll();
-
- List<ScanResult> results = mWsm.syncGetScanResultsList();
- assertEquals(8, results.size());
+ verifyScan(WifiScanner.WIFI_BAND_BOTH_WITH_DFS,
+ WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN
+ | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT, null);
}
@Test
@@ -769,14 +801,10 @@ public class WifiStateMachineTest {
mWsm.startScan(-1, 0, null, null);
mLooper.dispatchAll();
- verify(mWifiNative).scan(null, mWifiConfigManager.getHiddenConfiguredNetworkIds());
-
- when(mWifiNative.getScanResults()).thenReturn(getMockScanResults());
- mWsm.sendMessage(WifiMonitor.SCAN_RESULTS_EVENT);
- mLooper.dispatchAll();
-
- List<ScanResult> results = mWsm.syncGetScanResultsList();
- assertEquals(8, results.size());
+ verifyScan(WifiScanner.WIFI_BAND_BOTH_WITH_DFS,
+ WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN
+ | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT,
+ mWifiConfigManager.getHiddenConfiguredNetworkIds());
}
@Test