WificondControlTest.java revision e6d7f23569585f8f0fb02adbef992d3f1430db44
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.IWifiScannerImpl;
33import android.net.wifi.IWificond;
34import android.test.suitebuilder.annotation.SmallTest;
35
36import com.android.server.wifi.util.NativeUtil;
37import com.android.server.wifi.wificond.ChannelSettings;
38import com.android.server.wifi.wificond.HiddenNetwork;
39import com.android.server.wifi.wificond.NativeScanResult;
40import com.android.server.wifi.wificond.SingleScanSettings;
41
42import org.junit.Before;
43import org.junit.Test;
44import org.mockito.ArgumentMatcher;
45
46import java.util.ArrayList;
47import java.util.BitSet;
48import java.util.HashSet;
49import java.util.Set;
50
51/**
52 * Unit tests for {@link com.android.server.wifi.WificondControl}.
53 */
54@SmallTest
55public class WificondControlTest {
56    private WifiInjector mWifiInjector;
57    private WificondControl mWificondControl;
58    private static final byte[] TEST_SSID =
59            new byte[] {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'};
60    private static final byte[] TEST_BSSID =
61            new byte[] {(byte) 0x12, (byte) 0xef, (byte) 0xa1,
62                        (byte) 0x2c, (byte) 0x97, (byte) 0x8b};
63    // This the IE buffer which is consistent with TEST_SSID.
64    private static final byte[] TEST_INFO_ELEMENT =
65            new byte[] {
66                    // Element ID for SSID.
67                    (byte) 0x00,
68                    // Length of the SSID: 0x0b or 11.
69                    (byte) 0x0b,
70                    // This is string "GoogleGuest"
71                    'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'};
72
73    private static final int TEST_FREQUENCY = 2456;
74    private static final int TEST_SIGNAL_MBM = -4500;
75    private static final long TEST_TSF = 34455441;
76    private static final BitSet TEST_CAPABILITY = new BitSet(16) {{ set(2); set(5); }};
77    private static final boolean TEST_ASSOCIATED = true;
78    private static final NativeScanResult MOCK_NATIVE_SCAN_RESULT =
79            new NativeScanResult() {{
80                ssid = TEST_SSID;
81                bssid = TEST_BSSID;
82                infoElement = TEST_INFO_ELEMENT;
83                frequency = TEST_FREQUENCY;
84                signalMbm = TEST_SIGNAL_MBM;
85                capability = TEST_CAPABILITY;
86                associated = TEST_ASSOCIATED;
87            }};
88
89    private static final Set<Integer> SCAN_FREQ_SET =
90            new HashSet<Integer>() {{
91                add(2410);
92                add(2450);
93                add(5050);
94                add(5200);
95            }};
96    private static final Set<String> SCAN_HIDDEN_NETWORK_SSID_SET =
97            new HashSet<String>() {{
98                // These SSIDs should be quoted.
99                add("\"hiddenAP1\"");
100                add("\"hiddenAP2\"");
101            }};
102
103    @Before
104    public void setUp() throws Exception {
105        mWifiInjector = mock(WifiInjector.class);
106        mWificondControl = new WificondControl(mWifiInjector);
107    }
108
109    /**
110     * Verifies that setupDriverForClientMode() calls Wificond.
111     */
112    @Test
113    public void testSetupDriverForClientMode() throws Exception {
114        IWificond wificond = mock(IWificond.class);
115        IClientInterface clientInterface = mock(IClientInterface.class);
116
117        when(mWifiInjector.makeWificond()).thenReturn(wificond);
118        when(wificond.createClientInterface()).thenReturn(clientInterface);
119
120        IClientInterface returnedClientInterface = mWificondControl.setupDriverForClientMode();
121        assertEquals(clientInterface, returnedClientInterface);
122        verify(wificond).createClientInterface();
123    }
124
125    /**
126     * Verifies that setupDriverForClientMode() returns null when wificond is not started.
127     */
128    @Test
129    public void testSetupDriverForClientModeErrorWhenWificondIsNotStarted() throws Exception {
130        when(mWifiInjector.makeWificond()).thenReturn(null);
131
132        IClientInterface returnedClientInterface = mWificondControl.setupDriverForClientMode();
133        assertEquals(null, returnedClientInterface);
134    }
135
136    /**
137     * Verifies that setupDriverForClientMode() returns null when wificond failed to setup client
138     * interface.
139     */
140    @Test
141    public void testSetupDriverForClientModeErrorWhenWificondFailedToSetupInterface()
142            throws Exception {
143        IWificond wificond = mock(IWificond.class);
144
145        when(mWifiInjector.makeWificond()).thenReturn(wificond);
146        when(wificond.createClientInterface()).thenReturn(null);
147
148        IClientInterface returnedClientInterface = mWificondControl.setupDriverForClientMode();
149        assertEquals(null, returnedClientInterface);
150    }
151
152    /**
153     * Verifies that setupDriverForSoftApMode() calls wificond.
154     */
155    @Test
156    public void testSetupDriverForSoftApMode() throws Exception {
157        IWificond wificond = mock(IWificond.class);
158        IApInterface apInterface = mock(IApInterface.class);
159
160        when(mWifiInjector.makeWificond()).thenReturn(wificond);
161        when(wificond.createApInterface()).thenReturn(apInterface);
162
163        IApInterface returnedApInterface = mWificondControl.setupDriverForSoftApMode();
164        assertEquals(apInterface, returnedApInterface);
165        verify(wificond).createApInterface();
166    }
167
168    /**
169     * Verifies that setupDriverForSoftAp() returns null when wificond is not started.
170     */
171    @Test
172    public void testSetupDriverForSoftApModeErrorWhenWificondIsNotStarted() throws Exception {
173        when(mWifiInjector.makeWificond()).thenReturn(null);
174
175        IApInterface returnedApInterface = mWificondControl.setupDriverForSoftApMode();
176
177        assertEquals(null, returnedApInterface);
178    }
179
180    /**
181     * Verifies that setupDriverForSoftApMode() returns null when wificond failed to setup
182     * AP interface.
183     */
184    @Test
185    public void testSetupDriverForSoftApModeErrorWhenWificondFailedToSetupInterface()
186            throws Exception {
187        IWificond wificond = mock(IWificond.class);
188
189        when(mWifiInjector.makeWificond()).thenReturn(wificond);
190        when(wificond.createApInterface()).thenReturn(null);
191
192        IApInterface returnedApInterface = mWificondControl.setupDriverForSoftApMode();
193        assertEquals(null, returnedApInterface);
194    }
195
196    /**
197     * Verifies that enableSupplicant() calls wificond.
198     */
199    @Test
200    public void testEnableSupplicant() throws Exception {
201        IWificond wificond = mock(IWificond.class);
202        IClientInterface clientInterface = mock(IClientInterface.class);
203
204        when(mWifiInjector.makeWificond()).thenReturn(wificond);
205        when(wificond.createClientInterface()).thenReturn(clientInterface);
206        when(clientInterface.enableSupplicant()).thenReturn(true);
207
208        mWificondControl.setupDriverForClientMode();
209        assertTrue(mWificondControl.enableSupplicant());
210        verify(clientInterface).enableSupplicant();
211    }
212
213    /**
214     * Verifies that enableSupplicant() returns false when there is no configured
215     * client interface.
216     */
217    @Test
218    public void testEnableSupplicantErrorWhenNoClientInterfaceConfigured() throws Exception {
219        IWificond wificond = mock(IWificond.class);
220        IClientInterface clientInterface = mock(IClientInterface.class);
221
222        when(mWifiInjector.makeWificond()).thenReturn(wificond);
223        when(wificond.createClientInterface()).thenReturn(clientInterface);
224
225        // Configure client interface.
226        IClientInterface returnedClientInterface = mWificondControl.setupDriverForClientMode();
227        assertEquals(clientInterface, returnedClientInterface);
228
229        // Tear down interfaces.
230        assertTrue(mWificondControl.tearDownInterfaces());
231
232        // Enabling supplicant should fail.
233        assertFalse(mWificondControl.enableSupplicant());
234    }
235
236    /**
237     * Verifies that disableSupplicant() calls wificond.
238     */
239    @Test
240    public void testDisableSupplicant() throws Exception {
241        IWificond wificond = mock(IWificond.class);
242        IClientInterface clientInterface = mock(IClientInterface.class);
243
244        when(mWifiInjector.makeWificond()).thenReturn(wificond);
245        when(wificond.createClientInterface()).thenReturn(clientInterface);
246        when(clientInterface.disableSupplicant()).thenReturn(true);
247
248        mWificondControl.setupDriverForClientMode();
249        assertTrue(mWificondControl.disableSupplicant());
250        verify(clientInterface).disableSupplicant();
251    }
252
253    /**
254     * Verifies that disableSupplicant() returns false when there is no configured
255     * client interface.
256     */
257    @Test
258    public void testDisableSupplicantErrorWhenNoClientInterfaceConfigured() throws Exception {
259        IWificond wificond = mock(IWificond.class);
260        IClientInterface clientInterface = mock(IClientInterface.class);
261
262        when(mWifiInjector.makeWificond()).thenReturn(wificond);
263        when(wificond.createClientInterface()).thenReturn(clientInterface);
264
265        // Configure client interface.
266        IClientInterface returnedClientInterface = mWificondControl.setupDriverForClientMode();
267        assertEquals(clientInterface, returnedClientInterface);
268
269        // Tear down interfaces.
270        assertTrue(mWificondControl.tearDownInterfaces());
271
272        // Disabling supplicant should fail.
273        assertFalse(mWificondControl.disableSupplicant());
274    }
275
276    /**
277     * Verifies that tearDownInterfaces() calls wificond.
278     */
279    @Test
280    public void testTearDownInterfaces() throws Exception {
281        IWificond wificond = mock(IWificond.class);
282
283        when(mWifiInjector.makeWificond()).thenReturn(wificond);
284
285        assertTrue(mWificondControl.tearDownInterfaces());
286        verify(wificond).tearDownInterfaces();
287    }
288
289    /**
290     * Verifies that tearDownInterfaces() returns false when wificond is not started.
291     */
292    @Test
293    public void testTearDownInterfacesErrorWhenWificondIsNotStarterd() throws Exception {
294        when(mWifiInjector.makeWificond()).thenReturn(null);
295
296        assertFalse(mWificondControl.tearDownInterfaces());
297    }
298
299    /**
300     * Verifies that signalPoll() calls wificond.
301     */
302    @Test
303    public void testSignalPoll() throws Exception {
304        IWificond wificond = mock(IWificond.class);
305        IClientInterface clientInterface = mock(IClientInterface.class);
306
307        when(mWifiInjector.makeWificond()).thenReturn(wificond);
308        when(wificond.createClientInterface()).thenReturn(clientInterface);
309
310        mWificondControl.setupDriverForClientMode();
311        mWificondControl.signalPoll();
312        verify(clientInterface).signalPoll();
313    }
314
315    /**
316     * Verifies that signalPoll() returns null when there is no configured client interface.
317     */
318    @Test
319    public void testSignalPollErrorWhenNoClientInterfaceConfigured() throws Exception {
320        IWificond wificond = mock(IWificond.class);
321        IClientInterface clientInterface = mock(IClientInterface.class);
322
323        when(mWifiInjector.makeWificond()).thenReturn(wificond);
324        when(wificond.createClientInterface()).thenReturn(clientInterface);
325
326        // Configure client interface.
327        IClientInterface returnedClientInterface = mWificondControl.setupDriverForClientMode();
328        assertEquals(clientInterface, returnedClientInterface);
329
330        // Tear down interfaces.
331        assertTrue(mWificondControl.tearDownInterfaces());
332
333        // Signal poll should fail.
334        assertEquals(null, mWificondControl.signalPoll());
335    }
336
337    /**
338     * Verifies that getTxPacketCounters() calls wificond.
339     */
340    @Test
341    public void testGetTxPacketCounters() throws Exception {
342        IWificond wificond = mock(IWificond.class);
343        IClientInterface clientInterface = mock(IClientInterface.class);
344
345        when(mWifiInjector.makeWificond()).thenReturn(wificond);
346        when(wificond.createClientInterface()).thenReturn(clientInterface);
347
348        mWificondControl.setupDriverForClientMode();
349        mWificondControl.getTxPacketCounters();
350        verify(clientInterface).getPacketCounters();
351    }
352
353    /**
354     * Verifies that getTxPacketCounters() returns null when there is no configured client
355     * interface.
356     */
357    @Test
358    public void testGetTxPacketCountersErrorWhenNoClientInterfaceConfigured() throws Exception {
359        IWificond wificond = mock(IWificond.class);
360        IClientInterface clientInterface = mock(IClientInterface.class);
361
362        when(mWifiInjector.makeWificond()).thenReturn(wificond);
363        when(wificond.createClientInterface()).thenReturn(clientInterface);
364
365        // Configure client interface.
366        IClientInterface returnedClientInterface = mWificondControl.setupDriverForClientMode();
367        assertEquals(clientInterface, returnedClientInterface);
368
369        // Tear down interfaces.
370        assertTrue(mWificondControl.tearDownInterfaces());
371
372        // Signal poll should fail.
373        assertEquals(null, mWificondControl.getTxPacketCounters());
374    }
375
376    /**
377     * Verifies that getScanResults() returns null when there is no configured client
378     * interface.
379     */
380    @Test
381    public void testGetScanResultsErrorWhenNoClientInterfaceConfigured() throws Exception {
382        IWificond wificond = mock(IWificond.class);
383        IClientInterface clientInterface = mock(IClientInterface.class);
384
385        when(mWifiInjector.makeWificond()).thenReturn(wificond);
386        when(wificond.createClientInterface()).thenReturn(clientInterface);
387
388        // Configure client interface.
389        IClientInterface returnedClientInterface = mWificondControl.setupDriverForClientMode();
390        assertEquals(clientInterface, returnedClientInterface);
391
392        // Tear down interfaces.
393        assertTrue(mWificondControl.tearDownInterfaces());
394
395        // getScanResults should fail.
396        assertEquals(0, mWificondControl.getScanResults().size());
397    }
398
399    /**
400     * Verifies that getScanResults() can parse NativeScanResult from wificond correctly,
401     */
402    @Test
403    public void testGetScanResults() throws Exception {
404        IWifiScannerImpl scanner = setupClientInterfaceAndCreateMockWificondScanner();
405        assertNotNull(scanner);
406
407        // Mock the returned array of NativeScanResult.
408        NativeScanResult[] mockScanResults = {MOCK_NATIVE_SCAN_RESULT};
409        when(scanner.getScanResults()).thenReturn(mockScanResults);
410
411        ArrayList<ScanDetail> returnedScanResults = mWificondControl.getScanResults();
412        assertEquals(mockScanResults.length, returnedScanResults.size());
413        // Since NativeScanResult is organized differently from ScanResult, this only checks
414        // a few fields.
415        for (int i = 0; i < mockScanResults.length; i++) {
416            assertArrayEquals(mockScanResults[i].ssid,
417                              returnedScanResults.get(i).getScanResult().SSID.getBytes());
418            assertEquals(mockScanResults[i].frequency,
419                         returnedScanResults.get(i).getScanResult().frequency);
420            assertEquals(mockScanResults[i].tsf,
421                         returnedScanResults.get(i).getScanResult().timestamp);
422        }
423    }
424
425    /**
426     * Verifies that Scan() can convert input parameters to SingleScanSettings correctly.
427     */
428    @Test
429    public void testScan() throws Exception {
430        IWifiScannerImpl scanner = setupClientInterfaceAndCreateMockWificondScanner();
431
432        when(scanner.scan(any(SingleScanSettings.class))).thenReturn(true);
433
434        assertTrue(mWificondControl.scan(SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_SET));
435        verify(scanner).scan(argThat(new ScanMatcher(
436                SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_SET)));
437    }
438
439    /**
440     * Verifies that Scan() can handle null input parameters correctly.
441     */
442    @Test
443    public void testScanNullParameters() throws Exception {
444        IWifiScannerImpl scanner = setupClientInterfaceAndCreateMockWificondScanner();
445
446        when(scanner.scan(any(SingleScanSettings.class))).thenReturn(true);
447
448        assertTrue(mWificondControl.scan(null, null));
449        verify(scanner).scan(argThat(new ScanMatcher(null, null)));
450    }
451
452    /**
453     * Verifies that Scan() can handle wificond scan failure.
454     */
455    @Test
456    public void testScanFailure() throws Exception {
457        IWifiScannerImpl scanner = setupClientInterfaceAndCreateMockWificondScanner();
458
459        when(scanner.scan(any(SingleScanSettings.class))).thenReturn(false);
460        assertFalse(mWificondControl.scan(SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_SET));
461        verify(scanner).scan(any(SingleScanSettings.class));
462    }
463
464    /**
465     * Helper method: Setup interface to client mode for mWificondControl.
466     * Returns a mock IWifiScannerImpl.
467     */
468    private IWifiScannerImpl setupClientInterfaceAndCreateMockWificondScanner() throws Exception {
469        IWificond wificond = mock(IWificond.class);
470        IClientInterface clientInterface = mock(IClientInterface.class);
471        IWifiScannerImpl scanner = mock(IWifiScannerImpl.class);
472
473        when(mWifiInjector.makeWificond()).thenReturn(wificond);
474        when(wificond.createClientInterface()).thenReturn(clientInterface);
475        when(clientInterface.getWifiScannerImpl()).thenReturn(scanner);
476
477        assertEquals(clientInterface, mWificondControl.setupDriverForClientMode());
478
479        return scanner;
480    }
481
482    // Create a ArgumentMatcher which captures a SingleScanSettings parameter and checks if it
483    // matches the provided frequency set and ssid set.
484    private class ScanMatcher extends ArgumentMatcher<SingleScanSettings> {
485        private final Set<Integer> mExpectedFreqs;
486        private final Set<String> mExpectedSsids;
487        ScanMatcher(Set<Integer> expectedFreqs, Set<String> expectedSsids) {
488            this.mExpectedFreqs = expectedFreqs;
489            this.mExpectedSsids = expectedSsids;
490        }
491
492        @Override
493        public boolean matches(Object argument) {
494            SingleScanSettings settings = (SingleScanSettings) argument;
495            ArrayList<ChannelSettings> channelSettings = settings.channelSettings;
496            ArrayList<HiddenNetwork> hiddenNetworks = settings.hiddenNetworks;
497            if (mExpectedFreqs != null) {
498                Set<Integer> freqSet = new HashSet<Integer>();
499                for (ChannelSettings channel : channelSettings) {
500                    freqSet.add(channel.frequency);
501                }
502                if (!mExpectedFreqs.equals(freqSet)) {
503                    return false;
504                }
505            } else {
506                if (channelSettings != null && channelSettings.size() > 0) {
507                    return false;
508                }
509            }
510
511            if (mExpectedSsids != null) {
512                Set<String> ssidSet = new HashSet<String>();
513                for (HiddenNetwork network : hiddenNetworks) {
514                    ssidSet.add(NativeUtil.encodeSsid(
515                            NativeUtil.byteArrayToArrayList(network.ssid)));
516                }
517                if (!mExpectedSsids.equals(ssidSet)) {
518                    return false;
519                }
520
521            } else {
522                if (hiddenNetworks != null && hiddenNetworks.size() > 0) {
523                    return false;
524                }
525            }
526            return true;
527        }
528    }
529
530}
531