diff options
Diffstat (limited to 'tests')
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 |