1/*
2 * Copyright (C) 2017 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
17package com.android.server.wifi;
18
19import static org.junit.Assert.assertArrayEquals;
20import static org.junit.Assert.assertEquals;
21import static org.junit.Assert.assertFalse;
22import static org.junit.Assert.assertNotNull;
23import static org.junit.Assert.assertTrue;
24import static org.mockito.Matchers.argThat;
25import static org.mockito.Mockito.any;
26import static org.mockito.Mockito.mock;
27import static org.mockito.Mockito.verify;
28import static org.mockito.Mockito.when;
29
30import android.net.wifi.IApInterface;
31import android.net.wifi.IClientInterface;
32import android.net.wifi.IPnoScanEvent;
33import android.net.wifi.IScanEvent;
34import android.net.wifi.IWifiScannerImpl;
35import android.net.wifi.IWificond;
36import android.net.wifi.WifiScanner;
37import android.test.suitebuilder.annotation.SmallTest;
38
39import com.android.server.wifi.util.NativeUtil;
40import com.android.server.wifi.wificond.ChannelSettings;
41import com.android.server.wifi.wificond.HiddenNetwork;
42import com.android.server.wifi.wificond.NativeScanResult;
43import com.android.server.wifi.wificond.PnoSettings;
44import com.android.server.wifi.wificond.SingleScanSettings;
45
46import org.junit.Before;
47import org.junit.Test;
48import org.mockito.ArgumentCaptor;
49import org.mockito.ArgumentMatcher;
50
51import java.util.ArrayList;
52import java.util.BitSet;
53import java.util.HashSet;
54import java.util.Set;
55
56/**
57 * Unit tests for {@link com.android.server.wifi.WificondControl}.
58 */
59@SmallTest
60public class WificondControlTest {
61    private WifiInjector mWifiInjector;
62    private WifiMonitor mWifiMonitor;
63    private WificondControl mWificondControl;
64    private static final String TEST_INTERFACE_NAME = "test_wlan_if";
65    private static final byte[] TEST_SSID =
66            new byte[] {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'};
67    private static final byte[] TEST_BSSID =
68            new byte[] {(byte) 0x12, (byte) 0xef, (byte) 0xa1,
69                        (byte) 0x2c, (byte) 0x97, (byte) 0x8b};
70    // This the IE buffer which is consistent with TEST_SSID.
71    private static final byte[] TEST_INFO_ELEMENT =
72            new byte[] {
73                    // Element ID for SSID.
74                    (byte) 0x00,
75                    // Length of the SSID: 0x0b or 11.
76                    (byte) 0x0b,
77                    // This is string "GoogleGuest"
78                    'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'};
79
80    private static final int TEST_FREQUENCY = 2456;
81    private static final int TEST_SIGNAL_MBM = -4500;
82    private static final long TEST_TSF = 34455441;
83    private static final BitSet TEST_CAPABILITY = new BitSet(16) {{ set(2); set(5); }};
84    private static final boolean TEST_ASSOCIATED = true;
85    private static final NativeScanResult MOCK_NATIVE_SCAN_RESULT =
86            new NativeScanResult() {{
87                ssid = TEST_SSID;
88                bssid = TEST_BSSID;
89                infoElement = TEST_INFO_ELEMENT;
90                frequency = TEST_FREQUENCY;
91                signalMbm = TEST_SIGNAL_MBM;
92                capability = TEST_CAPABILITY;
93                associated = TEST_ASSOCIATED;
94            }};
95
96    private static final Set<Integer> SCAN_FREQ_SET =
97            new HashSet<Integer>() {{
98                add(2410);
99                add(2450);
100                add(5050);
101                add(5200);
102            }};
103    private static final String TEST_QUOTED_SSID_1 = "\"testSsid1\"";
104    private static final String TEST_QUOTED_SSID_2 = "\"testSsid2\"";
105
106    private static final Set<String> SCAN_HIDDEN_NETWORK_SSID_SET =
107            new HashSet<String>() {{
108                add(TEST_QUOTED_SSID_1);
109                add(TEST_QUOTED_SSID_2);
110            }};
111
112
113    private static final WifiNative.PnoSettings TEST_PNO_SETTINGS =
114            new WifiNative.PnoSettings() {{
115                isConnected = false;
116                periodInMs = 6000;
117                networkList = new WifiNative.PnoNetwork[2];
118                networkList[0] = new WifiNative.PnoNetwork();
119                networkList[1] = new WifiNative.PnoNetwork();
120                networkList[0].ssid = TEST_QUOTED_SSID_1;
121                networkList[0].flags = WifiScanner.PnoSettings.PnoNetwork.FLAG_DIRECTED_SCAN;
122                networkList[1].ssid = TEST_QUOTED_SSID_2;
123                networkList[1].flags = 0;
124            }};
125
126    @Before
127    public void setUp() throws Exception {
128        mWifiInjector = mock(WifiInjector.class);
129        mWifiMonitor = mock(WifiMonitor.class);
130        mWificondControl = new WificondControl(mWifiInjector, mWifiMonitor);
131    }
132
133    /**
134     * Verifies that setupDriverForClientMode() calls Wificond.
135     */
136    @Test
137    public void testSetupDriverForClientMode() throws Exception {
138        IWificond wificond = mock(IWificond.class);
139        IClientInterface clientInterface = getMockClientInterface();
140
141        when(mWifiInjector.makeWificond()).thenReturn(wificond);
142        when(wificond.createClientInterface()).thenReturn(clientInterface);
143
144        IClientInterface returnedClientInterface = mWificondControl.setupDriverForClientMode();
145        assertEquals(clientInterface, returnedClientInterface);
146        verify(wificond).createClientInterface();
147    }
148
149    /**
150     * Verifies that setupDriverForClientMode() calls subscribeScanEvents().
151     */
152    @Test
153    public void testSetupDriverForClientModeCallsScanEventSubscripiton() throws Exception {
154        IWifiScannerImpl scanner = setupClientInterfaceAndCreateMockWificondScanner();
155
156        verify(scanner).subscribeScanEvents(any(IScanEvent.class));
157    }
158
159    /**
160     * Verifies that setupDriverForClientMode() returns null when wificond is not started.
161     */
162    @Test
163    public void testSetupDriverForClientModeErrorWhenWificondIsNotStarted() throws Exception {
164        when(mWifiInjector.makeWificond()).thenReturn(null);
165
166        IClientInterface returnedClientInterface = mWificondControl.setupDriverForClientMode();
167        assertEquals(null, returnedClientInterface);
168    }
169
170    /**
171     * Verifies that setupDriverForClientMode() returns null when wificond failed to setup client
172     * interface.
173     */
174    @Test
175    public void testSetupDriverForClientModeErrorWhenWificondFailedToSetupInterface()
176            throws Exception {
177        IWificond wificond = mock(IWificond.class);
178
179        when(mWifiInjector.makeWificond()).thenReturn(wificond);
180        when(wificond.createClientInterface()).thenReturn(null);
181
182        IClientInterface returnedClientInterface = mWificondControl.setupDriverForClientMode();
183        assertEquals(null, returnedClientInterface);
184    }
185
186    /**
187     * Verifies that setupDriverForSoftApMode() calls wificond.
188     */
189    @Test
190    public void testSetupDriverForSoftApMode() throws Exception {
191        IWificond wificond = mock(IWificond.class);
192        IApInterface apInterface = mock(IApInterface.class);
193
194        when(mWifiInjector.makeWificond()).thenReturn(wificond);
195        when(wificond.createApInterface()).thenReturn(apInterface);
196
197        IApInterface returnedApInterface = mWificondControl.setupDriverForSoftApMode();
198        assertEquals(apInterface, returnedApInterface);
199        verify(wificond).createApInterface();
200    }
201
202    /**
203     * Verifies that setupDriverForSoftAp() returns null when wificond is not started.
204     */
205    @Test
206    public void testSetupDriverForSoftApModeErrorWhenWificondIsNotStarted() throws Exception {
207        when(mWifiInjector.makeWificond()).thenReturn(null);
208
209        IApInterface returnedApInterface = mWificondControl.setupDriverForSoftApMode();
210
211        assertEquals(null, returnedApInterface);
212    }
213
214    /**
215     * Verifies that setupDriverForSoftApMode() returns null when wificond failed to setup
216     * AP interface.
217     */
218    @Test
219    public void testSetupDriverForSoftApModeErrorWhenWificondFailedToSetupInterface()
220            throws Exception {
221        IWificond wificond = mock(IWificond.class);
222
223        when(mWifiInjector.makeWificond()).thenReturn(wificond);
224        when(wificond.createApInterface()).thenReturn(null);
225
226        IApInterface returnedApInterface = mWificondControl.setupDriverForSoftApMode();
227        assertEquals(null, returnedApInterface);
228    }
229
230    /**
231     * Verifies that enableSupplicant() calls wificond.
232     */
233    @Test
234    public void testEnableSupplicant() throws Exception {
235        IWificond wificond = mock(IWificond.class);
236        IClientInterface clientInterface = getMockClientInterface();
237
238        when(mWifiInjector.makeWificond()).thenReturn(wificond);
239        when(wificond.createClientInterface()).thenReturn(clientInterface);
240        when(clientInterface.enableSupplicant()).thenReturn(true);
241
242        mWificondControl.setupDriverForClientMode();
243        assertTrue(mWificondControl.enableSupplicant());
244        verify(clientInterface).enableSupplicant();
245    }
246
247    /**
248     * Verifies that enableSupplicant() returns false when there is no configured
249     * client interface.
250     */
251    @Test
252    public void testEnableSupplicantErrorWhenNoClientInterfaceConfigured() throws Exception {
253        IWificond wificond = mock(IWificond.class);
254        IClientInterface clientInterface = getMockClientInterface();
255
256        when(mWifiInjector.makeWificond()).thenReturn(wificond);
257        when(wificond.createClientInterface()).thenReturn(clientInterface);
258
259        // Configure client interface.
260        IClientInterface returnedClientInterface = mWificondControl.setupDriverForClientMode();
261        assertEquals(clientInterface, returnedClientInterface);
262
263        // Tear down interfaces.
264        assertTrue(mWificondControl.tearDownInterfaces());
265
266        // Enabling supplicant should fail.
267        assertFalse(mWificondControl.enableSupplicant());
268    }
269
270    /**
271     * Verifies that disableSupplicant() calls wificond.
272     */
273    @Test
274    public void testDisableSupplicant() throws Exception {
275        IWificond wificond = mock(IWificond.class);
276        IClientInterface clientInterface = getMockClientInterface();
277
278        when(mWifiInjector.makeWificond()).thenReturn(wificond);
279        when(wificond.createClientInterface()).thenReturn(clientInterface);
280        when(clientInterface.disableSupplicant()).thenReturn(true);
281
282        mWificondControl.setupDriverForClientMode();
283        assertTrue(mWificondControl.disableSupplicant());
284        verify(clientInterface).disableSupplicant();
285    }
286
287    /**
288     * Verifies that disableSupplicant() returns false when there is no configured
289     * client interface.
290     */
291    @Test
292    public void testDisableSupplicantErrorWhenNoClientInterfaceConfigured() throws Exception {
293        IWificond wificond = mock(IWificond.class);
294        IClientInterface clientInterface = getMockClientInterface();
295
296        when(mWifiInjector.makeWificond()).thenReturn(wificond);
297        when(wificond.createClientInterface()).thenReturn(clientInterface);
298
299        // Configure client interface.
300        IClientInterface returnedClientInterface = mWificondControl.setupDriverForClientMode();
301        assertEquals(clientInterface, returnedClientInterface);
302
303        // Tear down interfaces.
304        assertTrue(mWificondControl.tearDownInterfaces());
305
306        // Disabling supplicant should fail.
307        assertFalse(mWificondControl.disableSupplicant());
308    }
309
310    /**
311     * Verifies that tearDownInterfaces() calls wificond.
312     */
313    @Test
314    public void testTearDownInterfaces() throws Exception {
315        IWificond wificond = mock(IWificond.class);
316
317        when(mWifiInjector.makeWificond()).thenReturn(wificond);
318        assertTrue(mWificondControl.tearDownInterfaces());
319
320        verify(wificond).tearDownInterfaces();
321    }
322
323    /**
324     * Verifies that tearDownInterfaces() calls unsubscribeScanEvents() when there was
325     * a configured client interface.
326     */
327    @Test
328    public void testTearDownInterfacesRemovesScanEventSubscription() throws Exception {
329        IWifiScannerImpl scanner = setupClientInterfaceAndCreateMockWificondScanner();
330
331        assertTrue(mWificondControl.tearDownInterfaces());
332
333        verify(scanner).unsubscribeScanEvents();
334    }
335
336
337    /**
338     * Verifies that tearDownInterfaces() returns false when wificond is not started.
339     */
340    @Test
341    public void testTearDownInterfacesErrorWhenWificondIsNotStarterd() throws Exception {
342        when(mWifiInjector.makeWificond()).thenReturn(null);
343
344        assertFalse(mWificondControl.tearDownInterfaces());
345    }
346
347    /**
348     * Verifies that signalPoll() calls wificond.
349     */
350    @Test
351    public void testSignalPoll() throws Exception {
352        IWificond wificond = mock(IWificond.class);
353        IClientInterface clientInterface = getMockClientInterface();
354
355        when(mWifiInjector.makeWificond()).thenReturn(wificond);
356        when(wificond.createClientInterface()).thenReturn(clientInterface);
357
358        mWificondControl.setupDriverForClientMode();
359        mWificondControl.signalPoll();
360        verify(clientInterface).signalPoll();
361    }
362
363    /**
364     * Verifies that signalPoll() returns null when there is no configured client interface.
365     */
366    @Test
367    public void testSignalPollErrorWhenNoClientInterfaceConfigured() throws Exception {
368        IWificond wificond = mock(IWificond.class);
369        IClientInterface clientInterface = getMockClientInterface();
370
371        when(mWifiInjector.makeWificond()).thenReturn(wificond);
372        when(wificond.createClientInterface()).thenReturn(clientInterface);
373
374        // Configure client interface.
375        IClientInterface returnedClientInterface = mWificondControl.setupDriverForClientMode();
376        assertEquals(clientInterface, returnedClientInterface);
377
378        // Tear down interfaces.
379        assertTrue(mWificondControl.tearDownInterfaces());
380
381        // Signal poll should fail.
382        assertEquals(null, mWificondControl.signalPoll());
383    }
384
385    /**
386     * Verifies that getTxPacketCounters() calls wificond.
387     */
388    @Test
389    public void testGetTxPacketCounters() throws Exception {
390        IWificond wificond = mock(IWificond.class);
391        IClientInterface clientInterface = getMockClientInterface();
392
393        when(mWifiInjector.makeWificond()).thenReturn(wificond);
394        when(wificond.createClientInterface()).thenReturn(clientInterface);
395
396        mWificondControl.setupDriverForClientMode();
397        mWificondControl.getTxPacketCounters();
398        verify(clientInterface).getPacketCounters();
399    }
400
401    /**
402     * Verifies that getTxPacketCounters() returns null when there is no configured client
403     * interface.
404     */
405    @Test
406    public void testGetTxPacketCountersErrorWhenNoClientInterfaceConfigured() throws Exception {
407        IWificond wificond = mock(IWificond.class);
408        IClientInterface clientInterface = getMockClientInterface();
409
410        when(mWifiInjector.makeWificond()).thenReturn(wificond);
411        when(wificond.createClientInterface()).thenReturn(clientInterface);
412
413        // Configure client interface.
414        IClientInterface returnedClientInterface = mWificondControl.setupDriverForClientMode();
415        assertEquals(clientInterface, returnedClientInterface);
416
417        // Tear down interfaces.
418        assertTrue(mWificondControl.tearDownInterfaces());
419
420        // Signal poll should fail.
421        assertEquals(null, mWificondControl.getTxPacketCounters());
422    }
423
424    /**
425     * Verifies that getScanResults() returns null when there is no configured client
426     * interface.
427     */
428    @Test
429    public void testGetScanResultsErrorWhenNoClientInterfaceConfigured() throws Exception {
430        IWificond wificond = mock(IWificond.class);
431        IClientInterface clientInterface = getMockClientInterface();
432
433        when(mWifiInjector.makeWificond()).thenReturn(wificond);
434        when(wificond.createClientInterface()).thenReturn(clientInterface);
435
436        // Configure client interface.
437        IClientInterface returnedClientInterface = mWificondControl.setupDriverForClientMode();
438        assertEquals(clientInterface, returnedClientInterface);
439
440        // Tear down interfaces.
441        assertTrue(mWificondControl.tearDownInterfaces());
442
443        // getScanResults should fail.
444        assertEquals(0, mWificondControl.getScanResults().size());
445    }
446
447    /**
448     * Verifies that getScanResults() can parse NativeScanResult from wificond correctly,
449     */
450    @Test
451    public void testGetScanResults() throws Exception {
452        IWifiScannerImpl scanner = setupClientInterfaceAndCreateMockWificondScanner();
453        assertNotNull(scanner);
454
455        // Mock the returned array of NativeScanResult.
456        NativeScanResult[] mockScanResults = {MOCK_NATIVE_SCAN_RESULT};
457        when(scanner.getScanResults()).thenReturn(mockScanResults);
458
459        ArrayList<ScanDetail> returnedScanResults = mWificondControl.getScanResults();
460        assertEquals(mockScanResults.length, returnedScanResults.size());
461        // Since NativeScanResult is organized differently from ScanResult, this only checks
462        // a few fields.
463        for (int i = 0; i < mockScanResults.length; i++) {
464            assertArrayEquals(mockScanResults[i].ssid,
465                              returnedScanResults.get(i).getScanResult().SSID.getBytes());
466            assertEquals(mockScanResults[i].frequency,
467                         returnedScanResults.get(i).getScanResult().frequency);
468            assertEquals(mockScanResults[i].tsf,
469                         returnedScanResults.get(i).getScanResult().timestamp);
470        }
471    }
472
473    /**
474     * Verifies that Scan() can convert input parameters to SingleScanSettings correctly.
475     */
476    @Test
477    public void testScan() throws Exception {
478        IWifiScannerImpl scanner = setupClientInterfaceAndCreateMockWificondScanner();
479
480        when(scanner.scan(any(SingleScanSettings.class))).thenReturn(true);
481
482        assertTrue(mWificondControl.scan(SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_SET));
483        verify(scanner).scan(argThat(new ScanMatcher(
484                SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_SET)));
485    }
486
487    /**
488     * Verifies that Scan() can handle null input parameters correctly.
489     */
490    @Test
491    public void testScanNullParameters() throws Exception {
492        IWifiScannerImpl scanner = setupClientInterfaceAndCreateMockWificondScanner();
493
494        when(scanner.scan(any(SingleScanSettings.class))).thenReturn(true);
495
496        assertTrue(mWificondControl.scan(null, null));
497        verify(scanner).scan(argThat(new ScanMatcher(null, null)));
498    }
499
500    /**
501     * Verifies that Scan() can handle wificond scan failure.
502     */
503    @Test
504    public void testScanFailure() throws Exception {
505        IWifiScannerImpl scanner = setupClientInterfaceAndCreateMockWificondScanner();
506
507        when(scanner.scan(any(SingleScanSettings.class))).thenReturn(false);
508        assertFalse(mWificondControl.scan(SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_SET));
509        verify(scanner).scan(any(SingleScanSettings.class));
510    }
511
512    /**
513     * Verifies that startPnoScan() can convert input parameters to PnoSettings correctly.
514     */
515    @Test
516    public void testStartPnoScan() throws Exception {
517        IWifiScannerImpl scanner = setupClientInterfaceAndCreateMockWificondScanner();
518
519        when(scanner.startPnoScan(any(PnoSettings.class))).thenReturn(true);
520        assertTrue(mWificondControl.startPnoScan(TEST_PNO_SETTINGS));
521        verify(scanner).startPnoScan(argThat(new PnoScanMatcher(TEST_PNO_SETTINGS)));
522    }
523
524    /**
525     * Verifies that stopPnoScan() calls underlying wificond.
526     */
527    @Test
528    public void testStopPnoScan() throws Exception {
529        IWifiScannerImpl scanner = setupClientInterfaceAndCreateMockWificondScanner();
530
531        when(scanner.stopPnoScan()).thenReturn(true);
532        assertTrue(mWificondControl.stopPnoScan());
533        verify(scanner).stopPnoScan();
534    }
535
536    /**
537     * Verifies that stopPnoScan() can handle wificond failure.
538     */
539    @Test
540    public void testStopPnoScanFailure() throws Exception {
541        IWifiScannerImpl scanner = setupClientInterfaceAndCreateMockWificondScanner();
542
543        when(scanner.stopPnoScan()).thenReturn(false);
544        assertFalse(mWificondControl.stopPnoScan());
545        verify(scanner).stopPnoScan();
546    }
547
548    /**
549     * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon scan
550     * reuslt event.
551     */
552    @Test
553    public void testScanResultEvent() throws Exception {
554        IWifiScannerImpl scanner = setupClientInterfaceAndCreateMockWificondScanner();
555
556        ArgumentCaptor<IScanEvent> messageCaptor = ArgumentCaptor.forClass(IScanEvent.class);
557        verify(scanner).subscribeScanEvents(messageCaptor.capture());
558        IScanEvent scanEvent = messageCaptor.getValue();
559        assertNotNull(scanEvent);
560        scanEvent.OnScanResultReady();
561
562        verify(mWifiMonitor).broadcastScanResultEvent(any(String.class));
563    }
564
565    /**
566     * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon scan
567     * failed event.
568     */
569    @Test
570    public void testScanFailedEvent() throws Exception {
571        IWifiScannerImpl scanner = setupClientInterfaceAndCreateMockWificondScanner();
572
573        ArgumentCaptor<IScanEvent> messageCaptor = ArgumentCaptor.forClass(IScanEvent.class);
574        verify(scanner).subscribeScanEvents(messageCaptor.capture());
575        IScanEvent scanEvent = messageCaptor.getValue();
576        assertNotNull(scanEvent);
577        scanEvent.OnScanFailed();
578
579        verify(mWifiMonitor).broadcastScanFailedEvent(any(String.class));
580    }
581
582    /**
583     * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon pno scan
584     * reuslt event.
585     */
586    @Test
587    public void testPnoScanResultEvent() throws Exception {
588        IWifiScannerImpl scanner = setupClientInterfaceAndCreateMockWificondScanner();
589
590        ArgumentCaptor<IPnoScanEvent> messageCaptor = ArgumentCaptor.forClass(IPnoScanEvent.class);
591        verify(scanner).subscribePnoScanEvents(messageCaptor.capture());
592        IPnoScanEvent pnoScanEvent = messageCaptor.getValue();
593        assertNotNull(pnoScanEvent);
594        pnoScanEvent.OnPnoNetworkFound();
595
596        verify(mWifiMonitor).broadcastPnoScanResultEvent(any(String.class));
597    }
598
599    /**
600     * Verifies that abortScan() calls underlying wificond.
601     */
602    @Test
603    public void testAbortScan() throws Exception {
604        IWifiScannerImpl scanner = setupClientInterfaceAndCreateMockWificondScanner();
605
606        mWificondControl.abortScan();
607        verify(scanner).abortScan();
608    }
609
610    /**
611     * Helper method: create a mock IClientInterface which mocks all neccessary operations.
612     * Returns a mock IClientInterface.
613     */
614    private IClientInterface getMockClientInterface() throws Exception {
615        IClientInterface clientInterface = mock(IClientInterface.class);
616        IWifiScannerImpl scanner = mock(IWifiScannerImpl.class);
617
618        when(clientInterface.getWifiScannerImpl()).thenReturn(scanner);
619
620        return clientInterface;
621    }
622
623    /**
624     * Helper method: Setup interface to client mode for mWificondControl.
625     * Returns a mock IWifiScannerImpl.
626     */
627    private IWifiScannerImpl setupClientInterfaceAndCreateMockWificondScanner() throws Exception {
628        IWificond wificond = mock(IWificond.class);
629        IClientInterface clientInterface = mock(IClientInterface.class);
630        IWifiScannerImpl scanner = mock(IWifiScannerImpl.class);
631
632        when(mWifiInjector.makeWificond()).thenReturn(wificond);
633        when(wificond.createClientInterface()).thenReturn(clientInterface);
634        when(clientInterface.getWifiScannerImpl()).thenReturn(scanner);
635        when(clientInterface.getInterfaceName()).thenReturn(TEST_INTERFACE_NAME);
636
637        assertEquals(clientInterface, mWificondControl.setupDriverForClientMode());
638
639        return scanner;
640    }
641
642    // Create a ArgumentMatcher which captures a SingleScanSettings parameter and checks if it
643    // matches the provided frequency set and ssid set.
644    private class ScanMatcher implements ArgumentMatcher<SingleScanSettings> {
645        private final Set<Integer> mExpectedFreqs;
646        private final Set<String> mExpectedSsids;
647        ScanMatcher(Set<Integer> expectedFreqs, Set<String> expectedSsids) {
648            this.mExpectedFreqs = expectedFreqs;
649            this.mExpectedSsids = expectedSsids;
650        }
651
652        @Override
653        public boolean matches(SingleScanSettings settings) {
654            ArrayList<ChannelSettings> channelSettings = settings.channelSettings;
655            ArrayList<HiddenNetwork> hiddenNetworks = settings.hiddenNetworks;
656            if (mExpectedFreqs != null) {
657                Set<Integer> freqSet = new HashSet<Integer>();
658                for (ChannelSettings channel : channelSettings) {
659                    freqSet.add(channel.frequency);
660                }
661                if (!mExpectedFreqs.equals(freqSet)) {
662                    return false;
663                }
664            } else {
665                if (channelSettings != null && channelSettings.size() > 0) {
666                    return false;
667                }
668            }
669
670            if (mExpectedSsids != null) {
671                Set<String> ssidSet = new HashSet<String>();
672                for (HiddenNetwork network : hiddenNetworks) {
673                    ssidSet.add(NativeUtil.encodeSsid(
674                            NativeUtil.byteArrayToArrayList(network.ssid)));
675                }
676                if (!mExpectedSsids.equals(ssidSet)) {
677                    return false;
678                }
679
680            } else {
681                if (hiddenNetworks != null && hiddenNetworks.size() > 0) {
682                    return false;
683                }
684            }
685            return true;
686        }
687
688        @Override
689        public String toString() {
690            return "ScanMatcher{mExpectedFreqs=" + mExpectedFreqs
691                    + ", mExpectedSsids=" + mExpectedSsids + '}';
692        }
693    }
694
695    // Create a ArgumentMatcher which captures a PnoSettings parameter and checks if it
696    // matches the WifiNative.PnoSettings;
697    private class PnoScanMatcher implements ArgumentMatcher<PnoSettings> {
698        private final WifiNative.PnoSettings mExpectedPnoSettings;
699        PnoScanMatcher(WifiNative.PnoSettings expectedPnoSettings) {
700            this.mExpectedPnoSettings = expectedPnoSettings;
701        }
702        @Override
703        public boolean matches(PnoSettings settings) {
704            if (mExpectedPnoSettings == null) {
705                return false;
706            }
707            if (settings.intervalMs != mExpectedPnoSettings.periodInMs
708                    || settings.min2gRssi != mExpectedPnoSettings.min24GHzRssi
709                    || settings.min5gRssi != mExpectedPnoSettings.min5GHzRssi) {
710                return false;
711            }
712            if (settings.pnoNetworks == null || mExpectedPnoSettings.networkList == null) {
713                return false;
714            }
715            if (settings.pnoNetworks.size() != mExpectedPnoSettings.networkList.length) {
716                return false;
717            }
718
719            for (int i = 0; i < settings.pnoNetworks.size(); i++) {
720                if (!mExpectedPnoSettings.networkList[i].ssid.equals(NativeUtil.encodeSsid(
721                         NativeUtil.byteArrayToArrayList(settings.pnoNetworks.get(i).ssid)))) {
722                    return false;
723                }
724                boolean isNetworkHidden = (mExpectedPnoSettings.networkList[i].flags
725                        & WifiScanner.PnoSettings.PnoNetwork.FLAG_DIRECTED_SCAN) != 0;
726                if (isNetworkHidden != settings.pnoNetworks.get(i).isHidden) {
727                    return false;
728                }
729
730            }
731            return true;
732        }
733
734        @Override
735        public String toString() {
736            return "PnoScanMatcher{" + "mExpectedPnoSettings=" + mExpectedPnoSettings + '}';
737        }
738    }
739}
740