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
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.assertTrue;
23import static org.mockito.Mockito.anyBoolean;
24import static org.mockito.Mockito.eq;
25import static org.mockito.Mockito.mock;
26import static org.mockito.Mockito.never;
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.WifiConfiguration;
33import android.test.suitebuilder.annotation.SmallTest;
34
35import org.junit.Before;
36import org.junit.Test;
37import org.mockito.Mock;
38import org.mockito.MockitoAnnotations;
39
40import java.util.HashSet;
41import java.util.Set;
42import java.util.regex.Pattern;
43
44/**
45 * Unit tests for {@link com.android.server.wifi.WifiNative}.
46 */
47@SmallTest
48public class WifiNativeTest {
49    private static final long FATE_REPORT_DRIVER_TIMESTAMP_USEC = 12345;
50    private static final byte[] FATE_REPORT_FRAME_BYTES = new byte[] {
51            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 0, 1, 2, 3, 4, 5, 6, 7};
52    private static final WifiNative.TxFateReport TX_FATE_REPORT = new WifiNative.TxFateReport(
53            WifiLoggerHal.TX_PKT_FATE_SENT,
54            FATE_REPORT_DRIVER_TIMESTAMP_USEC,
55            WifiLoggerHal.FRAME_TYPE_ETHERNET_II,
56            FATE_REPORT_FRAME_BYTES
57    );
58    private static final WifiNative.RxFateReport RX_FATE_REPORT = new WifiNative.RxFateReport(
59            WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID,
60            FATE_REPORT_DRIVER_TIMESTAMP_USEC,
61            WifiLoggerHal.FRAME_TYPE_ETHERNET_II,
62            FATE_REPORT_FRAME_BYTES
63    );
64    private static final FrameTypeMapping[] FRAME_TYPE_MAPPINGS = new FrameTypeMapping[] {
65            new FrameTypeMapping(WifiLoggerHal.FRAME_TYPE_UNKNOWN, "unknown", "N/A"),
66            new FrameTypeMapping(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, "data", "Ethernet"),
67            new FrameTypeMapping(WifiLoggerHal.FRAME_TYPE_80211_MGMT, "802.11 management",
68                    "802.11 Mgmt"),
69            new FrameTypeMapping((byte) 42, "42", "N/A")
70    };
71    private static final FateMapping[] TX_FATE_MAPPINGS = new FateMapping[] {
72            new FateMapping(WifiLoggerHal.TX_PKT_FATE_ACKED, "acked"),
73            new FateMapping(WifiLoggerHal.TX_PKT_FATE_SENT, "sent"),
74            new FateMapping(WifiLoggerHal.TX_PKT_FATE_FW_QUEUED, "firmware queued"),
75            new FateMapping(WifiLoggerHal.TX_PKT_FATE_FW_DROP_INVALID,
76                    "firmware dropped (invalid frame)"),
77            new FateMapping(
78                    WifiLoggerHal.TX_PKT_FATE_FW_DROP_NOBUFS,  "firmware dropped (no bufs)"),
79            new FateMapping(
80                    WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER, "firmware dropped (other)"),
81            new FateMapping(WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED, "driver queued"),
82            new FateMapping(WifiLoggerHal.TX_PKT_FATE_DRV_DROP_INVALID,
83                    "driver dropped (invalid frame)"),
84            new FateMapping(WifiLoggerHal.TX_PKT_FATE_DRV_DROP_NOBUFS,
85                    "driver dropped (no bufs)"),
86            new FateMapping(WifiLoggerHal.TX_PKT_FATE_DRV_DROP_OTHER, "driver dropped (other)"),
87            new FateMapping((byte) 42, "42")
88    };
89    private static final FateMapping[] RX_FATE_MAPPINGS = new FateMapping[] {
90            new FateMapping(WifiLoggerHal.RX_PKT_FATE_SUCCESS, "success"),
91            new FateMapping(WifiLoggerHal.RX_PKT_FATE_FW_QUEUED, "firmware queued"),
92            new FateMapping(
93                    WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER, "firmware dropped (filter)"),
94            new FateMapping(WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID,
95                    "firmware dropped (invalid frame)"),
96            new FateMapping(
97                    WifiLoggerHal.RX_PKT_FATE_FW_DROP_NOBUFS, "firmware dropped (no bufs)"),
98            new FateMapping(
99                    WifiLoggerHal.RX_PKT_FATE_FW_DROP_OTHER, "firmware dropped (other)"),
100            new FateMapping(WifiLoggerHal.RX_PKT_FATE_DRV_QUEUED, "driver queued"),
101            new FateMapping(
102                    WifiLoggerHal.RX_PKT_FATE_DRV_DROP_FILTER, "driver dropped (filter)"),
103            new FateMapping(WifiLoggerHal.RX_PKT_FATE_DRV_DROP_INVALID,
104                    "driver dropped (invalid frame)"),
105            new FateMapping(
106                    WifiLoggerHal.RX_PKT_FATE_DRV_DROP_NOBUFS, "driver dropped (no bufs)"),
107            new FateMapping(WifiLoggerHal.RX_PKT_FATE_DRV_DROP_OTHER, "driver dropped (other)"),
108            new FateMapping((byte) 42, "42")
109    };
110    private static final WifiNative.SignalPollResult SIGNAL_POLL_RESULT =
111            new WifiNative.SignalPollResult() {{
112                currentRssi = -60;
113                txBitrate = 12;
114                associationFrequency = 5240;
115            }};
116    private static final WifiNative.TxPacketCounters PACKET_COUNTERS_RESULT =
117            new WifiNative.TxPacketCounters() {{
118                txSucceeded = 2000;
119                txFailed = 120;
120            }};
121
122    private static final Set<Integer> SCAN_FREQ_SET =
123            new HashSet<Integer>() {{
124                add(2410);
125                add(2450);
126                add(5050);
127                add(5200);
128            }};
129    private static final String TEST_QUOTED_SSID_1 = "\"testSsid1\"";
130    private static final String TEST_QUOTED_SSID_2 = "\"testSsid2\"";
131    private static final Set<String> SCAN_HIDDEN_NETWORK_SSID_SET =
132            new HashSet<String>() {{
133                add(TEST_QUOTED_SSID_1);
134                add(TEST_QUOTED_SSID_2);
135            }};
136
137    private static final WifiNative.PnoSettings TEST_PNO_SETTINGS =
138            new WifiNative.PnoSettings() {{
139                isConnected = false;
140                periodInMs = 6000;
141                networkList = new WifiNative.PnoNetwork[2];
142                networkList[0] = new WifiNative.PnoNetwork();
143                networkList[1] = new WifiNative.PnoNetwork();
144                networkList[0].ssid = TEST_QUOTED_SSID_1;
145                networkList[1].ssid = TEST_QUOTED_SSID_2;
146            }};
147
148    @Mock private WifiVendorHal mWifiVendorHal;
149    @Mock private WificondControl mWificondControl;
150    @Mock private SupplicantStaIfaceHal mStaIfaceHal;
151    private WifiNative mWifiNative;
152
153    @Before
154    public void setUp() throws Exception {
155        MockitoAnnotations.initMocks(this);
156        when(mWifiVendorHal.isVendorHalSupported()).thenReturn(true);
157        when(mWifiVendorHal.startVendorHal(anyBoolean())).thenReturn(true);
158        mWifiNative = new WifiNative("test0", mWifiVendorHal, mStaIfaceHal, mWificondControl);
159    }
160
161    /**
162     * Verifies that TxFateReport's constructor sets all of the TxFateReport fields.
163     */
164    @Test
165    public void testTxFateReportCtorSetsFields() {
166        WifiNative.TxFateReport fateReport = new WifiNative.TxFateReport(
167                WifiLoggerHal.TX_PKT_FATE_SENT,  // non-zero value
168                FATE_REPORT_DRIVER_TIMESTAMP_USEC,
169                WifiLoggerHal.FRAME_TYPE_ETHERNET_II,  // non-zero value
170                FATE_REPORT_FRAME_BYTES
171        );
172        assertEquals(WifiLoggerHal.TX_PKT_FATE_SENT, fateReport.mFate);
173        assertEquals(FATE_REPORT_DRIVER_TIMESTAMP_USEC, fateReport.mDriverTimestampUSec);
174        assertEquals(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, fateReport.mFrameType);
175        assertArrayEquals(FATE_REPORT_FRAME_BYTES, fateReport.mFrameBytes);
176    }
177
178    /**
179     * Verifies that RxFateReport's constructor sets all of the RxFateReport fields.
180     */
181    @Test
182    public void testRxFateReportCtorSetsFields() {
183        WifiNative.RxFateReport fateReport = new WifiNative.RxFateReport(
184                WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID,  // non-zero value
185                FATE_REPORT_DRIVER_TIMESTAMP_USEC,
186                WifiLoggerHal.FRAME_TYPE_ETHERNET_II,  // non-zero value
187                FATE_REPORT_FRAME_BYTES
188        );
189        assertEquals(WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID, fateReport.mFate);
190        assertEquals(FATE_REPORT_DRIVER_TIMESTAMP_USEC, fateReport.mDriverTimestampUSec);
191        assertEquals(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, fateReport.mFrameType);
192        assertArrayEquals(FATE_REPORT_FRAME_BYTES, fateReport.mFrameBytes);
193    }
194
195    /**
196     * Verifies the hashCode methods for HiddenNetwork and PnoNetwork classes
197     */
198    @Test
199    public void testHashCode() {
200        WifiNative.HiddenNetwork hiddenNet1 = new WifiNative.HiddenNetwork();
201        hiddenNet1.ssid = new String("sametext");
202
203        WifiNative.HiddenNetwork hiddenNet2 = new WifiNative.HiddenNetwork();
204        hiddenNet2.ssid = new String("sametext");
205
206        assertTrue(hiddenNet1.equals(hiddenNet2));
207        assertEquals(hiddenNet1.hashCode(), hiddenNet2.hashCode());
208
209        WifiNative.PnoNetwork pnoNet1 = new WifiNative.PnoNetwork();
210        pnoNet1.ssid = new String("sametext");
211        pnoNet1.flags = 2;
212        pnoNet1.auth_bit_field = 4;
213
214        WifiNative.PnoNetwork pnoNet2 = new WifiNative.PnoNetwork();
215        pnoNet2.ssid = new String("sametext");
216        pnoNet2.flags = 2;
217        pnoNet2.auth_bit_field = 4;
218
219        assertTrue(pnoNet1.equals(pnoNet2));
220        assertEquals(pnoNet1.hashCode(), pnoNet2.hashCode());
221    }
222
223    // Support classes for test{Tx,Rx}FateReportToString.
224    private static class FrameTypeMapping {
225        byte mTypeNumber;
226        String mExpectedTypeText;
227        String mExpectedProtocolText;
228        FrameTypeMapping(byte typeNumber, String expectedTypeText, String expectedProtocolText) {
229            this.mTypeNumber = typeNumber;
230            this.mExpectedTypeText = expectedTypeText;
231            this.mExpectedProtocolText = expectedProtocolText;
232        }
233    }
234    private static class FateMapping {
235        byte mFateNumber;
236        String mExpectedText;
237        FateMapping(byte fateNumber, String expectedText) {
238            this.mFateNumber = fateNumber;
239            this.mExpectedText = expectedText;
240        }
241    }
242
243    /**
244     * Verifies that FateReport.getTableHeader() prints the right header.
245     */
246    @Test
247    public void testFateReportTableHeader() {
248        final String header = WifiNative.FateReport.getTableHeader();
249        assertEquals(
250                "\nTime usec        Walltime      Direction  Fate                              "
251                + "Protocol      Type                     Result\n"
252                + "---------        --------      ---------  ----                              "
253                + "--------      ----                     ------\n", header);
254    }
255
256    /**
257     * Verifies that TxFateReport.toTableRowString() includes the information we care about.
258     */
259    @Test
260    public void testTxFateReportToTableRowString() {
261        WifiNative.TxFateReport fateReport = TX_FATE_REPORT;
262        assertTrue(
263                fateReport.toTableRowString().replaceAll("\\s+", " ").trim().matches(
264                    FATE_REPORT_DRIVER_TIMESTAMP_USEC + " "  // timestamp
265                            + "\\d{2}:\\d{2}:\\d{2}\\.\\d{3} "  // walltime
266                            + "TX "  // direction
267                            + "sent "  // fate
268                            + "Ethernet "  // type
269                            + "N/A "  // protocol
270                            + "N/A"  // result
271                )
272        );
273
274        for (FrameTypeMapping frameTypeMapping : FRAME_TYPE_MAPPINGS) {
275            fateReport = new WifiNative.TxFateReport(
276                    WifiLoggerHal.TX_PKT_FATE_SENT,
277                    FATE_REPORT_DRIVER_TIMESTAMP_USEC,
278                    frameTypeMapping.mTypeNumber,
279                    FATE_REPORT_FRAME_BYTES
280            );
281            assertTrue(
282                    fateReport.toTableRowString().replaceAll("\\s+", " ").trim().matches(
283                            FATE_REPORT_DRIVER_TIMESTAMP_USEC + " "  // timestamp
284                                    + "\\d{2}:\\d{2}:\\d{2}\\.\\d{3} "  // walltime
285                                    + "TX "  // direction
286                                    + "sent "  // fate
287                                    + frameTypeMapping.mExpectedProtocolText + " "  // type
288                                    + "N/A "  // protocol
289                                    + "N/A"  // result
290                    )
291            );
292        }
293
294        for (FateMapping fateMapping : TX_FATE_MAPPINGS) {
295            fateReport = new WifiNative.TxFateReport(
296                    fateMapping.mFateNumber,
297                    FATE_REPORT_DRIVER_TIMESTAMP_USEC,
298                    WifiLoggerHal.FRAME_TYPE_80211_MGMT,
299                    FATE_REPORT_FRAME_BYTES
300            );
301            assertTrue(
302                    fateReport.toTableRowString().replaceAll("\\s+", " ").trim().matches(
303                            FATE_REPORT_DRIVER_TIMESTAMP_USEC + " "  // timestamp
304                                    + "\\d{2}:\\d{2}:\\d{2}\\.\\d{3} "  // walltime
305                                    + "TX "  // direction
306                                    + Pattern.quote(fateMapping.mExpectedText) + " "  // fate
307                                    + "802.11 Mgmt "  // type
308                                    + "N/A "  // protocol
309                                    + "N/A"  // result
310                    )
311            );
312        }
313    }
314
315    /**
316     * Verifies that TxFateReport.toVerboseStringWithPiiAllowed() includes the information we care
317     * about.
318     */
319    @Test
320    public void testTxFateReportToVerboseStringWithPiiAllowed() {
321        WifiNative.TxFateReport fateReport = TX_FATE_REPORT;
322
323        String verboseFateString = fateReport.toVerboseStringWithPiiAllowed();
324        assertTrue(verboseFateString.contains("Frame direction: TX"));
325        assertTrue(verboseFateString.contains("Frame timestamp: 12345"));
326        assertTrue(verboseFateString.contains("Frame fate: sent"));
327        assertTrue(verboseFateString.contains("Frame type: data"));
328        assertTrue(verboseFateString.contains("Frame protocol: Ethernet"));
329        assertTrue(verboseFateString.contains("Frame protocol type: N/A"));
330        assertTrue(verboseFateString.contains("Frame length: 16"));
331        assertTrue(verboseFateString.contains(
332                "61 62 63 64 65 66 67 68 00 01 02 03 04 05 06 07")); // hex dump
333        // TODO(quiche): uncomment this, once b/27975149 is fixed.
334        // assertTrue(verboseFateString.contains("abcdefgh........"));  // hex dump
335
336        for (FrameTypeMapping frameTypeMapping : FRAME_TYPE_MAPPINGS) {
337            fateReport = new WifiNative.TxFateReport(
338                    WifiLoggerHal.TX_PKT_FATE_SENT,
339                    FATE_REPORT_DRIVER_TIMESTAMP_USEC,
340                    frameTypeMapping.mTypeNumber,
341                    FATE_REPORT_FRAME_BYTES
342            );
343            verboseFateString = fateReport.toVerboseStringWithPiiAllowed();
344            assertTrue(verboseFateString.contains("Frame type: "
345                    + frameTypeMapping.mExpectedTypeText));
346        }
347
348        for (FateMapping fateMapping : TX_FATE_MAPPINGS) {
349            fateReport = new WifiNative.TxFateReport(
350                    fateMapping.mFateNumber,
351                    FATE_REPORT_DRIVER_TIMESTAMP_USEC,
352                    WifiLoggerHal.FRAME_TYPE_80211_MGMT,
353                    FATE_REPORT_FRAME_BYTES
354            );
355            verboseFateString = fateReport.toVerboseStringWithPiiAllowed();
356            assertTrue(verboseFateString.contains("Frame fate: " + fateMapping.mExpectedText));
357        }
358    }
359
360    /**
361     * Verifies that RxFateReport.toTableRowString() includes the information we care about.
362     */
363    @Test
364    public void testRxFateReportToTableRowString() {
365        WifiNative.RxFateReport fateReport = RX_FATE_REPORT;
366        assertTrue(
367                fateReport.toTableRowString().replaceAll("\\s+", " ").trim().matches(
368                        FATE_REPORT_DRIVER_TIMESTAMP_USEC + " "  // timestamp
369                                + "\\d{2}:\\d{2}:\\d{2}\\.\\d{3} "  // walltime
370                                + "RX "  // direction
371                                + Pattern.quote("firmware dropped (invalid frame) ")  // fate
372                                + "Ethernet "  // type
373                                + "N/A "  // protocol
374                                + "N/A"  // result
375                )
376        );
377
378        // FrameTypeMappings omitted, as they're the same as for TX.
379
380        for (FateMapping fateMapping : RX_FATE_MAPPINGS) {
381            fateReport = new WifiNative.RxFateReport(
382                    fateMapping.mFateNumber,
383                    FATE_REPORT_DRIVER_TIMESTAMP_USEC,
384                    WifiLoggerHal.FRAME_TYPE_80211_MGMT,
385                    FATE_REPORT_FRAME_BYTES
386            );
387            assertTrue(
388                    fateReport.toTableRowString().replaceAll("\\s+", " ").trim().matches(
389                            FATE_REPORT_DRIVER_TIMESTAMP_USEC + " "  // timestamp
390                                    + "\\d{2}:\\d{2}:\\d{2}\\.\\d{3} "  // walltime
391                                    + "RX "  // direction
392                                    + Pattern.quote(fateMapping.mExpectedText) + " " // fate
393                                    + "802.11 Mgmt "  // type
394                                    + "N/A " // protocol
395                                    + "N/A"  // result
396                    )
397            );
398        }
399    }
400
401    /**
402     * Verifies that RxFateReport.toVerboseStringWithPiiAllowed() includes the information we care
403     * about.
404     */
405    @Test
406    public void testRxFateReportToVerboseStringWithPiiAllowed() {
407        WifiNative.RxFateReport fateReport = RX_FATE_REPORT;
408
409        String verboseFateString = fateReport.toVerboseStringWithPiiAllowed();
410        assertTrue(verboseFateString.contains("Frame direction: RX"));
411        assertTrue(verboseFateString.contains("Frame timestamp: 12345"));
412        assertTrue(verboseFateString.contains("Frame fate: firmware dropped (invalid frame)"));
413        assertTrue(verboseFateString.contains("Frame type: data"));
414        assertTrue(verboseFateString.contains("Frame protocol: Ethernet"));
415        assertTrue(verboseFateString.contains("Frame protocol type: N/A"));
416        assertTrue(verboseFateString.contains("Frame length: 16"));
417        assertTrue(verboseFateString.contains(
418                "61 62 63 64 65 66 67 68 00 01 02 03 04 05 06 07")); // hex dump
419        // TODO(quiche): uncomment this, once b/27975149 is fixed.
420        // assertTrue(verboseFateString.contains("abcdefgh........"));  // hex dump
421
422        // FrameTypeMappings omitted, as they're the same as for TX.
423
424        for (FateMapping fateMapping : RX_FATE_MAPPINGS) {
425            fateReport = new WifiNative.RxFateReport(
426                    fateMapping.mFateNumber,
427                    FATE_REPORT_DRIVER_TIMESTAMP_USEC,
428                    WifiLoggerHal.FRAME_TYPE_80211_MGMT,
429                    FATE_REPORT_FRAME_BYTES
430            );
431            verboseFateString = fateReport.toVerboseStringWithPiiAllowed();
432            assertTrue(verboseFateString.contains("Frame fate: " + fateMapping.mExpectedText));
433        }
434    }
435
436    /**
437     * Verifies that startPktFateMonitoring returns false when HAL is not started.
438     */
439    @Test
440    public void testStartPktFateMonitoringReturnsFalseWhenHalIsNotStarted() {
441        assertFalse(mWifiNative.isHalStarted());
442        assertFalse(mWifiNative.startPktFateMonitoring());
443    }
444
445    /**
446     * Verifies that getTxPktFates returns error when HAL is not started.
447     */
448    @Test
449    public void testGetTxPktFatesReturnsErrorWhenHalIsNotStarted() {
450        WifiNative.TxFateReport[] fateReports = null;
451        assertFalse(mWifiNative.isHalStarted());
452        assertFalse(mWifiNative.getTxPktFates(fateReports));
453    }
454
455    /**
456     * Verifies that getRxPktFates returns error when HAL is not started.
457     */
458    @Test
459    public void testGetRxPktFatesReturnsErrorWhenHalIsNotStarted() {
460        WifiNative.RxFateReport[] fateReports = null;
461        assertFalse(mWifiNative.isHalStarted());
462        assertFalse(mWifiNative.getRxPktFates(fateReports));
463    }
464
465    // TODO(quiche): Add tests for the success cases (when HAL has been started). Specifically:
466    // - testStartPktFateMonitoringCallsHalIfHalIsStarted()
467    // - testGetTxPktFatesCallsHalIfHalIsStarted()
468    // - testGetRxPktFatesCallsHalIfHalIsStarted()
469    //
470    // Adding these tests is difficult to do at the moment, because we can't mock out the HAL
471    // itself. Also, we can't mock out the native methods, because those methods are private.
472    // b/28005116.
473
474    /** Verifies that getDriverStateDumpNative returns null when HAL is not started. */
475    @Test
476    public void testGetDriverStateDumpReturnsNullWhenHalIsNotStarted() {
477        assertEquals(null, mWifiNative.getDriverStateDump());
478    }
479
480    // TODO(b/28005116): Add test for the success case of getDriverStateDump().
481
482    /**
483     * Verifies that setupDriverForClientMode() calls underlying WificondControl.
484     */
485    @Test
486    public void testSetupDriverForClientMode() {
487        IClientInterface clientInterface = mock(IClientInterface.class);
488        when(mWificondControl.setupDriverForClientMode()).thenReturn(clientInterface);
489
490        IClientInterface returnedClientInterface = mWifiNative.setupForClientMode();
491        assertEquals(clientInterface, returnedClientInterface);
492        verify(mWifiVendorHal).startVendorHal(eq(true));
493        verify(mWificondControl).setupDriverForClientMode();
494    }
495
496    /**
497     * Verifies that setupDriverForClientMode() does not call start vendor HAL when it is not
498     * supported and calls underlying WificondControl setup.
499     */
500    @Test
501    public void testSetupDriverForClientModeWithNoVendorHal() {
502        when(mWifiVendorHal.isVendorHalSupported()).thenReturn(false);
503        IClientInterface clientInterface = mock(IClientInterface.class);
504        when(mWificondControl.setupDriverForClientMode()).thenReturn(clientInterface);
505
506        IClientInterface returnedClientInterface = mWifiNative.setupForClientMode();
507        assertEquals(clientInterface, returnedClientInterface);
508        verify(mWifiVendorHal, never()).startVendorHal(anyBoolean());
509        verify(mWificondControl).setupDriverForClientMode();
510    }
511
512    /**
513     * Verifies that setupDriverForClientMode() returns null when underlying WificondControl
514     * call fails.
515     */
516    @Test
517    public void testSetupDriverForClientModeWificondError() {
518        when(mWificondControl.setupDriverForClientMode()).thenReturn(null);
519
520        IClientInterface returnedClientInterface = mWifiNative.setupForClientMode();
521        assertEquals(null, returnedClientInterface);
522        verify(mWifiVendorHal).startVendorHal(eq(true));
523        verify(mWificondControl).setupDriverForClientMode();
524    }
525
526    /**
527     * Verifies that setupDriverForClientMode() returns null when underlying Hal call fails.
528     */
529    @Test
530    public void testSetupDriverForClientModeHalError() {
531        when(mWifiVendorHal.startVendorHal(anyBoolean())).thenReturn(false);
532
533        IClientInterface returnedClientInterface = mWifiNative.setupForClientMode();
534        assertEquals(null, returnedClientInterface);
535        verify(mWifiVendorHal).startVendorHal(eq(true));
536        verify(mWificondControl, never()).setupDriverForClientMode();
537    }
538
539    /**
540     * Verifies that setupDriverForSoftApMode() calls underlying WificondControl.
541     */
542    @Test
543    public void testSetupDriverForSoftApMode() {
544        IApInterface apInterface = mock(IApInterface.class);
545        when(mWificondControl.setupDriverForSoftApMode()).thenReturn(apInterface);
546
547        IApInterface returnedApInterface = mWifiNative.setupForSoftApMode();
548        assertEquals(apInterface, returnedApInterface);
549        verify(mWifiVendorHal).startVendorHal(eq(false));
550        verify(mWificondControl).setupDriverForSoftApMode();
551    }
552
553    /**
554     * Verifies that setupDriverForClientMode() does not call start vendor HAL when it is not
555     * supported and calls underlying WificondControl setup.
556     */
557    @Test
558    public void testSetupDriverForSoftApModeWithNoVendorHal() {
559        when(mWifiVendorHal.isVendorHalSupported()).thenReturn(false);
560        IApInterface apInterface = mock(IApInterface.class);
561        when(mWificondControl.setupDriverForSoftApMode()).thenReturn(apInterface);
562
563        IApInterface returnedApInterface = mWifiNative.setupForSoftApMode();
564        assertEquals(apInterface, returnedApInterface);
565        verify(mWifiVendorHal, never()).startVendorHal(anyBoolean());
566        verify(mWificondControl).setupDriverForSoftApMode();
567    }
568
569    /**
570     * Verifies that setupDriverForSoftApMode() returns null when underlying WificondControl
571     * call fails.
572     */
573    @Test
574    public void testSetupDriverForSoftApModeWificondError() {
575        when(mWificondControl.setupDriverForSoftApMode()).thenReturn(null);
576        IApInterface returnedApInterface = mWifiNative.setupForSoftApMode();
577
578        assertEquals(null, returnedApInterface);
579        verify(mWifiVendorHal).startVendorHal(eq(false));
580        verify(mWificondControl).setupDriverForSoftApMode();
581    }
582
583    /**
584     * Verifies that setupDriverForSoftApMode() returns null when underlying Hal call fails.
585     */
586    @Test
587    public void testSetupDriverForSoftApModeHalError() {
588        when(mWifiVendorHal.startVendorHal(anyBoolean())).thenReturn(false);
589
590        IApInterface returnedApInterface = mWifiNative.setupForSoftApMode();
591        assertEquals(null, returnedApInterface);
592        verify(mWifiVendorHal).startVendorHal(eq(false));
593        verify(mWificondControl, never()).setupDriverForSoftApMode();
594    }
595
596    /**
597     * Verifies that enableSupplicant() calls underlying WificondControl.
598     */
599    @Test
600    public void testEnableSupplicant() {
601        when(mWificondControl.enableSupplicant()).thenReturn(true);
602
603        mWifiNative.enableSupplicant();
604        verify(mWificondControl).enableSupplicant();
605    }
606
607    /**
608     * Verifies that disableSupplicant() calls underlying WificondControl.
609     */
610    @Test
611    public void testDisableSupplicant() {
612        when(mWificondControl.disableSupplicant()).thenReturn(true);
613
614        mWifiNative.disableSupplicant();
615        verify(mWificondControl).disableSupplicant();
616    }
617
618    /**
619     * Verifies that tearDownInterfaces() calls underlying WificondControl.
620     */
621    @Test
622    public void testTearDown() {
623        when(mWificondControl.tearDownInterfaces()).thenReturn(true);
624
625        assertTrue(mWifiNative.tearDown());
626        verify(mWificondControl).tearDownInterfaces();
627        verify(mWifiVendorHal).stopVendorHal();
628    }
629
630    /**
631     * Verifies that signalPoll() calls underlying WificondControl.
632     */
633    @Test
634    public void testSignalPoll() throws Exception {
635        when(mWificondControl.signalPoll()).thenReturn(SIGNAL_POLL_RESULT);
636
637        assertEquals(SIGNAL_POLL_RESULT, mWifiNative.signalPoll());
638        verify(mWificondControl).signalPoll();
639    }
640
641    /**
642     * Verifies that getTxPacketCounters() calls underlying WificondControl.
643     */
644    @Test
645    public void testGetTxPacketCounters() throws Exception {
646        when(mWificondControl.getTxPacketCounters()).thenReturn(PACKET_COUNTERS_RESULT);
647
648        assertEquals(PACKET_COUNTERS_RESULT, mWifiNative.getTxPacketCounters());
649        verify(mWificondControl).getTxPacketCounters();
650    }
651
652    /**
653     * Verifies that scan() calls underlying WificondControl.
654     */
655    @Test
656    public void testScan() throws Exception {
657        mWifiNative.scan(SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_SET);
658        verify(mWificondControl).scan(SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_SET);
659    }
660
661    /**
662     * Verifies that startPnoscan() calls underlying WificondControl.
663     */
664    @Test
665    public void testStartPnoScan() throws Exception {
666        mWifiNative.startPnoScan(TEST_PNO_SETTINGS);
667        verify(mWificondControl).startPnoScan(TEST_PNO_SETTINGS);
668    }
669
670    /**
671     * Verifies that stopPnoscan() calls underlying WificondControl.
672     */
673    @Test
674    public void testStopPnoScan() throws Exception {
675        mWifiNative.stopPnoScan();
676        verify(mWificondControl).stopPnoScan();
677    }
678
679    /**
680     * Verifies that connectToNetwork() calls underlying WificondControl and SupplicantStaIfaceHal.
681     */
682    @Test
683    public void testConnectToNetwork() throws Exception {
684        WifiConfiguration config = mock(WifiConfiguration.class);
685        mWifiNative.connectToNetwork(config);
686        // connectToNetwork() should abort ongoing scan before connection.
687        verify(mWificondControl).abortScan();
688        verify(mStaIfaceHal).connectToNetwork(config);
689    }
690
691    /**
692     * Verifies that roamToNetwork() calls underlying WificondControl and SupplicantStaIfaceHal.
693     */
694    @Test
695    public void testRoamToNetwork() throws Exception {
696        WifiConfiguration config = mock(WifiConfiguration.class);
697        mWifiNative.roamToNetwork(config);
698        // roamToNetwork() should abort ongoing scan before connection.
699        verify(mWificondControl).abortScan();
700        verify(mStaIfaceHal).roamToNetwork(config);
701    }
702
703}
704