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.assertScanDatasEquals;
     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.net.wifi.ScanResult;
     27 import android.net.wifi.WifiScanner;
     28 import android.net.wifi.WifiSsid;
     29 import android.test.suitebuilder.annotation.SmallTest;
     30 
     31 import com.android.server.wifi.ScanDetail;
     32 import com.android.server.wifi.ScanResults;
     33 import com.android.server.wifi.WifiMonitor;
     34 import com.android.server.wifi.WifiNative;
     35 
     36 import org.junit.Before;
     37 import org.junit.Test;
     38 import org.mockito.InOrder;
     39 
     40 import java.util.ArrayList;
     41 import java.util.Set;
     42 
     43 /**
     44  * Unit tests for {@link com.android.server.wifi.scanner.WificondScannerImpl}.
     45  */
     46 @SmallTest
     47 public class WificondScannerTest extends BaseWifiScannerImplTest {
     48 
     49     @Before
     50     public void setup() throws Exception {
     51         mScanner = new WificondScannerImpl(mContext, mWifiNative, mWifiMonitor,
     52                 mLooper.getLooper(), mClock);
     53     }
     54 
     55     @Test
     56     public void backgroundScanSuccessSingleBucket() {
     57         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
     58                 .withBasePeriod(10000)
     59                 .withMaxApPerScan(10)
     60                 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
     61                         WifiScanner.WIFI_BAND_24_GHZ)
     62                 .build();
     63 
     64         ScanPeriod[] expectedPeriods = new ScanPeriod[] {
     65             new ScanPeriod(ScanPeriod.ReportType.RESULT,
     66                     ScanResults.create(0, 2400),
     67                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)),
     68             new ScanPeriod(ScanPeriod.ReportType.RESULT,
     69                     ScanResults.create(1, 2450),
     70                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ))
     71         };
     72 
     73         doSuccessfulTest(settings, expectedPeriods);
     74     }
     75 
     76     @Test
     77     public void backgroundScanMaxApExceeded() {
     78         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
     79                 .withBasePeriod(10000)
     80                 .withMaxApPerScan(2)
     81                 .addBucketWithBand(10000,
     82                         WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN
     83                         | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT,
     84                         WifiScanner.WIFI_BAND_24_GHZ)
     85                 .build();
     86 
     87         ScanPeriod[] expectedPeriods = new ScanPeriod[] {
     88             new ScanPeriod(ScanPeriod.ReportType.FULL_AND_RESULT,
     89                     ScanResults.createOverflowing(0, 2,
     90                             new ScanDetail(WifiSsid.createFromAsciiEncoded("TEST AP 1"),
     91                                     "00:00:00:00:00:00", "", -70, 2450, Long.MAX_VALUE, 0),
     92                             new ScanDetail(WifiSsid.createFromAsciiEncoded("TEST AP 2"),
     93                                     "AA:BB:CC:DD:EE:FF", "", -66, 2400, Long.MAX_VALUE, 0),
     94                             new ScanDetail(WifiSsid.createFromAsciiEncoded("TEST AP 3"),
     95                                     "00:00:00:00:00:00", "", -80, 2450, Long.MAX_VALUE, 0),
     96                             new ScanDetail(WifiSsid.createFromAsciiEncoded("TEST AP 4"),
     97                                     "AA:BB:CC:11:22:33", "", -65, 2450, Long.MAX_VALUE, 0)),
     98                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ))
     99         };
    100 
    101         doSuccessfulTest(settings, expectedPeriods);
    102     }
    103 
    104     @Test
    105     public void backgroundScanSuccessWithFullScanResults() {
    106         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    107                 .withBasePeriod(10000)
    108                 .withMaxApPerScan(10)
    109                 .addBucketWithBand(10000,
    110                         WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN
    111                         | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT,
    112                         WifiScanner.WIFI_BAND_24_GHZ)
    113                 .build();
    114 
    115         ScanPeriod[] expectedPeriods = new ScanPeriod[] {
    116             new ScanPeriod(ScanPeriod.ReportType.FULL_AND_RESULT,
    117                     ScanResults.create(0, 2400, 2450, 2400, 2400),
    118                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)),
    119             new ScanPeriod(ScanPeriod.ReportType.FULL_AND_RESULT,
    120                     ScanResults.create(1, 2450, 2400, 2450, 2400),
    121                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ))
    122         };
    123 
    124         doSuccessfulTest(settings, expectedPeriods);
    125     }
    126 
    127     @Test
    128     public void backgroundScanSuccessWithMixedFullResultsAndNot() {
    129         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    130                 .withBasePeriod(10000)
    131                 .withMaxApPerScan(10)
    132                 .addBucketWithBand(10000,
    133                         WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    134                         WifiScanner.WIFI_BAND_24_GHZ)
    135                 .addBucketWithBand(20000,
    136                         WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN
    137                         | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT,
    138                         WifiScanner.WIFI_BAND_5_GHZ)
    139                 .build();
    140 
    141         ScanPeriod[] expectedPeriods = new ScanPeriod[] {
    142             new ScanPeriod(ScanPeriod.ReportType.FULL_AND_RESULT,
    143                     ScanResults.create(0, 2400, 2450, 2400, 5175),
    144                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_BOTH)),
    145             new ScanPeriod(ScanPeriod.ReportType.RESULT,
    146                     ScanResults.create(1, 2450, 2400, 2450, 2400),
    147                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)),
    148             new ScanPeriod(ScanPeriod.ReportType.FULL_AND_RESULT,
    149                     ScanResults.create(2, 2450, 2400, 2450, 5150),
    150                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_BOTH))
    151         };
    152 
    153         doSuccessfulTest(settings, expectedPeriods);
    154     }
    155 
    156     @Test
    157     public void backgroundScanNoBatch() {
    158         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    159                 .withBasePeriod(10000)
    160                 .withMaxApPerScan(10)
    161                 .addBucketWithBand(10000,
    162                         WifiScanner.REPORT_EVENT_NO_BATCH,
    163                         WifiScanner.WIFI_BAND_24_GHZ)
    164                 .build();
    165 
    166         ScanPeriod[] expectedPeriods = new ScanPeriod[] {
    167             new ScanPeriod(ScanPeriod.ReportType.NONE,
    168                     ScanResults.create(0, 2400, 2400, 2400),
    169                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)),
    170             new ScanPeriod(ScanPeriod.ReportType.NONE,
    171                     ScanResults.create(1, 2400, 2400, 2450),
    172                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)),
    173             new ScanPeriod(ScanPeriod.ReportType.NONE,
    174                     ScanResults.create(2, 2400, 2450, 2400),
    175                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ))
    176         };
    177 
    178         doSuccessfulTest(settings, expectedPeriods);
    179     }
    180 
    181     @Test
    182     public void backgroundScanBatch() {
    183         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    184                 .withBasePeriod(10000)
    185                 .withMaxApPerScan(10)
    186                 .withMaxScansToCache(3)
    187                 .addBucketWithBand(10000,
    188                         WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL,
    189                         WifiScanner.WIFI_BAND_24_GHZ)
    190                 .build();
    191 
    192         ScanResults[] periodResults = new ScanResults[] {
    193             ScanResults.create(0, 2400, 2400, 2400),
    194             ScanResults.create(1, 2400, 2400, 2400, 2400),
    195             ScanResults.create(2, 2450),
    196             ScanResults.create(3, 2400, 2400),
    197             ScanResults.create(4, 2400, 2450),
    198             ScanResults.create(5, 2450)
    199         };
    200 
    201         ScanPeriod[] expectedPeriods = new ScanPeriod[] {
    202             new ScanPeriod(ScanPeriod.ReportType.NONE,
    203                     periodResults[0],
    204                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)),
    205             new ScanPeriod(ScanPeriod.ReportType.NONE,
    206                     periodResults[1],
    207                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)),
    208             new ScanPeriod(ScanPeriod.ReportType.RESULT,
    209                     new ScanResults[] {
    210                         periodResults[0],
    211                         periodResults[1],
    212                         periodResults[2]
    213                     },
    214                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)),
    215             new ScanPeriod(ScanPeriod.ReportType.NONE,
    216                     periodResults[3],
    217                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)),
    218             new ScanPeriod(ScanPeriod.ReportType.NONE,
    219                     periodResults[4],
    220                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)),
    221             new ScanPeriod(ScanPeriod.ReportType.RESULT,
    222                     new ScanResults[] {
    223                         periodResults[3],
    224                         periodResults[4],
    225                         periodResults[5]
    226                     },
    227                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ))
    228         };
    229 
    230         doSuccessfulTest(settings, expectedPeriods);
    231     }
    232 
    233     @Test
    234     public void backgroundScanSuccessWithMultipleBuckets() {
    235         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    236                 .withBasePeriod(10000)
    237                 .withMaxApPerScan(10)
    238                 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    239                         WifiScanner.WIFI_BAND_24_GHZ)
    240                 .addBucketWithBand(30000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    241                         WifiScanner.WIFI_BAND_BOTH)
    242                 .addBucketWithChannels(20000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    243                         5650)
    244                 .build();
    245 
    246         ScanPeriod[] expectedPeriods = new ScanPeriod[] {
    247             new ScanPeriod(ScanPeriod.ReportType.RESULT,
    248                     ScanResults.create(0, 2400, 5175),
    249                     expectedBandAndChannelScanFreqs(WifiScanner.WIFI_BAND_BOTH, 5650)),
    250             new ScanPeriod(ScanPeriod.ReportType.RESULT,
    251                     ScanResults.create(1, 2400),
    252                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)),
    253             new ScanPeriod(ScanPeriod.ReportType.RESULT,
    254                     ScanResults.create(2, 2450, 5650),
    255                     expectedBandAndChannelScanFreqs(WifiScanner.WIFI_BAND_24_GHZ, 5650)),
    256             new ScanPeriod(ScanPeriod.ReportType.RESULT,
    257                     ScanResults.create(3, 2450, 5175),
    258                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_BOTH)),
    259             new ScanPeriod(ScanPeriod.ReportType.RESULT,
    260                     ScanResults.create(4, new int[0]),
    261                     expectedBandAndChannelScanFreqs(WifiScanner.WIFI_BAND_24_GHZ, 5650)),
    262             new ScanPeriod(ScanPeriod.ReportType.RESULT,
    263                     ScanResults.create(5, 2400, 2400, 2400, 2450),
    264                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)),
    265             new ScanPeriod(ScanPeriod.ReportType.RESULT,
    266                     ScanResults.create(6, 5150, 5650, 5650),
    267                     expectedBandAndChannelScanFreqs(WifiScanner.WIFI_BAND_BOTH, 5650))
    268         };
    269 
    270         doSuccessfulTest(settings, expectedPeriods);
    271     }
    272 
    273     @Test
    274     public void backgroundScanSuccessWithMultipleBucketsWhereAPeriodDoesNotRequireAScan() {
    275         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    276                 .withBasePeriod(10000)
    277                 .withMaxApPerScan(10)
    278                 .addBucketWithBand(30000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    279                         WifiScanner.WIFI_BAND_BOTH)
    280                 .addBucketWithChannels(20000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    281                         5650)
    282                 .build();
    283 
    284         // expected scan frequencies
    285         ScanPeriod[] expectedPeriods = new ScanPeriod[] {
    286             new ScanPeriod(ScanPeriod.ReportType.RESULT,
    287                     ScanResults.create(0, 2400, 5175),
    288                     expectedBandAndChannelScanFreqs(WifiScanner.WIFI_BAND_BOTH, 5650)),
    289             null,
    290             new ScanPeriod(ScanPeriod.ReportType.RESULT,
    291                     ScanResults.create(1, 5650),
    292                     createFreqSet(5650)),
    293             new ScanPeriod(ScanPeriod.ReportType.RESULT,
    294                     ScanResults.create(2, 2450, 5175),
    295                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_BOTH)),
    296             new ScanPeriod(ScanPeriod.ReportType.RESULT,
    297                     ScanResults.create(3, 5650, 5650, 5650),
    298                     createFreqSet(5650)),
    299             null,
    300             new ScanPeriod(ScanPeriod.ReportType.RESULT,
    301                     ScanResults.create(4, 2400, 2400, 2400, 2450),
    302                     expectedBandAndChannelScanFreqs(WifiScanner.WIFI_BAND_BOTH, 5650))
    303         };
    304 
    305         doSuccessfulTest(settings, expectedPeriods);
    306     }
    307 
    308     @Test
    309     public void backgroundScanStartFailed() {
    310         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
    311         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    312                 .withBasePeriod(10000)
    313                 .withMaxApPerScan(10)
    314                 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    315                         WifiScanner.WIFI_BAND_24_GHZ)
    316                 .build();
    317 
    318         InOrder order = inOrder(eventHandler, mWifiNative);
    319 
    320         // All scans fail
    321         when(mWifiNative.scan(any(), any(Set.class))).thenReturn(false);
    322 
    323         // Start scan
    324         mScanner.startBatchedScan(settings, eventHandler);
    325 
    326         assertBackgroundPeriodAlarmPending();
    327 
    328         expectFailedScanStart(order, eventHandler,
    329                 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ));
    330 
    331         // Fire alarm to start next scan
    332         dispatchBackgroundPeriodAlarm();
    333 
    334         assertBackgroundPeriodAlarmPending();
    335 
    336         expectFailedScanStart(order, eventHandler,
    337                 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ));
    338 
    339         verifyNoMoreInteractions(eventHandler);
    340     }
    341 
    342 
    343     @Test
    344     public void backgroundScanEventFailed() {
    345         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
    346         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    347                 .withBasePeriod(10000)
    348                 .withMaxApPerScan(10)
    349                 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    350                         WifiScanner.WIFI_BAND_24_GHZ)
    351                 .build();
    352 
    353         InOrder order = inOrder(eventHandler, mWifiNative);
    354 
    355         // All scan starts succeed
    356         when(mWifiNative.scan(any(), any(Set.class))).thenReturn(true);
    357 
    358         // Start scan
    359         mScanner.startBatchedScan(settings, eventHandler);
    360 
    361         assertBackgroundPeriodAlarmPending();
    362 
    363         expectFailedEventScan(order, eventHandler,
    364                 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ));
    365 
    366         // Fire alarm to start next scan
    367         dispatchBackgroundPeriodAlarm();
    368 
    369         assertBackgroundPeriodAlarmPending();
    370 
    371         expectFailedEventScan(order, eventHandler,
    372                 expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ));
    373 
    374         verifyNoMoreInteractions(eventHandler);
    375     }
    376 
    377     /**
    378      * Run a scan and then pause after the first scan completes, but before the next one starts
    379      * Then resume the scan
    380      */
    381     @Test
    382     public void pauseWhileWaitingToStartNextScanAndResumeScan() {
    383         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
    384         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    385                 .withBasePeriod(10000)
    386                 .withMaxApPerScan(10)
    387                 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    388                         WifiScanner.WIFI_BAND_24_GHZ)
    389                 .build();
    390 
    391         ScanPeriod[] expectedPeriods = new ScanPeriod[] {
    392             new ScanPeriod(ScanPeriod.ReportType.RESULT,
    393                     ScanResults.create(0, 2400, 2450, 2450),
    394                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)),
    395             new ScanPeriod(ScanPeriod.ReportType.RESULT,
    396                     ScanResults.create(1, 2400),
    397                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ))
    398         };
    399 
    400         InOrder order = inOrder(eventHandler, mWifiNative);
    401 
    402         // All scan starts succeed
    403         when(mWifiNative.scan(any(), any(Set.class))).thenReturn(true);
    404 
    405         // Start scan
    406         mScanner.startBatchedScan(settings, eventHandler);
    407 
    408         assertBackgroundPeriodAlarmPending();
    409 
    410         expectSuccessfulBackgroundScan(order, eventHandler, expectedPeriods[0], 0);
    411 
    412         assertBackgroundPeriodAlarmPending();
    413 
    414         mScanner.pauseBatchedScan();
    415 
    416         // onPause callback (previous results were flushed)
    417         order.verify(eventHandler).onScanPaused(new WifiScanner.ScanData[0]);
    418 
    419         assertBackgroundPeriodAlarmNotPending();
    420 
    421         mScanner.restartBatchedScan();
    422 
    423         // onRestarted callback
    424         order.verify(eventHandler).onScanRestarted();
    425 
    426         expectSuccessfulBackgroundScan(order, eventHandler, expectedPeriods[1], 1);
    427 
    428         verifyNoMoreInteractions(eventHandler);
    429     }
    430 
    431     /**
    432      * Run a scan and then pause while the first scan is running
    433      * Then resume the scan
    434      */
    435     @Test
    436     public void pauseWhileScanningAndResumeScan() {
    437         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
    438         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    439                 .withBasePeriod(10000)
    440                 .withMaxApPerScan(10)
    441                 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    442                         WifiScanner.WIFI_BAND_24_GHZ)
    443                 .build();
    444 
    445         ScanPeriod[] expectedPeriods = new ScanPeriod[] {
    446             new ScanPeriod(ScanPeriod.ReportType.RESULT,
    447                     ScanResults.create(0, 2400, 2450, 2450),
    448                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ)),
    449             new ScanPeriod(ScanPeriod.ReportType.RESULT,
    450                     ScanResults.create(1, 2400),
    451                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ))
    452         };
    453 
    454         InOrder order = inOrder(eventHandler, mWifiNative);
    455 
    456         // All scan starts succeed
    457         when(mWifiNative.scan(any(), any(Set.class))).thenReturn(true);
    458 
    459         // Start scan
    460         mScanner.startBatchedScan(settings, eventHandler);
    461 
    462         assertBackgroundPeriodAlarmPending();
    463 
    464         order.verify(mWifiNative).scan(eq(expectedPeriods[0].getScanFreqs()), any(Set.class));
    465 
    466         mScanner.pauseBatchedScan();
    467 
    468         // onPause callback (no pending results)
    469         order.verify(eventHandler).onScanPaused(new WifiScanner.ScanData[0]);
    470 
    471         assertBackgroundPeriodAlarmNotPending();
    472 
    473         // Setup scan results
    474         when(mWifiNative.getScanResults()).thenReturn(expectedPeriods[0]
    475                 .getResultsToBeDelivered()[0].getScanDetailArrayList());
    476 
    477         // Notify scan has finished
    478         mWifiMonitor.sendMessage(mWifiNative.getInterfaceName(), WifiMonitor.SCAN_RESULTS_EVENT);
    479         assertEquals("dispatch message after results event", 1, mLooper.dispatchAll());
    480 
    481         // listener should not be notified
    482 
    483         mScanner.restartBatchedScan();
    484 
    485         // onRestarted callback
    486         order.verify(eventHandler).onScanRestarted();
    487 
    488         expectSuccessfulBackgroundScan(order, eventHandler, expectedPeriods[1], 1);
    489 
    490         verifyNoMoreInteractions(eventHandler);
    491     }
    492 
    493 
    494     /**
    495      * Run a scan and then pause after the first scan completes, but before the next one starts
    496      * Then schedule a new scan while still paused
    497      */
    498     @Test
    499     public void pauseWhileWaitingToStartNextScanAndStartNewScan() {
    500         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
    501         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    502                 .withBasePeriod(10000)
    503                 .withMaxApPerScan(10)
    504                 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    505                         WifiScanner.WIFI_BAND_24_GHZ)
    506                 .build();
    507 
    508         WifiNative.ScanSettings settings2 = new NativeScanSettingsBuilder()
    509                 .withBasePeriod(10000)
    510                 .withMaxApPerScan(10)
    511                 .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    512                         WifiScanner.WIFI_BAND_5_GHZ)
    513                 .build();
    514 
    515         ScanPeriod[] expectedPeriods = new ScanPeriod[] {
    516             new ScanPeriod(ScanPeriod.ReportType.RESULT,
    517                     ScanResults.create(0, 2400, 2450, 2450),
    518                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ))
    519         };
    520 
    521         ScanPeriod[] expectedPeriods2 = new ScanPeriod[] {
    522             new ScanPeriod(ScanPeriod.ReportType.RESULT,
    523                     ScanResults.create(1, 5150, 5175, 5175),
    524                     expectedBandScanFreqs(WifiScanner.WIFI_BAND_5_GHZ)),
    525         };
    526 
    527         InOrder order = inOrder(eventHandler, mWifiNative);
    528 
    529         // All scan starts succeed
    530         when(mWifiNative.scan(any(), any(Set.class))).thenReturn(true);
    531 
    532         // Start scan
    533         mScanner.startBatchedScan(settings, eventHandler);
    534 
    535         assertBackgroundPeriodAlarmPending();
    536 
    537         expectSuccessfulBackgroundScan(order, eventHandler, expectedPeriods[0], 0);
    538 
    539         assertBackgroundPeriodAlarmPending();
    540 
    541         mScanner.pauseBatchedScan();
    542 
    543         // onPause callback (previous results were flushed)
    544         order.verify(eventHandler).onScanPaused(new WifiScanner.ScanData[0]);
    545 
    546         assertBackgroundPeriodAlarmNotPending();
    547 
    548         // Start new scan
    549         mScanner.startBatchedScan(settings2, eventHandler);
    550 
    551         expectSuccessfulBackgroundScan(order, eventHandler, expectedPeriods2[0], 0);
    552 
    553         verifyNoMoreInteractions(eventHandler);
    554     }
    555 
    556     /**
    557      * Run a test with the given settings where all native scans succeed
    558      * This will execute expectedPeriods.length scan periods by first
    559      * starting the scan settings and then dispatching the scan period alarm to start the
    560      * next scan.
    561      */
    562     private void doSuccessfulTest(WifiNative.ScanSettings settings, ScanPeriod[] expectedPeriods) {
    563         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
    564 
    565         InOrder order = inOrder(eventHandler, mWifiNative);
    566 
    567         // All scans succeed
    568         when(mWifiNative.scan(any(), any(Set.class))).thenReturn(true);
    569 
    570         // Start scan
    571         mScanner.startBatchedScan(settings, eventHandler);
    572 
    573         for (int i = 0; i < expectedPeriods.length; ++i) {
    574             ScanPeriod period = expectedPeriods[i];
    575             assertBackgroundPeriodAlarmPending();
    576             if (period != null) { // scan should be scheduled
    577                 expectSuccessfulBackgroundScan(order, eventHandler, expectedPeriods[i], i);
    578             }
    579             if (i < expectedPeriods.length - 1) {
    580                 dispatchBackgroundPeriodAlarm();
    581             }
    582         }
    583 
    584         verifyNoMoreInteractions(eventHandler);
    585     }
    586 
    587     /**
    588      * Verify the state after a scan was started either through startBatchedScan or
    589      * dispatching the period alarm.
    590      */
    591     private void expectSuccessfulBackgroundScan(InOrder order,
    592             WifiNative.ScanEventHandler eventHandler, ScanPeriod period, int periodId) {
    593         WifiScanner.ScanData[] scanDatas = null;
    594         ArrayList<ScanDetail> nativeResults = null;
    595         ScanResult[] fullResults = null;
    596         if (period.getResultsToBeDelivered() != null) {
    597             ScanResults lastPeriodResults = period.getResultsToBeDelivered()
    598                     [period.getResultsToBeDelivered().length - 1];
    599             nativeResults = lastPeriodResults.getScanDetailArrayList();
    600             if (period.expectResults()) {
    601                 scanDatas =
    602                         new WifiScanner.ScanData[period.getResultsToBeDelivered().length];
    603                 for (int j = 0; j < scanDatas.length; ++j) {
    604                     scanDatas[j] = period.getResultsToBeDelivered()[j].getScanData();
    605                 }
    606             }
    607             if (period.expectFullResults()) {
    608                 fullResults = lastPeriodResults.getRawScanResults();
    609             }
    610         }
    611         expectSuccessfulBackgroundScan(order, eventHandler, period.getScanFreqs(),
    612                 nativeResults, scanDatas, fullResults, periodId);
    613     }
    614 
    615     /**
    616      * Verify the state after a scan was started either through startBatchedScan or
    617      * dispatching the period alarm.
    618      */
    619     private void expectSuccessfulBackgroundScan(InOrder order,
    620             WifiNative.ScanEventHandler eventHandler, Set<Integer> scanFreqs,
    621             ArrayList<ScanDetail> nativeResults,
    622             WifiScanner.ScanData[] expectedScanResults,
    623             ScanResult[] fullResults, int periodId) {
    624         // Verify scan started
    625         order.verify(mWifiNative).scan(eq(scanFreqs), any(Set.class));
    626 
    627         // Setup scan results
    628         when(mWifiNative.getScanResults()).thenReturn(nativeResults);
    629 
    630         // Notify scan has finished
    631         mWifiMonitor.sendMessage(mWifiNative.getInterfaceName(), WifiMonitor.SCAN_RESULTS_EVENT);
    632         assertEquals("dispatch message after results event", 1, mLooper.dispatchAll());
    633 
    634         if (fullResults != null) {
    635             for (ScanResult result : fullResults) {
    636                 order.verify(eventHandler).onFullScanResult(eq(result), eq(0));
    637             }
    638         }
    639 
    640         if (expectedScanResults != null) {
    641             // Verify scan results delivered
    642             order.verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
    643             assertScanDatasEquals("period[" + periodId + "].", expectedScanResults,
    644                     mScanner.getLatestBatchedScanResults(true));
    645         }
    646     }
    647 
    648     private void expectFailedScanStart(InOrder order, WifiNative.ScanEventHandler eventHandler,
    649             Set<Integer> scanFreqs) {
    650         // Verify scan started
    651         order.verify(mWifiNative).scan(eq(scanFreqs), any(Set.class));
    652     }
    653 
    654     private void expectFailedEventScan(InOrder order, WifiNative.ScanEventHandler eventHandler,
    655             Set<Integer> scanFreqs) {
    656         // Verify scan started
    657         order.verify(mWifiNative).scan(eq(scanFreqs), any(Set.class));
    658 
    659         // Notify scan has failed
    660         mWifiMonitor.sendMessage(mWifiNative.getInterfaceName(), WifiMonitor.SCAN_FAILED_EVENT);
    661         assertEquals("dispatch message after results event", 1, mLooper.dispatchAll());
    662 
    663         // TODO: verify failure event
    664     }
    665 
    666     private void assertBackgroundPeriodAlarmPending() {
    667         assertTrue("background period alarm not pending",
    668                 mAlarmManager.isPending(WificondScannerImpl.BACKGROUND_PERIOD_ALARM_TAG));
    669     }
    670 
    671     private void assertBackgroundPeriodAlarmNotPending() {
    672         assertFalse("background period alarm is pending",
    673                 mAlarmManager.isPending(WificondScannerImpl.BACKGROUND_PERIOD_ALARM_TAG));
    674     }
    675 
    676     private void dispatchBackgroundPeriodAlarm() {
    677         assertTrue("dispatch background period alarm",
    678                 mAlarmManager.dispatch(WificondScannerImpl.BACKGROUND_PERIOD_ALARM_TAG));
    679         mLooper.dispatchAll();
    680     }
    681 
    682     private static class ScanPeriod {
    683         enum ReportType {
    684             NONE(false, false),
    685             RESULT(true, false),
    686             FULL_AND_RESULT(true, true),
    687             FULL(false, true);
    688 
    689             public final boolean result;
    690             public final boolean full;
    691             ReportType(boolean result, boolean full) {
    692                 this.result = result;
    693                 this.full = full;
    694             }
    695         };
    696         private final ReportType mReportType;
    697         private final ScanResults[] mDeliveredResults;
    698         private final Set<Integer> mRequestedFreqs;
    699 
    700         ScanPeriod(ReportType reportType, ScanResults deliveredResult,
    701                 Set<Integer> requestedFreqs) {
    702             this(reportType, new ScanResults[] {deliveredResult}, requestedFreqs);
    703         }
    704 
    705         ScanPeriod(ReportType reportType, ScanResults[] deliveredResults,
    706                 Set<Integer> requestedFreqs) {
    707             mReportType = reportType;
    708             mDeliveredResults = deliveredResults;
    709             mRequestedFreqs = requestedFreqs;
    710         }
    711 
    712         public boolean expectResults() {
    713             return mReportType.result;
    714         }
    715         public boolean expectFullResults() {
    716             return mReportType.full;
    717         }
    718         public final ScanResults[] getResultsToBeDelivered() {
    719             return mDeliveredResults;
    720         }
    721         public Set<Integer> getScanFreqs() {
    722             return mRequestedFreqs;
    723         }
    724     }
    725 }
    726