Home | History | Annotate | Download | only in scanner
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server.wifi.scanner;
     18 
     19 import static com.android.server.wifi.ScanTestUtil.NativeScanSettingsBuilder;
     20 import static com.android.server.wifi.ScanTestUtil.assertScanDataEquals;
     21 import static com.android.server.wifi.ScanTestUtil.createFreqSet;
     22 
     23 import static org.junit.Assert.*;
     24 import static org.mockito.Mockito.*;
     25 
     26 import android.app.test.TestAlarmManager;
     27 import android.content.Context;
     28 import android.net.wifi.ScanResult;
     29 import android.net.wifi.WifiScanner;
     30 import android.net.wifi.WifiScanner.ScanData;
     31 import android.net.wifi.WifiSsid;
     32 import android.os.SystemClock;
     33 import android.os.test.TestLooper;
     34 
     35 import com.android.server.wifi.Clock;
     36 import com.android.server.wifi.MockResources;
     37 import com.android.server.wifi.MockWifiMonitor;
     38 import com.android.server.wifi.ScanDetail;
     39 import com.android.server.wifi.ScanResults;
     40 import com.android.server.wifi.WifiMonitor;
     41 import com.android.server.wifi.WifiNative;
     42 import com.android.server.wifi.scanner.ChannelHelper.ChannelCollection;
     43 
     44 import org.junit.Before;
     45 import org.junit.Test;
     46 import org.mockito.InOrder;
     47 import org.mockito.Mock;
     48 import org.mockito.MockitoAnnotations;
     49 
     50 import java.util.ArrayList;
     51 import java.util.Arrays;
     52 import java.util.Collections;
     53 import java.util.HashSet;
     54 import java.util.Set;
     55 
     56 /**
     57  * Base unit tests that should pass for all implementations of
     58  * {@link com.android.server.wifi.scanner.WifiScannerImpl}.
     59  */
     60 public abstract class BaseWifiScannerImplTest {
     61     protected static final String IFACE_NAME = "a_test_interface_name";
     62     @Mock Context mContext;
     63     TestAlarmManager mAlarmManager;
     64     MockWifiMonitor mWifiMonitor;
     65     TestLooper mLooper;
     66     @Mock WifiNative mWifiNative;
     67     MockResources mResources;
     68     @Mock Clock mClock;
     69 
     70     /**
     71      * mScanner implementation should be filled in by derived test class
     72      */
     73     WifiScannerImpl mScanner;
     74 
     75     @Before
     76     public void setUpBase() throws Exception {
     77         MockitoAnnotations.initMocks(this);
     78 
     79         mLooper = new TestLooper();
     80         mAlarmManager = new TestAlarmManager();
     81         mWifiMonitor = new MockWifiMonitor();
     82         mResources = new MockResources();
     83 
     84         when(mWifiNative.getClientInterfaceName()).thenReturn(IFACE_NAME);
     85 
     86         when(mContext.getSystemService(Context.ALARM_SERVICE))
     87                 .thenReturn(mAlarmManager.getAlarmManager());
     88 
     89         when(mContext.getResources()).thenReturn(mResources);
     90         when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime());
     91     }
     92 
     93     protected boolean isAllChannelsScanned(int band) {
     94         ChannelCollection collection = mScanner.getChannelHelper().createChannelCollection();
     95         collection.addBand(band);
     96         return collection.isAllChannels();
     97     }
     98 
     99     protected Set<Integer> expectedBandScanFreqs(int band) {
    100         ChannelCollection collection = mScanner.getChannelHelper().createChannelCollection();
    101         collection.addBand(band);
    102         return collection.getScanFreqs();
    103     }
    104 
    105     protected Set<Integer> expectedBandAndChannelScanFreqs(int band, int... channels) {
    106         ChannelCollection collection = mScanner.getChannelHelper().createChannelCollection();
    107         collection.addBand(band);
    108         for (int channel : channels) {
    109             collection.addChannel(channel);
    110         }
    111         return collection.getScanFreqs();
    112     }
    113 
    114     @Test
    115     public void singleScanSuccess() {
    116         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    117                 .withBasePeriod(10000) // ms
    118                 .withMaxApPerScan(10)
    119                 .addBucketWithBand(10000 /* ms */, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    120                         WifiScanner.WIFI_BAND_24_GHZ)
    121                 .build();
    122 
    123         doSuccessfulSingleScanTest(settings,
    124                 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ),
    125                 new HashSet<String>(),
    126                 ScanResults.create(0, isAllChannelsScanned(WifiScanner.WIFI_BAND_24_GHZ),
    127                         2400, 2450, 2450, 2400, 2450, 2450, 2400, 2450, 2450), false);
    128     }
    129 
    130     @Test
    131     public void singleScanSuccessWithChannels() {
    132         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    133                 .withBasePeriod(10000)
    134                 .withMaxApPerScan(10)
    135                 .addBucketWithChannels(20000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 5650)
    136                 .build();
    137 
    138         doSuccessfulSingleScanTest(settings, createFreqSet(5650),
    139                 new HashSet<String>(),
    140                 ScanResults.create(0, 5650, 5650, 5650, 5650, 5650, 5650, 5650, 5650), false);
    141     }
    142 
    143     @Test
    144     public void singleScanSuccessWithChannelsAndHighAccuracyType() {
    145         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    146                 .withType(WifiNative.SCAN_TYPE_HIGH_ACCURACY)
    147                 .withBasePeriod(10000)
    148                 .withMaxApPerScan(10)
    149                 .addBucketWithChannels(20000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 5650)
    150                 .build();
    151 
    152         doSuccessfulSingleScanTest(settings, createFreqSet(5650),
    153                 new HashSet<String>(),
    154                 ScanResults.create(0, 5650, 5650, 5650, 5650, 5650, 5650, 5650, 5650), false);
    155     }
    156 
    157     @Test
    158     public void singleScanSuccessWithFullResults() {
    159         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    160                 .withBasePeriod(10000)
    161                 .withMaxApPerScan(10)
    162                 .addBucketWithBand(10000,
    163                         WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN
    164                         | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT,
    165                         WifiScanner.WIFI_BAND_24_GHZ)
    166                 .build();
    167 
    168         doSuccessfulSingleScanTest(settings, expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ),
    169                 new HashSet<String>(),
    170                 ScanResults.create(0, isAllChannelsScanned(WifiScanner.WIFI_BAND_24_GHZ),
    171                         2400, 2450, 2450, 2400, 2450, 2450, 2400, 2450, 2450), true);
    172     }
    173 
    174     /**
    175      * Tests whether the provided hidden networkId's in scan settings is correctly passed along
    176      * when invoking native scan.
    177      */
    178     @Test
    179     public void singleScanSuccessWithHiddenNetworkIds() {
    180         String[] hiddenNetworkSSIDs = {"test_ssid_1", "test_ssid_2"};
    181         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    182                 .withBasePeriod(10000)
    183                 .withMaxApPerScan(10)
    184                 .withHiddenNetworkSSIDs(hiddenNetworkSSIDs)
    185                 .addBucketWithChannels(20000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 5650)
    186                 .build();
    187 
    188         Set<String> hiddenNetworkSSIDSet = new HashSet<>();
    189         for (int i = 0; i < hiddenNetworkSSIDs.length; i++) {
    190             hiddenNetworkSSIDSet.add(hiddenNetworkSSIDs[i]);
    191         }
    192         doSuccessfulSingleScanTest(settings, createFreqSet(5650),
    193                 hiddenNetworkSSIDSet,
    194                 ScanResults.create(0, 5650, 5650, 5650, 5650, 5650, 5650, 5650, 5650), false);
    195     }
    196 
    197     /**
    198      * Tests whether the provided hidden networkId's in scan settings is truncated to max size
    199      * supported by wificond when invoking native scan.
    200      */
    201     @Test
    202     public void singleScanSuccessWithTruncatedHiddenNetworkIds() {
    203         String[] hiddenNetworkSSIDs = {
    204                 "test_ssid_0", "test_ssid_1", "test_ssid_2", "test_ssid_3", "test_ssid_4",
    205                 "test_ssid_5", "test_ssid_6", "test_ssid_7", "test_ssid_8", "test_ssid_9",
    206                 "test_ssid_10", "test_ssid_11", "test_ssid_12", "test_ssid_13", "test_ssid_14",
    207                 "test_ssid_15", "test_ssid_16", "test_ssid_17", "test_ssid_18", "test_ssid_19"
    208         };
    209         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    210                 .withBasePeriod(10000)
    211                 .withMaxApPerScan(10)
    212                 .withHiddenNetworkSSIDs(hiddenNetworkSSIDs)
    213                 .addBucketWithChannels(20000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 5650)
    214                 .build();
    215 
    216         Set<String> hiddenNetworkSSIDSet = new HashSet<>();
    217         for (int i = 0; i < WificondScannerImpl.MAX_HIDDEN_NETWORK_IDS_PER_SCAN; i++) {
    218             hiddenNetworkSSIDSet.add(hiddenNetworkSSIDs[i]);
    219         }
    220         doSuccessfulSingleScanTest(settings, createFreqSet(5650),
    221                 hiddenNetworkSSIDSet,
    222                 ScanResults.create(0, 5650, 5650, 5650, 5650, 5650, 5650, 5650, 5650), false);
    223     }
    224 
    225     @Test
    226     public void overlappingSingleScanFails() {
    227         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    228                 .withBasePeriod(10000) // ms
    229                 .withMaxApPerScan(10)
    230                 .addBucketWithBand(10000 /* ms */, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    231                         WifiScanner.WIFI_BAND_24_GHZ)
    232                 .build();
    233         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
    234 
    235         WifiNative.ScanSettings settings2 = new NativeScanSettingsBuilder()
    236                 .withBasePeriod(10000) // ms
    237                 .withMaxApPerScan(10)
    238                 .addBucketWithBand(10000 /* ms */, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    239                         WifiScanner.WIFI_BAND_5_GHZ)
    240                 .build();
    241         WifiNative.ScanEventHandler eventHandler2 = mock(WifiNative.ScanEventHandler.class);
    242 
    243         // scan start succeeds
    244         when(mWifiNative.scan(eq(IFACE_NAME), anyInt(), any(), any(Set.class))).thenReturn(true);
    245 
    246         assertTrue(mScanner.startSingleScan(settings, eventHandler));
    247         assertFalse("second scan while first scan running should fail immediately",
    248                 mScanner.startSingleScan(settings2, eventHandler2));
    249     }
    250 
    251     @Test
    252     public void singleScanFailOnExecute() {
    253         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    254                 .withBasePeriod(10000)
    255                 .withMaxApPerScan(10)
    256                 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    257                         WifiScanner.WIFI_BAND_24_GHZ)
    258                 .build();
    259 
    260         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
    261 
    262         ScanResults results = ScanResults.create(0, 2400, 2450, 2450);
    263 
    264         InOrder order = inOrder(eventHandler, mWifiNative);
    265 
    266         // scan fails
    267         when(mWifiNative.scan(eq(IFACE_NAME), anyInt(), any(), any(Set.class))).thenReturn(false);
    268 
    269         // start scan
    270         assertTrue(mScanner.startSingleScan(settings, eventHandler));
    271 
    272         mLooper.dispatchAll();
    273         order.verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_FAILED);
    274 
    275         verifyNoMoreInteractions(eventHandler);
    276     }
    277 
    278     /**
    279      * Test that a scan failure is reported if a scan times out
    280      */
    281     @Test
    282     public void singleScanFailOnTimeout() {
    283         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    284                 .withBasePeriod(10000)
    285                 .withMaxApPerScan(10)
    286                 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    287                         WifiScanner.WIFI_BAND_24_GHZ)
    288                 .build();
    289 
    290         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
    291 
    292         ScanResults results = ScanResults.create(0, 2400, 2450, 2450);
    293 
    294         InOrder order = inOrder(eventHandler, mWifiNative);
    295 
    296         // scan succeeds
    297         when(mWifiNative.scan(eq(IFACE_NAME), anyInt(), any(), any(Set.class))).thenReturn(true);
    298 
    299         // start scan
    300         assertTrue(mScanner.startSingleScan(settings, eventHandler));
    301         mLooper.dispatchAll();
    302 
    303         // Fire timeout
    304         mAlarmManager.dispatch(WificondScannerImpl.TIMEOUT_ALARM_TAG);
    305         mLooper.dispatchAll();
    306 
    307         order.verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_FAILED);
    308 
    309         verifyNoMoreInteractions(eventHandler);
    310     }
    311 
    312     /**
    313      * Test that a scan failure is reported if wificond sends a scan failed event
    314      */
    315     @Test
    316     public void singleScanFailOnFailedEvent() {
    317         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    318                 .withBasePeriod(10000)
    319                 .withMaxApPerScan(10)
    320                 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    321                         WifiScanner.WIFI_BAND_24_GHZ)
    322                 .build();
    323 
    324         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
    325 
    326         ScanResults results = ScanResults.create(0, 2400, 2450, 2450);
    327 
    328         InOrder order = inOrder(eventHandler, mWifiNative);
    329 
    330         // scan succeeds
    331         when(mWifiNative.scan(eq(IFACE_NAME), anyInt(), any(), any(Set.class))).thenReturn(true);
    332 
    333         // start scan
    334         assertTrue(mScanner.startSingleScan(settings, eventHandler));
    335         mLooper.dispatchAll();
    336 
    337         // Fire failed event
    338         mWifiMonitor.sendMessage(eq(IFACE_NAME), WifiMonitor.SCAN_FAILED_EVENT);
    339         mLooper.dispatchAll();
    340 
    341         order.verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_FAILED);
    342 
    343         verifyNoMoreInteractions(eventHandler);
    344     }
    345 
    346     @Test
    347     public void singleScanNullEventHandler() {
    348         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    349                 .withBasePeriod(10000)
    350                 .withMaxApPerScan(10)
    351                 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    352                         WifiScanner.WIFI_BAND_24_GHZ)
    353                 .build();
    354         assertFalse(mScanner.startSingleScan(settings, null));
    355     }
    356 
    357     @Test
    358     public void singleScanNullSettings() {
    359         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
    360 
    361         assertFalse(mScanner.startSingleScan(null, eventHandler));
    362 
    363         verifyNoMoreInteractions(eventHandler);
    364     }
    365 
    366     @Test
    367     public void multipleSingleScanSuccess() {
    368         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    369                 .withBasePeriod(10000)
    370                 .withMaxApPerScan(10)
    371                 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    372                         WifiScanner.WIFI_BAND_24_GHZ)
    373                 .build();
    374         WifiNative.ScanSettings settings2 = new NativeScanSettingsBuilder()
    375                 .withType(WifiNative.SCAN_TYPE_LOW_POWER)
    376                 .withBasePeriod(10000)
    377                 .withMaxApPerScan(10)
    378                 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    379                         WifiScanner.WIFI_BAND_BOTH_WITH_DFS)
    380                 .build();
    381 
    382         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
    383         InOrder order = inOrder(eventHandler, mWifiNative);
    384 
    385         // scans succeed
    386         when(mWifiNative.scan(eq(IFACE_NAME), anyInt(), any(), any(Set.class))).thenReturn(true);
    387 
    388         // start first scan
    389         assertTrue(mScanner.startSingleScan(settings, eventHandler));
    390 
    391         expectSuccessfulSingleScan(order, WifiNative.SCAN_TYPE_LOW_LATENCY, eventHandler,
    392                 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ),
    393                 new HashSet<String>(),
    394                 ScanResults.create(0, isAllChannelsScanned(WifiScanner.WIFI_BAND_24_GHZ),
    395                         2400, 2450, 2450), false);
    396 
    397         // start second scan
    398         assertTrue(mScanner.startSingleScan(settings2, eventHandler));
    399 
    400         expectSuccessfulSingleScan(order, WifiNative.SCAN_TYPE_LOW_POWER, eventHandler,
    401                 expectedBandScanFreqs(WifiScanner.WIFI_BAND_BOTH_WITH_DFS),
    402                 new HashSet<String>(),
    403                 ScanResults.create(0, true,
    404                         5150, 5175), false);
    405 
    406         verifyNoMoreInteractions(eventHandler);
    407     }
    408 
    409     /**
    410      * Validate that scan results that are returned from wificond, which are timestamped prior to
    411      * the start of the scan, are ignored.
    412      */
    413     @Test
    414     public void singleScanWhereSupplicantReturnsSomeOldResults() {
    415         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    416                 .withBasePeriod(10000)
    417                 .withMaxApPerScan(2)
    418                 .addBucketWithBand(10000,
    419                         WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN
    420                         | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT,
    421                         WifiScanner.WIFI_BAND_24_GHZ)
    422                 .build();
    423 
    424         long approxScanStartUs = mClock.getElapsedSinceBootMillis() * 1000;
    425         ArrayList<ScanDetail> rawResults = new ArrayList<>(Arrays.asList(
    426                         new ScanDetail(WifiSsid.createFromAsciiEncoded("TEST AP 1"),
    427                                 "00:00:00:00:00:00", "", -70, 2450,
    428                                 approxScanStartUs + 2000 * 1000, 0),
    429                         new ScanDetail(WifiSsid.createFromAsciiEncoded("TEST AP 2"),
    430                                 "AA:BB:CC:DD:EE:FF", "", -66, 2400,
    431                                 approxScanStartUs + 2500 * 1000, 0),
    432                         new ScanDetail(WifiSsid.createFromAsciiEncoded("TEST AP 3"),
    433                                 "00:00:00:00:00:00", "", -80, 2450,
    434                                 approxScanStartUs - 2000 * 1000, 0), // old result will be filtered
    435                         new ScanDetail(WifiSsid.createFromAsciiEncoded("TEST AP 4"),
    436                                 "AA:BB:CC:11:22:33", "", -65, 2450,
    437                                 approxScanStartUs + 4000 * 1000, 0)));
    438 
    439         ArrayList<ScanResult> fullResults = new ArrayList<>();
    440         for (ScanDetail detail : rawResults) {
    441             if (detail.getScanResult().timestamp > approxScanStartUs) {
    442                 fullResults.add(detail.getScanResult());
    443             }
    444         }
    445         ArrayList<ScanResult> scanDataResults = new ArrayList<>(fullResults);
    446         Collections.sort(scanDataResults, ScanResults.SCAN_RESULT_RSSI_COMPARATOR);
    447         ScanData scanData = new ScanData(0, 0, 0,
    448                 isAllChannelsScanned(WifiScanner.WIFI_BAND_24_GHZ),
    449                 scanDataResults.toArray(new ScanResult[scanDataResults.size()]));
    450         Set<Integer> expectedScan = expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ);
    451 
    452         // Actual test
    453 
    454         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
    455 
    456         InOrder order = inOrder(eventHandler, mWifiNative);
    457 
    458         // scan succeeds
    459         when(mWifiNative.scan(eq(IFACE_NAME), anyInt(), any(), any(Set.class))).thenReturn(true);
    460 
    461         // start scan
    462         assertTrue(mScanner.startSingleScan(settings, eventHandler));
    463 
    464         order.verify(mWifiNative).scan(eq(IFACE_NAME), anyInt(), eq(expectedScan), any(Set.class));
    465 
    466         when(mWifiNative.getScanResults(eq(IFACE_NAME))).thenReturn(rawResults);
    467 
    468         // Notify scan has finished
    469         mWifiMonitor.sendMessage(eq(IFACE_NAME), WifiMonitor.SCAN_RESULTS_EVENT);
    470 
    471         mLooper.dispatchAll();
    472 
    473         for (ScanResult result : fullResults) {
    474             order.verify(eventHandler).onFullScanResult(eq(result), eq(0));
    475         }
    476 
    477         order.verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
    478         assertScanDataEquals(scanData, mScanner.getLatestSingleScanResults());
    479 
    480         verifyNoMoreInteractions(eventHandler);
    481     }
    482 
    483     @Test
    484     public void backgroundScanNullEventHandler() {
    485         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    486                 .withBasePeriod(10000)
    487                 .withMaxApPerScan(10)
    488                 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    489                         WifiScanner.WIFI_BAND_24_GHZ)
    490                 .build();
    491         assertFalse(mScanner.startBatchedScan(settings, null));
    492     }
    493 
    494     @Test
    495     public void backgroundScanNullSettings() {
    496         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
    497 
    498         assertFalse(mScanner.startBatchedScan(null, eventHandler));
    499 
    500         verifyNoMoreInteractions(eventHandler);
    501     }
    502 
    503     protected void doSuccessfulSingleScanTest(WifiNative.ScanSettings settings,
    504             Set<Integer> expectedScan, Set<String> expectedHiddenNetSSIDs, ScanResults results,
    505             boolean expectFullResults) {
    506         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
    507 
    508         InOrder order = inOrder(eventHandler, mWifiNative);
    509 
    510         // scan succeeds
    511         when(mWifiNative.scan(eq(IFACE_NAME), anyInt(), any(), any(Set.class))).thenReturn(true);
    512 
    513         // start scan
    514         assertTrue(mScanner.startSingleScan(settings, eventHandler));
    515 
    516         expectSuccessfulSingleScan(order, settings.scanType, eventHandler, expectedScan,
    517                 expectedHiddenNetSSIDs, results, expectFullResults);
    518 
    519         verifyNoMoreInteractions(eventHandler);
    520     }
    521 
    522     protected void expectSuccessfulSingleScan(InOrder order,
    523             int scanType, WifiNative.ScanEventHandler eventHandler, Set<Integer> expectedScan,
    524             Set<String> expectedHiddenNetSSIDs, ScanResults results, boolean expectFullResults) {
    525         order.verify(mWifiNative).scan(
    526                 eq(IFACE_NAME), eq(scanType), eq(expectedScan), eq(expectedHiddenNetSSIDs));
    527 
    528         when(mWifiNative.getScanResults(
    529                 eq(IFACE_NAME))).thenReturn(results.getScanDetailArrayList());
    530 
    531         // Notify scan has finished
    532         mWifiMonitor.sendMessage(eq(IFACE_NAME), WifiMonitor.SCAN_RESULTS_EVENT);
    533 
    534         mLooper.dispatchAll();
    535 
    536         if (expectFullResults) {
    537             for (ScanResult result : results.getRawScanResults()) {
    538                 order.verify(eventHandler).onFullScanResult(eq(result), eq(0));
    539             }
    540         }
    541 
    542         order.verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
    543         assertScanDataEquals(results.getScanData(), mScanner.getLatestSingleScanResults());
    544     }
    545 }
    546