• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 android.net.wifi;
18 
19 import static org.junit.Assert.assertArrayEquals;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertNotNull;
23 import static org.junit.Assert.assertNull;
24 import static org.junit.Assert.assertTrue;
25 import static org.junit.Assert.fail;
26 import static org.junit.Assume.assumeTrue;
27 import static org.mockito.ArgumentMatchers.any;
28 import static org.mockito.Mockito.mock;
29 import static org.mockito.Mockito.never;
30 import static org.mockito.Mockito.spy;
31 import static org.mockito.Mockito.times;
32 import static org.mockito.Mockito.validateMockitoUsage;
33 import static org.mockito.Mockito.verify;
34 import static org.mockito.Mockito.when;
35 
36 import android.content.Context;
37 import android.net.wifi.WifiScanner.PnoSettings;
38 import android.net.wifi.WifiScanner.PnoSettings.PnoNetwork;
39 import android.net.wifi.WifiScanner.ScanData;
40 import android.net.wifi.WifiScanner.ScanListener;
41 import android.net.wifi.WifiScanner.ScanSettings;
42 import android.os.Bundle;
43 import android.os.Handler;
44 import android.os.Message;
45 import android.os.Messenger;
46 import android.os.Parcel;
47 import android.os.test.TestLooper;
48 
49 import androidx.test.filters.SmallTest;
50 
51 import com.android.internal.util.test.BidirectionalAsyncChannelServer;
52 import com.android.modules.utils.build.SdkLevel;
53 
54 import org.junit.After;
55 import org.junit.Before;
56 import org.junit.Test;
57 import org.mockito.ArgumentCaptor;
58 import org.mockito.Mock;
59 import org.mockito.MockitoAnnotations;
60 import org.mockito.Spy;
61 
62 import java.util.Arrays;
63 import java.util.concurrent.Executor;
64 
65 /**
66  * Unit tests for {@link android.net.wifi.WifiScanner}.
67  */
68 @SmallTest
69 public class WifiScannerTest {
70     @Mock
71     private Context mContext;
72     @Mock
73     private IWifiScanner mService;
74     @Spy
75     private Executor mExecutor = new SynchronousExecutor();
76     @Mock
77     private ScanListener mScanListener;
78     @Mock
79     private WifiScanner.ParcelableScanData mParcelableScanData;
80     private ScanData[] mScanData = {};
81 
82     private static final boolean TEST_PNOSETTINGS_IS_CONNECTED = false;
83     private static final int TEST_PNOSETTINGS_MIN_5GHZ_RSSI = -60;
84     private static final int TEST_PNOSETTINGS_MIN_2GHZ_RSSI = -70;
85     private static final int TEST_PNOSETTINGS_MIN_6GHZ_RSSI = -55;
86     private static final String TEST_SSID_1 = "TEST1";
87     private static final String TEST_SSID_2 = "TEST2";
88     private static final int[] TEST_FREQUENCIES_1 = {};
89     private static final int[] TEST_FREQUENCIES_2 = {2500, 5124, 6245};
90     private static final String DESCRIPTION_NOT_AUTHORIZED = "Not authorized";
91 
92     private WifiScanner mWifiScanner;
93     private TestLooper mLooper;
94     private Handler mHandler;
95     private BidirectionalAsyncChannelServer mBidirectionalAsyncChannelServer;
96 
97     /**
98      * Setup before tests.
99      */
100     @Before
setUp()101     public void setUp() throws Exception {
102         MockitoAnnotations.initMocks(this);
103         mLooper = new TestLooper();
104         mHandler = spy(new Handler(mLooper.getLooper()));
105         mBidirectionalAsyncChannelServer = new BidirectionalAsyncChannelServer(
106                 mContext, mLooper.getLooper(), mHandler);
107         when(mService.getMessenger()).thenReturn(mBidirectionalAsyncChannelServer.getMessenger());
108         mWifiScanner = new WifiScanner(mContext, mService, mLooper.getLooper());
109         mLooper.dispatchAll();
110         when(mParcelableScanData.getResults()).thenReturn(mScanData);
111     }
112 
113     /**
114      * Clean up after tests.
115      */
116     @After
cleanup()117     public void cleanup() {
118         validateMockitoUsage();
119     }
120 
121     /**
122      * Verify parcel read/write for ScanSettings.
123      */
124     @Test
verifyScanSettingsParcelWithBand()125     public void verifyScanSettingsParcelWithBand() throws Exception {
126         ScanSettings writeSettings = new ScanSettings();
127         writeSettings.type = WifiScanner.SCAN_TYPE_LOW_POWER;
128         writeSettings.band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS;
129 
130         ScanSettings readSettings = parcelWriteRead(writeSettings);
131         assertEquals(readSettings.type, writeSettings.type);
132         assertEquals(readSettings.band, writeSettings.band);
133         assertEquals(0, readSettings.channels.length);
134     }
135 
136     /**
137      * Verify parcel read/write for ScanSettings.
138      */
139     @Test
verifyScanSettingsParcelWithChannels()140     public void verifyScanSettingsParcelWithChannels() throws Exception {
141         ScanSettings writeSettings = new ScanSettings();
142         writeSettings.type = WifiScanner.SCAN_TYPE_HIGH_ACCURACY;
143         writeSettings.band = WifiScanner.WIFI_BAND_UNSPECIFIED;
144         writeSettings.channels = new WifiScanner.ChannelSpec[] {
145                 new WifiScanner.ChannelSpec(5),
146                 new WifiScanner.ChannelSpec(7)
147         };
148 
149         ScanSettings readSettings = parcelWriteRead(writeSettings);
150         assertEquals(writeSettings.type, readSettings.type);
151         assertEquals(writeSettings.band, readSettings.band);
152         assertEquals(2, readSettings.channels.length);
153         assertEquals(5, readSettings.channels[0].frequency);
154         assertEquals(7, readSettings.channels[1].frequency);
155     }
156 
157     /**
158      * Write the provided {@link ScanSettings} to a parcel and deserialize it.
159      */
parcelWriteRead(ScanSettings writeSettings)160     private static ScanSettings parcelWriteRead(ScanSettings writeSettings) throws Exception {
161         Parcel parcel = Parcel.obtain();
162         writeSettings.writeToParcel(parcel, 0);
163         parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
164         return ScanSettings.CREATOR.createFromParcel(parcel);
165     }
166 
167     /**
168      *  PnoSettings object can be serialized and deserialized, while keeping the
169      *  values unchanged.
170      */
171     @Test
canSerializeAndDeserializePnoSettings()172     public void canSerializeAndDeserializePnoSettings() throws Exception {
173 
174         PnoSettings pnoSettings = new PnoSettings();
175 
176         PnoNetwork pnoNetwork1 = new PnoNetwork(TEST_SSID_1);
177         PnoNetwork pnoNetwork2 = new PnoNetwork(TEST_SSID_2);
178         pnoNetwork1.frequencies = TEST_FREQUENCIES_1;
179         pnoNetwork2.frequencies = TEST_FREQUENCIES_2;
180 
181         pnoSettings.networkList = new PnoNetwork[]{pnoNetwork1, pnoNetwork2};
182         pnoSettings.isConnected = TEST_PNOSETTINGS_IS_CONNECTED;
183         pnoSettings.min5GHzRssi = TEST_PNOSETTINGS_MIN_5GHZ_RSSI;
184         pnoSettings.min24GHzRssi = TEST_PNOSETTINGS_MIN_2GHZ_RSSI;
185         pnoSettings.min6GHzRssi = TEST_PNOSETTINGS_MIN_6GHZ_RSSI;
186 
187         Parcel parcel = Parcel.obtain();
188         pnoSettings.writeToParcel(parcel, 0);
189         // Rewind the pointer to the head of the parcel.
190         parcel.setDataPosition(0);
191         PnoSettings pnoSettingsDeserialized =
192                 pnoSettings.CREATOR.createFromParcel(parcel);
193 
194         assertNotNull(pnoSettingsDeserialized);
195         assertEquals(TEST_PNOSETTINGS_IS_CONNECTED, pnoSettingsDeserialized.isConnected);
196         assertEquals(TEST_PNOSETTINGS_MIN_5GHZ_RSSI, pnoSettingsDeserialized.min5GHzRssi);
197         assertEquals(TEST_PNOSETTINGS_MIN_2GHZ_RSSI, pnoSettingsDeserialized.min24GHzRssi);
198         assertEquals(TEST_PNOSETTINGS_MIN_6GHZ_RSSI, pnoSettingsDeserialized.min6GHzRssi);
199 
200         // Test parsing of PnoNetwork
201         assertEquals(pnoSettings.networkList.length, pnoSettingsDeserialized.networkList.length);
202         for (int i = 0; i < pnoSettings.networkList.length; i++) {
203             PnoNetwork expected = pnoSettings.networkList[i];
204             PnoNetwork actual = pnoSettingsDeserialized.networkList[i];
205             assertEquals(expected.ssid, actual.ssid);
206             assertEquals(expected.flags, actual.flags);
207             assertEquals(expected.authBitField, actual.authBitField);
208             assertTrue(Arrays.equals(expected.frequencies, actual.frequencies));
209         }
210     }
211 
212     /**
213      *  Make sure that frequencies is not null by default.
214      */
215     @Test
pnoNetworkFrequencyIsNotNull()216     public void pnoNetworkFrequencyIsNotNull() throws Exception {
217         PnoNetwork pnoNetwork = new PnoNetwork(TEST_SSID_1);
218         assertNotNull(pnoNetwork.frequencies);
219     }
220 
221     /**
222      * Verify parcel read/write for ScanData.
223      */
224     @Test
verifyScanDataParcel()225     public void verifyScanDataParcel() throws Exception {
226         ScanData writeScanData = new ScanData(2, 0, 3,
227                 WifiScanner.WIFI_BAND_BOTH_WITH_DFS, new ScanResult[0]);
228 
229         ScanData readScanData = parcelWriteRead(writeScanData);
230         assertEquals(writeScanData.getId(), readScanData.getId());
231         assertEquals(writeScanData.getFlags(), readScanData.getFlags());
232         assertEquals(writeScanData.getBucketsScanned(), readScanData.getBucketsScanned());
233         assertEquals(writeScanData.getScannedBandsInternal(),
234                 readScanData.getScannedBandsInternal());
235         assertArrayEquals(writeScanData.getResults(), readScanData.getResults());
236     }
237 
238     /**
239      * Write the provided {@link ScanData} to a parcel and deserialize it.
240      */
parcelWriteRead(ScanData writeScanData)241     private static ScanData parcelWriteRead(ScanData writeScanData) throws Exception {
242         Parcel parcel = Parcel.obtain();
243         writeScanData.writeToParcel(parcel, 0);
244         parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
245         return ScanData.CREATOR.createFromParcel(parcel);
246     }
247 
248     /**
249      * Verify #setRnrSetting with valid and invalid inputs.
250      */
251     @Test
testSetRnrSetting()252     public void testSetRnrSetting() throws Exception {
253         // First verify IllegalArgumentException if an invalid input is passed in.
254         assumeTrue(SdkLevel.isAtLeastS());
255         try {
256             WifiScanner.ScanSettings scanSettings = new WifiScanner.ScanSettings();
257             scanSettings.setRnrSetting(-1);
258             fail("Excepted IllegalArgumentException");
259         } catch (IllegalArgumentException e) {
260         }
261 
262         // Then verify calling the API with a valid input.
263         WifiScanner.ScanSettings scanSettings = new WifiScanner.ScanSettings();
264         scanSettings.setRnrSetting(WifiScanner.WIFI_RNR_NOT_NEEDED);
265         assertEquals(WifiScanner.WIFI_RNR_NOT_NEEDED, scanSettings.getRnrSetting());
266     }
267 
268     /**
269      * Test behavior of {@link WifiScanner#startScan(ScanSettings, ScanListener)}
270      * @throws Exception
271      */
272     @Test
testStartScan()273     public void testStartScan() throws Exception {
274         ScanSettings scanSettings = new ScanSettings();
275         ScanListener scanListener = mock(ScanListener.class);
276 
277         mWifiScanner.startScan(scanSettings, scanListener);
278         mLooper.dispatchAll();
279 
280         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
281         verify(mHandler).handleMessage(messageArgumentCaptor.capture());
282         Message message = messageArgumentCaptor.getValue();
283         assertNotNull(message);
284 
285         assertEquals(WifiScanner.CMD_START_SINGLE_SCAN, message.what);
286         assertTrue(message.obj instanceof Bundle);
287         Bundle messageBundle = (Bundle) message.obj;
288         assertEquals(scanSettings,
289                 messageBundle.getParcelable(WifiScanner.SCAN_PARAMS_SCAN_SETTINGS_KEY));
290         assertNull(messageBundle.getParcelable(WifiScanner.SCAN_PARAMS_WORK_SOURCE_KEY));
291         assertEquals(mContext.getOpPackageName(),
292                 messageBundle.getParcelable(WifiScanner.REQUEST_PACKAGE_NAME_KEY));
293         assertEquals(mContext.getAttributionTag(),
294                 messageBundle.getParcelable(WifiScanner.REQUEST_FEATURE_ID_KEY));
295 
296     }
297 
298     /**
299      * Test behavior of {@link WifiScanner#stopScan(ScanListener)}
300      * @throws Exception
301      */
302     @Test
testStopScan()303     public void testStopScan() throws Exception {
304         ScanSettings scanSettings = new ScanSettings();
305         ScanListener scanListener = mock(ScanListener.class);
306 
307         mWifiScanner.startScan(scanSettings, scanListener);
308         mLooper.dispatchAll();
309 
310         mWifiScanner.stopScan(scanListener);
311         mLooper.dispatchAll();
312 
313         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
314         verify(mHandler, times(2)).handleMessage(messageArgumentCaptor.capture());
315         Message message = messageArgumentCaptor.getValue();
316         assertNotNull(message);
317 
318         assertEquals(WifiScanner.CMD_STOP_SINGLE_SCAN, message.what);
319         assertTrue(message.obj instanceof Bundle);
320         Bundle messageBundle = (Bundle) message.obj;
321         assertEquals(mContext.getOpPackageName(),
322                 messageBundle.getParcelable(WifiScanner.REQUEST_PACKAGE_NAME_KEY));
323         assertEquals(mContext.getAttributionTag(),
324                 messageBundle.getParcelable(WifiScanner.REQUEST_FEATURE_ID_KEY));
325     }
326 
327     /**
328      * Test behavior of {@link WifiScanner#startScan(ScanSettings, ScanListener)}
329      * @throws Exception
330      */
331     @Test
testStartScanListenerOnSuccess()332     public void testStartScanListenerOnSuccess() throws Exception {
333         ScanSettings scanSettings = new ScanSettings();
334         ScanListener scanListener = mock(ScanListener.class);
335 
336         mWifiScanner.startScan(scanSettings, scanListener);
337         mLooper.dispatchAll();
338 
339         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
340         verify(mHandler).handleMessage(messageArgumentCaptor.capture());
341         Message sentMessage = messageArgumentCaptor.getValue();
342         assertNotNull(sentMessage);
343 
344         assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size());
345         Messenger scannerMessenger =
346                 mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next();
347 
348         Message responseMessage = Message.obtain();
349         responseMessage.what = WifiScanner.CMD_OP_SUCCEEDED;
350         responseMessage.arg2 = sentMessage.arg2;
351         scannerMessenger.send(responseMessage);
352         mLooper.dispatchAll();
353 
354         verify(scanListener).onSuccess();
355     }
356 
357     /**
358      * Test behavior of {@link WifiScanner#startScan(ScanSettings, ScanListener)}
359      * @throws Exception
360      */
361     @Test
testStartScanListenerOnResults()362     public void testStartScanListenerOnResults() throws Exception {
363         ScanSettings scanSettings = new ScanSettings();
364         ScanListener scanListener = mock(ScanListener.class);
365 
366         mWifiScanner.startScan(scanSettings, scanListener);
367         mLooper.dispatchAll();
368 
369         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
370         verify(mHandler).handleMessage(messageArgumentCaptor.capture());
371         Message sentMessage = messageArgumentCaptor.getValue();
372         assertNotNull(sentMessage);
373 
374         assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size());
375         Messenger scannerMessenger =
376                 mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next();
377 
378         ScanResult scanResult = new ScanResult();
379         ScanData scanDatas[] = new ScanData[]{new ScanData(0, 0 , new ScanResult[] {scanResult})};
380         Message responseMessage = Message.obtain();
381         responseMessage.what = WifiScanner.CMD_SCAN_RESULT;
382         responseMessage.arg2 = sentMessage.arg2;
383         responseMessage.obj = new WifiScanner.ParcelableScanData(scanDatas);
384         scannerMessenger.send(responseMessage);
385         mLooper.dispatchAll();
386 
387         verify(scanListener).onResults(scanDatas);
388     }
389 
390     /**
391      * Test behavior of {@link WifiScanner#startDisconnectedPnoScan(ScanSettings, PnoSettings,
392      * Executor, WifiScanner.PnoScanListener)}
393      * @throws Exception
394      */
395     @Test
testStartDisconnectedPnoScan()396     public void testStartDisconnectedPnoScan() throws Exception {
397         ScanSettings scanSettings = new ScanSettings();
398         PnoSettings pnoSettings = new PnoSettings();
399         WifiScanner.PnoScanListener pnoScanListener = mock(WifiScanner.PnoScanListener.class);
400 
401         mWifiScanner.startDisconnectedPnoScan(
402                 scanSettings, pnoSettings, mock(Executor.class), pnoScanListener);
403         mLooper.dispatchAll();
404 
405         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
406         verify(mHandler).handleMessage(messageArgumentCaptor.capture());
407         Message message = messageArgumentCaptor.getValue();
408         assertNotNull(message);
409 
410         assertEquals(WifiScanner.CMD_START_PNO_SCAN, message.what);
411         assertTrue(message.obj instanceof Bundle);
412         Bundle messageBundle = (Bundle) message.obj;
413         assertEquals(scanSettings,
414                 messageBundle.getParcelable(WifiScanner.PNO_PARAMS_SCAN_SETTINGS_KEY));
415         assertTrue(scanSettings.isPnoScan);
416         assertFalse(pnoSettings.isConnected);
417         assertEquals(pnoSettings,
418                 messageBundle.getParcelable(WifiScanner.PNO_PARAMS_PNO_SETTINGS_KEY));
419     }
420 
421     /**
422      * Test behavior of {@link WifiScanner#startConnectedPnoScan(ScanSettings, PnoSettings,
423      * Executor, WifiScanner.PnoScanListener)}
424      * @throws Exception
425      */
426     @Test
testStartConnectedPnoScan()427     public void testStartConnectedPnoScan() throws Exception {
428         ScanSettings scanSettings = new ScanSettings();
429         PnoSettings pnoSettings = new PnoSettings();
430         WifiScanner.PnoScanListener pnoScanListener = mock(WifiScanner.PnoScanListener.class);
431 
432         mWifiScanner.startConnectedPnoScan(
433                 scanSettings, pnoSettings, mock(Executor.class), pnoScanListener);
434         mLooper.dispatchAll();
435 
436         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
437         verify(mHandler).handleMessage(messageArgumentCaptor.capture());
438         Message message = messageArgumentCaptor.getValue();
439         assertNotNull(message);
440 
441         assertEquals(WifiScanner.CMD_START_PNO_SCAN, message.what);
442         assertTrue(message.obj instanceof Bundle);
443         Bundle messageBundle = (Bundle) message.obj;
444         assertEquals(scanSettings,
445                 messageBundle.getParcelable(WifiScanner.PNO_PARAMS_SCAN_SETTINGS_KEY));
446         assertTrue(scanSettings.isPnoScan);
447         assertTrue(pnoSettings.isConnected);
448         assertEquals(pnoSettings,
449                 messageBundle.getParcelable(WifiScanner.PNO_PARAMS_PNO_SETTINGS_KEY));
450     }
451 
452     /**
453      * Test behavior of {@link WifiScanner#stopPnoScan(ScanListener)}
454      * Executor, WifiScanner.PnoScanListener)}
455      * @throws Exception
456      */
457     @Test
testStopPnoScan()458     public void testStopPnoScan() throws Exception {
459         ScanSettings scanSettings = new ScanSettings();
460         PnoSettings pnoSettings = new PnoSettings();
461         WifiScanner.PnoScanListener pnoScanListener = mock(WifiScanner.PnoScanListener.class);
462 
463         mWifiScanner.startDisconnectedPnoScan(
464                 scanSettings, pnoSettings, mock(Executor.class), pnoScanListener);
465         mLooper.dispatchAll();
466         mWifiScanner.stopPnoScan(pnoScanListener);
467         mLooper.dispatchAll();
468 
469         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
470         verify(mHandler, times(2)).handleMessage(messageArgumentCaptor.capture());
471         Message message = messageArgumentCaptor.getValue();
472         assertNotNull(message);
473 
474         assertEquals(WifiScanner.CMD_STOP_PNO_SCAN, message.what);
475     }
476 
477     @Test
testScanDataAddResults()478     public void testScanDataAddResults() throws Exception {
479         ScanResult scanResult1 = new ScanResult();
480         scanResult1.SSID = TEST_SSID_1;
481         ScanData scanData = new ScanData(0, 0, new ScanResult[]{scanResult1});
482 
483         ScanResult scanResult2 = new ScanResult();
484         scanResult2.SSID = TEST_SSID_2;
485         scanData.addResults(new ScanResult[]{scanResult2});
486 
487         ScanResult[] consolidatedScanResults = scanData.getResults();
488         assertEquals(2, consolidatedScanResults.length);
489         assertEquals(TEST_SSID_1, consolidatedScanResults[0].SSID);
490         assertEquals(TEST_SSID_2, consolidatedScanResults[1].SSID);
491     }
492 
493     @Test
testScanDataParcel()494     public void testScanDataParcel() throws Exception {
495         ScanResult scanResult1 = new ScanResult();
496         scanResult1.SSID = TEST_SSID_1;
497         ScanData scanData = new ScanData(5, 4, new ScanResult[]{scanResult1});
498 
499         Parcel parcel = Parcel.obtain();
500         scanData.writeToParcel(parcel, 0);
501         parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
502         ScanData readScanData = ScanData.CREATOR.createFromParcel(parcel);
503 
504         assertEquals(scanData.getId(), readScanData.getId());
505         assertEquals(scanData.getFlags(), readScanData.getFlags());
506         assertEquals(scanData.getResults().length, readScanData.getResults().length);
507         assertEquals(scanData.getResults()[0].SSID, readScanData.getResults()[0].SSID);
508     }
509 
510     /** Tests that upon registration success, {@link ScanListener#onSuccess()} is called. */
511     @Test
testRegisterScanListenerSuccess()512     public void testRegisterScanListenerSuccess() throws Exception {
513         mWifiScanner.registerScanListener(mExecutor, mScanListener);
514         mLooper.dispatchAll();
515 
516         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
517         verify(mHandler).handleMessage(messageArgumentCaptor.capture());
518         Message sentMessage = messageArgumentCaptor.getValue();
519         assertNotNull(sentMessage);
520 
521         assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size());
522         Messenger scannerMessenger =
523                 mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next();
524 
525         Message responseMessage = Message.obtain();
526         responseMessage.what = WifiScanner.CMD_OP_SUCCEEDED;
527         responseMessage.arg2 = sentMessage.arg2;
528         scannerMessenger.send(responseMessage);
529         mLooper.dispatchAll();
530 
531         verify(mExecutor).execute(any());
532         verify(mScanListener).onSuccess();
533     }
534 
535     /**
536      * Tests that upon registration failed, {@link ScanListener#onFailure(int, String)} is called.
537      */
538     @Test
testRegisterScanListenerFailed()539     public void testRegisterScanListenerFailed() throws Exception {
540         mWifiScanner.registerScanListener(mExecutor, mScanListener);
541         mLooper.dispatchAll();
542 
543         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
544         verify(mHandler).handleMessage(messageArgumentCaptor.capture());
545         Message sentMessage = messageArgumentCaptor.getValue();
546         assertNotNull(sentMessage);
547 
548         assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size());
549         Messenger scannerMessenger =
550                 mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next();
551 
552         {
553             Message responseMessage = Message.obtain();
554             responseMessage.what = WifiScanner.CMD_OP_FAILED;
555             responseMessage.arg2 = sentMessage.arg2;
556             responseMessage.obj = new WifiScanner.OperationResult(
557                     WifiScanner.REASON_NOT_AUTHORIZED, DESCRIPTION_NOT_AUTHORIZED);
558             scannerMessenger.send(responseMessage);
559             mLooper.dispatchAll();
560         }
561 
562         verify(mExecutor).execute(any());
563         verify(mScanListener).onFailure(
564                 WifiScanner.REASON_NOT_AUTHORIZED, DESCRIPTION_NOT_AUTHORIZED);
565 
566         // CMD_OP_FAILED should have caused the removal of the listener, verify this
567         {
568             Message responseMessage = Message.obtain();
569             responseMessage.what = WifiScanner.CMD_SCAN_RESULT;
570             responseMessage.arg2 = sentMessage.arg2;
571             responseMessage.obj = mParcelableScanData;
572             scannerMessenger.send(responseMessage);
573             mLooper.dispatchAll();
574         }
575         // execute() called once before, not called again
576         verify(mExecutor, times(1)).execute(any());
577         // onResults() never triggered
578         verify(mScanListener, never()).onResults(any());
579     }
580 
581     /**
582      * Tests that when the ScanListener is triggered, {@link ScanListener#onResults(ScanData[])}
583      * is called.
584      */
585     @Test
testRegisterScanListenerReceiveScanResults()586     public void testRegisterScanListenerReceiveScanResults() throws Exception {
587         mWifiScanner.registerScanListener(mExecutor, mScanListener);
588         mLooper.dispatchAll();
589 
590         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
591         verify(mHandler).handleMessage(messageArgumentCaptor.capture());
592         Message sentMessage = messageArgumentCaptor.getValue();
593         assertNotNull(sentMessage);
594 
595         assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size());
596         Messenger scannerMessenger =
597                 mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next();
598 
599         Message responseMessage = Message.obtain();
600         responseMessage.what = WifiScanner.CMD_SCAN_RESULT;
601         responseMessage.arg2 = sentMessage.arg2;
602         responseMessage.obj = mParcelableScanData;
603         scannerMessenger.send(responseMessage);
604         mLooper.dispatchAll();
605 
606         verify(mExecutor).execute(any());
607         verify(mScanListener).onResults(mScanData);
608     }
609 
610     /**
611      * Tests that after unregistering a scan listener, {@link ScanListener#onResults(ScanData[])}
612      * is not called.
613      */
614     @Test
testUnregisterScanListener()615     public void testUnregisterScanListener() throws Exception {
616         mWifiScanner.registerScanListener(mExecutor, mScanListener);
617         mWifiScanner.unregisterScanListener(mScanListener);
618         mLooper.dispatchAll();
619 
620         assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size());
621         Messenger scannerMessenger =
622                 mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next();
623 
624         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
625         verify(mHandler, times(2)).handleMessage(messageArgumentCaptor.capture());
626         Message sentMessage = messageArgumentCaptor.getValue();
627         assertNotNull(sentMessage);
628 
629         Message responseMessage = Message.obtain();
630         responseMessage.what = WifiScanner.CMD_SCAN_RESULT;
631         responseMessage.obj = mParcelableScanData;
632         responseMessage.arg2 = sentMessage.arg2;
633         scannerMessenger.send(responseMessage);
634         mLooper.dispatchAll();
635 
636         verify(mExecutor, never()).execute(any());
637         verify(mScanListener, never()).onResults(mScanData);
638     }
639 
640     /**
641      * Tests isFullBandScan() method with and without DFS check
642      */
643     @Test
testIsFullBandScan()644     public void testIsFullBandScan() throws Exception {
645         assertFalse(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_24_GHZ, true));
646         assertFalse(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_5_GHZ, true));
647         assertFalse(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_6_GHZ, true));
648         assertFalse(WifiScanner.isFullBandScan(
649                 WifiScanner.WIFI_BAND_6_GHZ | WifiScanner.WIFI_BAND_5_GHZ, true));
650         assertTrue(WifiScanner.isFullBandScan(
651                 WifiScanner.WIFI_BAND_24_GHZ | WifiScanner.WIFI_BAND_5_GHZ, true));
652         assertFalse(WifiScanner.isFullBandScan(
653                 WifiScanner.WIFI_BAND_24_GHZ | WifiScanner.WIFI_BAND_5_GHZ, false));
654         assertTrue(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, true));
655         assertTrue(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, false));
656     }
657 }
658