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 */
16package com.android.server.wifi;
17
18import static org.junit.Assert.*;
19import static org.mockito.Matchers.eq;
20import static org.mockito.Mockito.any;
21import static org.mockito.Mockito.anyString;
22import static org.mockito.Mockito.doAnswer;
23import static org.mockito.Mockito.never;
24import static org.mockito.Mockito.verify;
25import static org.mockito.Mockito.when;
26
27import android.app.test.MockAnswerUtil.AnswerWithArguments;
28import android.content.Context;
29import android.hardware.wifi.supplicant.V1_0.ISupplicantNetwork;
30import android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetwork;
31import android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetworkCallback;
32import android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetworkCallback
33        .NetworkRequestEapSimGsmAuthParams;
34import android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetworkCallback
35        .NetworkRequestEapSimUmtsAuthParams;
36import android.hardware.wifi.supplicant.V1_0.SupplicantStatus;
37import android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode;
38import android.net.wifi.WifiConfiguration;
39import android.net.wifi.WifiEnterpriseConfig;
40import android.os.RemoteException;
41import android.text.TextUtils;
42
43import com.android.internal.R;
44import com.android.server.wifi.util.NativeUtil;
45
46import org.junit.Before;
47import org.junit.Test;
48import org.mockito.Mock;
49import org.mockito.MockitoAnnotations;
50
51import java.util.ArrayList;
52import java.util.HashMap;
53import java.util.Map;
54import java.util.Random;
55
56/**
57 * Unit tests for SupplicantStaNetworkHal
58 */
59public class SupplicantStaNetworkHalTest {
60    private static final String IFACE_NAME = "wlan0";
61    private static final Map<String, String> NETWORK_EXTRAS_VALUES = new HashMap<>();
62    static {
63        NETWORK_EXTRAS_VALUES.put("key1", "value1");
64        NETWORK_EXTRAS_VALUES.put("key2", "value2");
65    }
66    private static final String NETWORK_EXTRAS_SERIALIZED =
67            "%7B%22key1%22%3A%22value1%22%2C%22key2%22%3A%22value2%22%7D";
68    private static final String ANONYMOUS_IDENTITY = "aaa@bbb.cc.ddd";
69
70    private SupplicantStaNetworkHal mSupplicantNetwork;
71    private SupplicantStatus mStatusSuccess;
72    private SupplicantStatus mStatusFailure;
73    @Mock private ISupplicantStaNetwork mISupplicantStaNetworkMock;
74    @Mock private Context mContext;
75    @Mock private WifiMonitor mWifiMonitor;
76    private SupplicantNetworkVariables mSupplicantVariables;
77    private MockResources mResources;
78    private ISupplicantStaNetworkCallback mISupplicantStaNetworkCallback;
79
80    @Before
81    public void setUp() throws Exception {
82        MockitoAnnotations.initMocks(this);
83        mStatusSuccess = createSupplicantStatus(SupplicantStatusCode.SUCCESS);
84        mStatusFailure = createSupplicantStatus(SupplicantStatusCode.FAILURE_UNKNOWN);
85        mSupplicantVariables = new SupplicantNetworkVariables();
86        setupISupplicantNetworkMock();
87
88        mResources = new MockResources();
89        when(mContext.getResources()).thenReturn(mResources);
90        createSupplicantStaNetwork();
91    }
92
93    /**
94     * Tests the saving of WifiConfiguration to wpa_supplicant.
95     */
96    @Test
97    public void testOpenNetworkWifiConfigurationSaveLoad() throws Exception {
98        WifiConfiguration config = WifiConfigurationTestUtil.createOpenHiddenNetwork();
99        config.updateIdentifier = "45";
100        testWifiConfigurationSaveLoad(config);
101    }
102
103    /**
104     * Tests the saving/loading of WifiConfiguration to wpa_supplicant with psk passphrase.
105     */
106    @Test
107    public void testPskPassphraseNetworkWifiConfigurationSaveLoad() throws Exception {
108        WifiConfiguration config = WifiConfigurationTestUtil.createPskNetwork();
109        config.requirePMF = true;
110        testWifiConfigurationSaveLoad(config);
111        verify(mISupplicantStaNetworkMock).setPskPassphrase(anyString());
112        verify(mISupplicantStaNetworkMock)
113                .getPskPassphrase(any(ISupplicantStaNetwork.getPskPassphraseCallback.class));
114        verify(mISupplicantStaNetworkMock, never()).setPsk(any(byte[].class));
115        verify(mISupplicantStaNetworkMock, never())
116                .getPsk(any(ISupplicantStaNetwork.getPskCallback.class));
117    }
118
119    /**
120     * Tests the saving/loading of WifiConfiguration to wpa_supplicant with raw psk.
121     */
122    @Test
123    public void testPskNetworkWifiConfigurationSaveLoad() throws Exception {
124        WifiConfiguration config = WifiConfigurationTestUtil.createPskNetwork();
125        config.preSharedKey = "945ef00c463c2a7c2496376b13263d1531366b46377179a4b17b393687450779";
126        testWifiConfigurationSaveLoad(config);
127        verify(mISupplicantStaNetworkMock).setPsk(any(byte[].class));
128        verify(mISupplicantStaNetworkMock)
129                .getPsk(any(ISupplicantStaNetwork.getPskCallback.class));
130        verify(mISupplicantStaNetworkMock, never()).setPskPassphrase(anyString());
131        verify(mISupplicantStaNetworkMock)
132                .getPskPassphrase(any(ISupplicantStaNetwork.getPskPassphraseCallback.class));
133    }
134
135    /**
136     * Tests the saving of WifiConfiguration to wpa_supplicant removes enclosing quotes of psk
137     * passphrase
138     */
139    @Test
140    public void testPskNetworkWifiConfigurationSaveRemovesPskQuotes() throws Exception {
141        WifiConfiguration config = WifiConfigurationTestUtil.createPskNetwork();
142        config.preSharedKey = "\"quoted_psd\"";
143        assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
144        assertEquals(mSupplicantVariables.pskPassphrase,
145                NativeUtil.removeEnclosingQuotes(config.preSharedKey));
146    }
147
148    /**
149     * Tests the saving/loading of WifiConfiguration to wpa_supplicant.
150     */
151    @Test
152    public void testWepNetworkWifiConfigurationSaveLoad() throws Exception {
153        WifiConfiguration config = WifiConfigurationTestUtil.createWepHiddenNetwork();
154        config.BSSID = "34:45:19:09:45";
155        testWifiConfigurationSaveLoad(config);
156    }
157
158    /**
159     * Tests the saving of WifiConfiguration to wpa_supplicant.
160     */
161    @Test
162    public void testEapPeapGtcNetworkWifiConfigurationSaveLoad() throws Exception {
163        WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
164        config.enterpriseConfig =
165                WifiConfigurationTestUtil.createPEAPWifiEnterpriseConfigWithGTCPhase2();
166        testWifiConfigurationSaveLoad(config);
167    }
168
169    /**
170     * Tests the saving of WifiConfiguration to wpa_supplicant.
171     */
172    @Test
173    public void testEapTlsNoneNetworkWifiConfigurationSaveLoad() throws Exception {
174        WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
175        config.enterpriseConfig =
176                WifiConfigurationTestUtil.createTLSWifiEnterpriseConfigWithNonePhase2();
177        testWifiConfigurationSaveLoad(config);
178    }
179
180    /**
181     * Tests the saving of WifiConfiguration to wpa_supplicant.
182     */
183    @Test
184    public void testEapTlsNoneClientCertNetworkWifiConfigurationSaveLoad() throws Exception {
185        WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
186        config.enterpriseConfig =
187                WifiConfigurationTestUtil.createTLSWifiEnterpriseConfigWithNonePhase2();
188        config.enterpriseConfig.setClientCertificateAlias("test_alias");
189        testWifiConfigurationSaveLoad(config);
190    }
191
192    /**
193     * Tests the saving of WifiConfiguration to wpa_supplicant.
194     */
195    @Test
196    public void testEapTlsAkaNetworkWifiConfigurationSaveLoad() throws Exception {
197        WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
198        config.enterpriseConfig =
199                WifiConfigurationTestUtil.createTLSWifiEnterpriseConfigWithAkaPhase2();
200        testWifiConfigurationSaveLoad(config);
201    }
202
203    /**
204     * Tests the loading of network ID.
205     */
206    @Test
207    public void testNetworkIdLoad() throws Exception {
208        WifiConfiguration config = WifiConfigurationTestUtil.createWepHiddenNetwork();
209        assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
210
211        // Modify the supplicant variable directly.
212        mSupplicantVariables.networkId = 5;
213        WifiConfiguration loadConfig = new WifiConfiguration();
214        Map<String, String> networkExtras = new HashMap<>();
215        assertTrue(mSupplicantNetwork.loadWifiConfiguration(loadConfig, networkExtras));
216        assertEquals(mSupplicantVariables.networkId, loadConfig.networkId);
217    }
218
219    /**
220     * Tests the failure to load ssid aborts the loading of network variables.
221     */
222    @Test
223    public void testSsidLoadFailure() throws Exception {
224        WifiConfiguration config = WifiConfigurationTestUtil.createWepHiddenNetwork();
225        assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
226
227        doAnswer(new AnswerWithArguments() {
228            public void answer(ISupplicantStaNetwork.getSsidCallback cb) throws RemoteException {
229                cb.onValues(mStatusFailure, mSupplicantVariables.ssid);
230            }
231        }).when(mISupplicantStaNetworkMock)
232                .getSsid(any(ISupplicantStaNetwork.getSsidCallback.class));
233
234        WifiConfiguration loadConfig = new WifiConfiguration();
235        Map<String, String> networkExtras = new HashMap<>();
236        assertFalse(mSupplicantNetwork.loadWifiConfiguration(loadConfig, networkExtras));
237    }
238
239    /**
240     * Tests the failure to save ssid.
241     */
242    @Test
243    public void testSsidSaveFailure() throws Exception {
244        WifiConfiguration config = WifiConfigurationTestUtil.createWepHiddenNetwork();
245
246        doAnswer(new AnswerWithArguments() {
247            public SupplicantStatus answer(ArrayList<Byte> ssid) throws RemoteException {
248                return mStatusFailure;
249            }
250        }).when(mISupplicantStaNetworkMock).setSsid(any(ArrayList.class));
251
252        assertFalse(mSupplicantNetwork.saveWifiConfiguration(config));
253    }
254
255    /**
256     * Tests the failure to save invalid key mgmt (unknown bit set in the
257     * {@link WifiConfiguration#allowedKeyManagement} being saved).
258     */
259    @Test
260    public void testInvalidKeyMgmtSaveFailure() throws Exception {
261        WifiConfiguration config = WifiConfigurationTestUtil.createWepHiddenNetwork();
262        config.allowedKeyManagement.set(10);
263        try {
264            assertFalse(mSupplicantNetwork.saveWifiConfiguration(config));
265        } catch (IllegalArgumentException e) {
266            return;
267        }
268        assertTrue(false);
269    }
270
271    /**
272     * Tests the failure to load invalid key mgmt (unkown bit set in the supplicant network key_mgmt
273     * variable read).
274     */
275    @Test
276    public void testInvalidKeyMgmtLoadFailure() throws Exception {
277        WifiConfiguration config = WifiConfigurationTestUtil.createWepHiddenNetwork();
278        assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
279
280        // Modify the supplicant variable directly.
281        mSupplicantVariables.keyMgmtMask = 0xFFFFF;
282        WifiConfiguration loadConfig = new WifiConfiguration();
283        Map<String, String> networkExtras = new HashMap<>();
284        try {
285            assertFalse(mSupplicantNetwork.loadWifiConfiguration(loadConfig, networkExtras));
286        } catch (IllegalArgumentException e) {
287            return;
288        }
289        assertTrue(false);
290    }
291
292    /**
293     * Tests the failure to save invalid bssid (less than 6 bytes in the
294     * {@link WifiConfiguration#BSSID} being saved).
295     */
296    @Test
297    public void testInvalidBssidSaveFailure() throws Exception {
298        WifiConfiguration config = WifiConfigurationTestUtil.createWepHiddenNetwork();
299        config.getNetworkSelectionStatus().setNetworkSelectionBSSID("45:34:23:12");
300        try {
301            assertFalse(mSupplicantNetwork.saveWifiConfiguration(config));
302        } catch (IllegalArgumentException e) {
303            return;
304        }
305        assertTrue(false);
306    }
307
308    /**
309     * Tests the failure to load invalid bssid (less than 6 bytes in the supplicant bssid variable
310     * read).
311     */
312    @Test
313    public void testInvalidBssidLoadFailure() throws Exception {
314        WifiConfiguration config = WifiConfigurationTestUtil.createWepHiddenNetwork();
315        assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
316
317        // Modify the supplicant variable directly.
318        mSupplicantVariables.bssid = new byte[3];
319        WifiConfiguration loadConfig = new WifiConfiguration();
320        Map<String, String> networkExtras = new HashMap<>();
321        try {
322            assertFalse(mSupplicantNetwork.loadWifiConfiguration(loadConfig, networkExtras));
323        } catch (IllegalArgumentException e) {
324            return;
325        }
326        assertTrue(false);
327    }
328
329    /**
330     * Tests the loading of invalid ssid from wpa_supplicant.
331     */
332    @Test
333    public void testInvalidSsidLoadFailure() throws Exception {
334        WifiConfiguration config = WifiConfigurationTestUtil.createWepHiddenNetwork();
335        assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
336
337        // Modify the supplicant variable directly.
338        mSupplicantVariables.ssid = null;
339
340        WifiConfiguration loadConfig = new WifiConfiguration();
341        Map<String, String> networkExtras = new HashMap<>();
342        assertFalse(mSupplicantNetwork.loadWifiConfiguration(loadConfig, networkExtras));
343    }
344
345    /**
346     * Tests the loading of invalid eap method from wpa_supplicant.
347     * Invalid eap method is assumed to be a non enterprise network. So, the loading should
348     * succeed as a non-enterprise network.
349     */
350    @Test
351    public void testInvalidEapMethodLoadFailure() throws Exception {
352        WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
353        config.enterpriseConfig =
354                WifiConfigurationTestUtil.createPEAPWifiEnterpriseConfigWithGTCPhase2();
355        assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
356
357        // Modify the supplicant variable directly.
358        mSupplicantVariables.eapMethod = -1;
359
360        WifiConfiguration loadConfig = new WifiConfiguration();
361        Map<String, String> networkExtras = new HashMap<>();
362        assertTrue(mSupplicantNetwork.loadWifiConfiguration(loadConfig, networkExtras));
363    }
364
365    /**
366     * Tests the loading of invalid eap phase2 method from wpa_supplicant.
367     */
368    @Test
369    public void testInvalidEapPhase2MethodLoadFailure() throws Exception {
370        WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
371        config.enterpriseConfig =
372                WifiConfigurationTestUtil.createPEAPWifiEnterpriseConfigWithGTCPhase2();
373        assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
374
375        // Modify the supplicant variable directly.
376        mSupplicantVariables.eapPhase2Method = -1;
377
378        WifiConfiguration loadConfig = new WifiConfiguration();
379        Map<String, String> networkExtras = new HashMap<>();
380        assertFalse(mSupplicantNetwork.loadWifiConfiguration(loadConfig, networkExtras));
381    }
382
383    /**
384     * Tests the parsing of GSM auth response parameters.
385     */
386    @Test
387    public void testSendNetworkEapSimGsmAuthResponseWith2KcSresPair() throws Exception {
388        final byte[] kc = new byte[]{0x45, 0x45, 0x32, 0x34, 0x45, 0x10, 0x34, 0x12};
389        final byte[] sres = new byte[]{0x12, 0x10, 0x32, 0x23};
390        // Send 2 kc/sres pair for this request.
391        String paramsStr = ":" + NativeUtil.hexStringFromByteArray(kc)
392                + ":" + NativeUtil.hexStringFromByteArray(sres)
393                + ":" + NativeUtil.hexStringFromByteArray(kc)
394                + ":" + NativeUtil.hexStringFromByteArray(sres);
395
396        doAnswer(new AnswerWithArguments() {
397            public SupplicantStatus answer(
398                    ArrayList<ISupplicantStaNetwork.NetworkResponseEapSimGsmAuthParams> params)
399                    throws RemoteException {
400                assertEquals(2, params.size());
401                assertArrayEquals(kc, params.get(0).kc);
402                assertArrayEquals(sres, params.get(0).sres);
403                assertArrayEquals(kc, params.get(1).kc);
404                assertArrayEquals(sres, params.get(1).sres);
405                return mStatusSuccess;
406            }
407        }).when(mISupplicantStaNetworkMock).sendNetworkEapSimGsmAuthResponse(any(ArrayList.class));
408
409        assertTrue(mSupplicantNetwork.sendNetworkEapSimGsmAuthResponse(paramsStr));
410    }
411
412    /**
413     * Tests the parsing of GSM auth response parameters.
414     */
415    @Test
416    public void testSendNetworkEapSimGsmAuthResponseWith3KcSresPair() throws Exception {
417        final byte[] kc1 = new byte[]{0x45, 0x45, 0x32, 0x34, 0x45, 0x10, 0x34, 0x12};
418        final byte[] sres1 = new byte[]{0x12, 0x10, 0x32, 0x23};
419        final byte[] kc2 = new byte[]{0x45, 0x34, 0x12, 0x34, 0x45, 0x10, 0x34, 0x12};
420        final byte[] sres2 = new byte[]{0x12, 0x23, 0x12, 0x23};
421        final byte[] kc3 = new byte[]{0x25, 0x34, 0x12, 0x14, 0x45, 0x10, 0x34, 0x12};
422        final byte[] sres3 = new byte[]{0x42, 0x23, 0x22, 0x23};
423        // Send 3 kc/sres pair for this request.
424        String paramsStr = ":" + NativeUtil.hexStringFromByteArray(kc1)
425                + ":" + NativeUtil.hexStringFromByteArray(sres1)
426                + ":" + NativeUtil.hexStringFromByteArray(kc2)
427                + ":" + NativeUtil.hexStringFromByteArray(sres2)
428                + ":" + NativeUtil.hexStringFromByteArray(kc3)
429                + ":" + NativeUtil.hexStringFromByteArray(sres3);
430
431        doAnswer(new AnswerWithArguments() {
432            public SupplicantStatus answer(
433                    ArrayList<ISupplicantStaNetwork.NetworkResponseEapSimGsmAuthParams> params)
434                    throws RemoteException {
435                assertEquals(3, params.size());
436                assertArrayEquals(kc1, params.get(0).kc);
437                assertArrayEquals(sres1, params.get(0).sres);
438                assertArrayEquals(kc2, params.get(1).kc);
439                assertArrayEquals(sres2, params.get(1).sres);
440                assertArrayEquals(kc3, params.get(2).kc);
441                assertArrayEquals(sres3, params.get(2).sres);
442                return mStatusSuccess;
443            }
444        }).when(mISupplicantStaNetworkMock).sendNetworkEapSimGsmAuthResponse(any(ArrayList.class));
445
446        assertTrue(mSupplicantNetwork.sendNetworkEapSimGsmAuthResponse(paramsStr));
447    }
448
449    /**
450     * Tests the parsing of invalid GSM auth response parameters (invalid kc & sres lengths).
451     */
452    @Test
453    public void testSendInvalidKcSresLenNetworkEapSimGsmAuthResponse() throws Exception {
454        final byte[] kc1 = new byte[]{0x45, 0x45, 0x32, 0x34, 0x45, 0x10, 0x34};
455        final byte[] sres1 = new byte[]{0x12, 0x10, 0x23};
456        final byte[] kc2 = new byte[]{0x45, 0x34, 0x12, 0x34, 0x45, 0x10, 0x34, 0x12};
457        final byte[] sres2 = new byte[]{0x12, 0x23, 0x12, 0x23};
458        // Send 2 kc/sres pair for this request.
459        String paramsStr = ":" + NativeUtil.hexStringFromByteArray(kc1)
460                + ":" + NativeUtil.hexStringFromByteArray(sres1)
461                + ":" + NativeUtil.hexStringFromByteArray(kc2)
462                + ":" + NativeUtil.hexStringFromByteArray(sres2);
463
464        doAnswer(new AnswerWithArguments() {
465            public SupplicantStatus answer(
466                    ArrayList<ISupplicantStaNetwork.NetworkResponseEapSimGsmAuthParams> params)
467                    throws RemoteException {
468                return mStatusSuccess;
469            }
470        }).when(mISupplicantStaNetworkMock).sendNetworkEapSimGsmAuthResponse(any(ArrayList.class));
471
472        assertFalse(mSupplicantNetwork.sendNetworkEapSimGsmAuthResponse(paramsStr));
473    }
474
475    /**
476     * Tests the parsing of invalid GSM auth response parameters (invalid number of kc/sres pairs).
477     */
478    @Test
479    public void testSendInvalidKcSresPairNumNetworkEapSimGsmAuthResponse() throws Exception {
480        final byte[] kc = new byte[]{0x45, 0x34, 0x12, 0x34, 0x45, 0x10, 0x34, 0x12};
481        final byte[] sres = new byte[]{0x12, 0x23, 0x12, 0x23};
482        // Send 1 kc/sres pair for this request.
483        String paramsStr = ":" + NativeUtil.hexStringFromByteArray(kc)
484                + ":" + NativeUtil.hexStringFromByteArray(sres);
485
486        doAnswer(new AnswerWithArguments() {
487            public SupplicantStatus answer(
488                    ArrayList<ISupplicantStaNetwork.NetworkResponseEapSimGsmAuthParams> params)
489                    throws RemoteException {
490                return mStatusSuccess;
491            }
492        }).when(mISupplicantStaNetworkMock).sendNetworkEapSimGsmAuthResponse(any(ArrayList.class));
493
494        assertFalse(mSupplicantNetwork.sendNetworkEapSimGsmAuthResponse(paramsStr));
495    }
496
497    /**
498     * Tests the parsing of UMTS auth response parameters.
499     */
500    @Test
501    public void testSendNetworkEapSimUmtsAuthResponse() throws Exception {
502        final byte[] ik = new byte[]{0x45, 0x45, 0x32, 0x34, 0x45, 0x10, 0x34, 0x12, 0x23, 0x34,
503                0x33, 0x23, 0x34, 0x10, 0x40, 0x34};
504        final byte[] ck = new byte[]{0x12, 0x10, 0x32, 0x23, 0x45, 0x10, 0x34, 0x12, 0x23, 0x34,
505                0x33, 0x23, 0x34, 0x10, 0x40, 0x34};
506        final byte[] res = new byte[]{0x12, 0x10, 0x32, 0x23, 0x45, 0x10, 0x34, 0x12, 0x23, 0x34};
507        String paramsStr = ":" + NativeUtil.hexStringFromByteArray(ik)
508                + ":" + NativeUtil.hexStringFromByteArray(ck)
509                + ":" + NativeUtil.hexStringFromByteArray(res);
510
511        doAnswer(new AnswerWithArguments() {
512            public SupplicantStatus answer(
513                    ISupplicantStaNetwork.NetworkResponseEapSimUmtsAuthParams params)
514                    throws RemoteException {
515                assertArrayEquals(ik, params.ik);
516                assertArrayEquals(ck, params.ck);
517                // Convert to arraylist before comparison.
518                ArrayList<Byte> resList = new ArrayList<>();
519                for (byte b : res) {
520                    resList.add(b);
521                }
522                assertEquals(resList, params.res);
523                return mStatusSuccess;
524            }
525        }).when(mISupplicantStaNetworkMock).sendNetworkEapSimUmtsAuthResponse(
526                any(ISupplicantStaNetwork.NetworkResponseEapSimUmtsAuthParams.class));
527
528        assertTrue(mSupplicantNetwork.sendNetworkEapSimUmtsAuthResponse(paramsStr));
529    }
530
531    /**
532     * Tests the parsing of invalid UMTS auth response parameters (invalid ik, ck lengths).
533     */
534    @Test
535    public void testSendInvalidNetworkEapSimUmtsAuthResponse() throws Exception {
536        final byte[] ik = new byte[]{0x45, 0x45, 0x32, 0x34, 0x45, 0x10, 0x34, 0x12};
537        final byte[] ck = new byte[]{0x12, 0x10, 0x32, 0x23, 0x45, 0x10, 0x34, 0x12, 0x23, 0x34,
538                0x33, 0x23, 0x34, 0x10, 0x40};
539        final byte[] res = new byte[]{0x12, 0x10, 0x32, 0x23, 0x45, 0x10, 0x34, 0x12, 0x23, 0x34};
540        String paramsStr = ":" + NativeUtil.hexStringFromByteArray(ik)
541                + ":" + NativeUtil.hexStringFromByteArray(ck)
542                + ":" + NativeUtil.hexStringFromByteArray(res);
543
544        doAnswer(new AnswerWithArguments() {
545            public SupplicantStatus answer(
546                    ISupplicantStaNetwork.NetworkResponseEapSimUmtsAuthParams params)
547                    throws RemoteException {
548                return mStatusSuccess;
549            }
550        }).when(mISupplicantStaNetworkMock).sendNetworkEapSimUmtsAuthResponse(
551                any(ISupplicantStaNetwork.NetworkResponseEapSimUmtsAuthParams.class));
552
553        assertFalse(mSupplicantNetwork.sendNetworkEapSimUmtsAuthResponse(paramsStr));
554    }
555
556    /**
557     * Tests the parsing of UMTS auts response parameters.
558     */
559    @Test
560    public void testSendNetworkEapSimUmtsAutsResponse() throws Exception {
561        final byte[] auts = new byte[]{0x45, 0x45, 0x32, 0x34, 0x45, 0x10, 0x34, 0x12, 0x23, 0x34,
562                0x33, 0x23, 0x34, 0x10};
563        String paramsStr = ":" + NativeUtil.hexStringFromByteArray(auts);
564
565        doAnswer(new AnswerWithArguments() {
566            public SupplicantStatus answer(byte[] params)
567                    throws RemoteException {
568                assertArrayEquals(auts, params);
569                return mStatusSuccess;
570            }
571        }).when(mISupplicantStaNetworkMock).sendNetworkEapSimUmtsAutsResponse(any(byte[].class));
572
573        assertTrue(mSupplicantNetwork.sendNetworkEapSimUmtsAutsResponse(paramsStr));
574    }
575
576    /**
577     * Tests the parsing of invalid UMTS auts response parameters (invalid auts length).
578     */
579    @Test
580    public void testSendInvalidNetworkEapSimUmtsAutsResponse() throws Exception {
581        final byte[] auts = new byte[]{0x45, 0x45, 0x32, 0x34, 0x45, 0x10, 0x34, 0x12, 0x23};
582        String paramsStr = ":" + NativeUtil.hexStringFromByteArray(auts);
583
584        doAnswer(new AnswerWithArguments() {
585            public SupplicantStatus answer(byte[] params)
586                    throws RemoteException {
587                assertArrayEquals(auts, params);
588                return mStatusSuccess;
589            }
590        }).when(mISupplicantStaNetworkMock).sendNetworkEapSimUmtsAutsResponse(any(byte[].class));
591
592        assertFalse(mSupplicantNetwork.sendNetworkEapSimUmtsAutsResponse(paramsStr));
593    }
594
595    /**
596     * Tests the parsing of identity string.
597     */
598    @Test
599    public void testSendNetworkEapIdentityResponse() throws Exception {
600        final String identityStr = "test@test.com";
601
602        doAnswer(new AnswerWithArguments() {
603            public SupplicantStatus answer(ArrayList<Byte> identity)
604                    throws RemoteException {
605                assertEquals(identityStr, NativeUtil.stringFromByteArrayList(identity));
606                return mStatusSuccess;
607            }
608        }).when(mISupplicantStaNetworkMock).sendNetworkEapIdentityResponse(any(ArrayList.class));
609
610        assertTrue(mSupplicantNetwork.sendNetworkEapIdentityResponse(identityStr));
611    }
612
613    /**
614     * Tests the addition of FT flags when the device supports it.
615     */
616    @Test
617    public void testAddFtPskFlags() throws Exception {
618        mResources.setBoolean(R.bool.config_wifi_fast_bss_transition_enabled, true);
619        createSupplicantStaNetwork();
620
621        WifiConfiguration config = WifiConfigurationTestUtil.createPskNetwork();
622        assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
623
624        // Check the supplicant variables to ensure that we have added the FT flags.
625        assertTrue((mSupplicantVariables.keyMgmtMask & ISupplicantStaNetwork.KeyMgmtMask.FT_PSK)
626                == ISupplicantStaNetwork.KeyMgmtMask.FT_PSK);
627
628        WifiConfiguration loadConfig = new WifiConfiguration();
629        Map<String, String> networkExtras = new HashMap<>();
630        assertTrue(mSupplicantNetwork.loadWifiConfiguration(loadConfig, networkExtras));
631        // The FT flags should be stripped out when reading it back.
632        WifiConfigurationTestUtil.assertConfigurationEqualForSupplicant(config, loadConfig);
633    }
634
635    /**
636     * Tests the addition of FT flags when the device supports it.
637     */
638    @Test
639    public void testAddFtEapFlags() throws Exception {
640        mResources.setBoolean(R.bool.config_wifi_fast_bss_transition_enabled, true);
641        createSupplicantStaNetwork();
642
643        WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
644        assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
645
646        // Check the supplicant variables to ensure that we have added the FT flags.
647        assertTrue((mSupplicantVariables.keyMgmtMask & ISupplicantStaNetwork.KeyMgmtMask.FT_EAP)
648                == ISupplicantStaNetwork.KeyMgmtMask.FT_EAP);
649
650        WifiConfiguration loadConfig = new WifiConfiguration();
651        Map<String, String> networkExtras = new HashMap<>();
652        assertTrue(mSupplicantNetwork.loadWifiConfiguration(loadConfig, networkExtras));
653        // The FT flags should be stripped out when reading it back.
654        WifiConfigurationTestUtil.assertConfigurationEqualForSupplicant(config, loadConfig);
655    }
656
657    /**
658     * Tests the retrieval of WPS NFC token.
659     */
660    @Test
661    public void testGetWpsNfcConfigurationToken() throws Exception {
662        final ArrayList<Byte> token = new ArrayList<>();
663        token.add(Byte.valueOf((byte) 0x45));
664        token.add(Byte.valueOf((byte) 0x34));
665
666        doAnswer(new AnswerWithArguments() {
667            public void answer(ISupplicantStaNetwork.getWpsNfcConfigurationTokenCallback cb)
668                    throws RemoteException {
669                cb.onValues(mStatusSuccess, token);
670            }
671        }).when(mISupplicantStaNetworkMock)
672                .getWpsNfcConfigurationToken(
673                        any(ISupplicantStaNetwork.getWpsNfcConfigurationTokenCallback.class));
674
675        assertEquals("4534", mSupplicantNetwork.getWpsNfcConfigurationToken());
676    }
677
678    /**
679     * Tests that callback registration failure triggers a failure in saving network config.
680     */
681    @Test
682    public void testSaveFailureDueToCallbackReg() throws Exception {
683        when(mISupplicantStaNetworkMock.registerCallback(any(ISupplicantStaNetworkCallback.class)))
684                .thenReturn(mStatusFailure);
685        WifiConfiguration config = WifiConfigurationTestUtil.createPskNetwork();
686        assertFalse(mSupplicantNetwork.saveWifiConfiguration(config));
687    }
688
689    /**
690     * Tests the network gsm auth callback.
691     */
692    @Test
693    public void testNetworkEapGsmAuthCallback() throws Exception {
694        WifiConfiguration config = WifiConfigurationTestUtil.createPskNetwork();
695        assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
696        assertNotNull(mISupplicantStaNetworkCallback);
697
698        // Now trigger eap gsm callback and ensure that the event is broadcast via WifiMonitor.
699        NetworkRequestEapSimGsmAuthParams params = new NetworkRequestEapSimGsmAuthParams();
700        Random random = new Random();
701        byte[] rand1 = new byte[16];
702        byte[] rand2 = new byte[16];
703        byte[] rand3 = new byte[16];
704        random.nextBytes(rand1);
705        random.nextBytes(rand2);
706        random.nextBytes(rand3);
707        params.rands.add(rand1);
708        params.rands.add(rand2);
709        params.rands.add(rand3);
710
711        String[] expectedRands = {
712                NativeUtil.hexStringFromByteArray(rand1), NativeUtil.hexStringFromByteArray(rand2),
713                NativeUtil.hexStringFromByteArray(rand3)
714        };
715
716        mISupplicantStaNetworkCallback.onNetworkEapSimGsmAuthRequest(params);
717        verify(mWifiMonitor).broadcastNetworkGsmAuthRequestEvent(
718                eq(IFACE_NAME), eq(config.networkId), eq(config.SSID), eq(expectedRands));
719    }
720
721    /**
722     * Tests the network umts auth callback.
723     */
724    @Test
725    public void testNetworkEapUmtsAuthCallback() throws Exception {
726        WifiConfiguration config = WifiConfigurationTestUtil.createPskNetwork();
727        assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
728        assertNotNull(mISupplicantStaNetworkCallback);
729
730        // Now trigger eap gsm callback and ensure that the event is broadcast via WifiMonitor.
731        NetworkRequestEapSimUmtsAuthParams params = new NetworkRequestEapSimUmtsAuthParams();
732        Random random = new Random();
733        random.nextBytes(params.autn);
734        random.nextBytes(params.rand);
735
736        String[] expectedRands = {
737                NativeUtil.hexStringFromByteArray(params.rand),
738                NativeUtil.hexStringFromByteArray(params.autn)
739        };
740
741        mISupplicantStaNetworkCallback.onNetworkEapSimUmtsAuthRequest(params);
742        verify(mWifiMonitor).broadcastNetworkUmtsAuthRequestEvent(
743                eq(IFACE_NAME), eq(config.networkId), eq(config.SSID), eq(expectedRands));
744    }
745
746    /**
747     * Tests the network identity callback.
748     */
749    @Test
750    public void testNetworkIdentityCallback() throws Exception {
751        WifiConfiguration config = WifiConfigurationTestUtil.createPskNetwork();
752        assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
753        assertNotNull(mISupplicantStaNetworkCallback);
754
755        // Now trigger identity request callback and ensure that the event is broadcast via
756        // WifiMonitor.
757        mISupplicantStaNetworkCallback.onNetworkEapIdentityRequest();
758        verify(mWifiMonitor).broadcastNetworkIdentityRequestEvent(
759                eq(IFACE_NAME), eq(config.networkId), eq(config.SSID));
760    }
761
762    private void testWifiConfigurationSaveLoad(WifiConfiguration config) {
763        assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
764        WifiConfiguration loadConfig = new WifiConfiguration();
765        Map<String, String> networkExtras = new HashMap<>();
766        assertTrue(mSupplicantNetwork.loadWifiConfiguration(loadConfig, networkExtras));
767        WifiConfigurationTestUtil.assertConfigurationEqualForSupplicant(config, loadConfig);
768        assertEquals(config.configKey(),
769                networkExtras.get(SupplicantStaNetworkHal.ID_STRING_KEY_CONFIG_KEY));
770        assertEquals(
771                config.creatorUid,
772                Integer.parseInt(networkExtras.get(
773                        SupplicantStaNetworkHal.ID_STRING_KEY_CREATOR_UID)));
774        // There is no getter for this one, so check the supplicant variable.
775        if (!TextUtils.isEmpty(config.updateIdentifier)) {
776            assertEquals(Integer.parseInt(config.updateIdentifier),
777                    mSupplicantVariables.updateIdentifier);
778        }
779        // There is no getter for this one, so check the supplicant variable.
780        String oppKeyCaching =
781                config.enterpriseConfig.getFieldValue(WifiEnterpriseConfig.OPP_KEY_CACHING);
782        if (!TextUtils.isEmpty(oppKeyCaching)) {
783            assertEquals(
784                    Integer.parseInt(oppKeyCaching) == 1 ? true : false,
785                    mSupplicantVariables.eapProactiveKeyCaching);
786        }
787    }
788
789    /**
790     * Verifies that createNetworkExtra() & parseNetworkExtra correctly writes a serialized and
791     * URL-encoded JSON object.
792     */
793    @Test
794    public void testNetworkExtra() {
795        assertEquals(NETWORK_EXTRAS_SERIALIZED,
796                SupplicantStaNetworkHal.createNetworkExtra(NETWORK_EXTRAS_VALUES));
797        assertEquals(NETWORK_EXTRAS_VALUES,
798                SupplicantStaNetworkHal.parseNetworkExtra(NETWORK_EXTRAS_SERIALIZED));
799    }
800
801    /**
802     * Verifies that fetachEapAnonymousIdentity() can get the anonymous identity from supplicant.
803     */
804    @Test
805    public void testFetchEapAnonymousIdentity() {
806        WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
807        config.enterpriseConfig.setAnonymousIdentity(ANONYMOUS_IDENTITY);
808        assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
809        assertEquals(ANONYMOUS_IDENTITY, mSupplicantNetwork.fetchEapAnonymousIdentity());
810    }
811
812    /**
813     * Sets up the HIDL interface mock with all the setters/getter values.
814     * Note: This only sets up the mock to return success on all methods.
815     */
816    private void setupISupplicantNetworkMock() throws Exception {
817        /** SSID */
818        doAnswer(new AnswerWithArguments() {
819            public SupplicantStatus answer(ArrayList<Byte> ssid) throws RemoteException {
820                mSupplicantVariables.ssid = ssid;
821                return mStatusSuccess;
822            }
823        }).when(mISupplicantStaNetworkMock).setSsid(any(ArrayList.class));
824        doAnswer(new AnswerWithArguments() {
825            public void answer(ISupplicantStaNetwork.getSsidCallback cb) throws RemoteException {
826                cb.onValues(mStatusSuccess, mSupplicantVariables.ssid);
827            }
828        }).when(mISupplicantStaNetworkMock)
829                .getSsid(any(ISupplicantStaNetwork.getSsidCallback.class));
830
831        /** Network Id */
832        doAnswer(new AnswerWithArguments() {
833            public void answer(ISupplicantNetwork.getIdCallback cb) throws RemoteException {
834                cb.onValues(mStatusSuccess, mSupplicantVariables.networkId);
835            }
836        }).when(mISupplicantStaNetworkMock).getId(any(ISupplicantNetwork.getIdCallback.class));
837
838        /** BSSID */
839        doAnswer(new AnswerWithArguments() {
840            public SupplicantStatus answer(byte[] bssid) throws RemoteException {
841                mSupplicantVariables.bssid = bssid;
842                return mStatusSuccess;
843            }
844        }).when(mISupplicantStaNetworkMock).setBssid(any(byte[].class));
845        doAnswer(new AnswerWithArguments() {
846            public void answer(ISupplicantStaNetwork.getBssidCallback cb) throws RemoteException {
847                cb.onValues(mStatusSuccess, mSupplicantVariables.bssid);
848            }
849        }).when(mISupplicantStaNetworkMock)
850                .getBssid(any(ISupplicantStaNetwork.getBssidCallback.class));
851
852        /** Scan SSID (Is Hidden Network?) */
853        doAnswer(new AnswerWithArguments() {
854            public SupplicantStatus answer(boolean enable) throws RemoteException {
855                mSupplicantVariables.scanSsid = enable;
856                return mStatusSuccess;
857            }
858        }).when(mISupplicantStaNetworkMock).setScanSsid(any(boolean.class));
859        doAnswer(new AnswerWithArguments() {
860            public void answer(ISupplicantStaNetwork.getScanSsidCallback cb)
861                    throws RemoteException {
862                cb.onValues(mStatusSuccess, mSupplicantVariables.scanSsid);
863            }
864        }).when(mISupplicantStaNetworkMock)
865                .getScanSsid(any(ISupplicantStaNetwork.getScanSsidCallback.class));
866
867        /** Require PMF*/
868        doAnswer(new AnswerWithArguments() {
869            public SupplicantStatus answer(boolean enable) throws RemoteException {
870                mSupplicantVariables.requirePmf = enable;
871                return mStatusSuccess;
872            }
873        }).when(mISupplicantStaNetworkMock).setRequirePmf(any(boolean.class));
874        doAnswer(new AnswerWithArguments() {
875            public void answer(ISupplicantStaNetwork.getRequirePmfCallback cb)
876                    throws RemoteException {
877                cb.onValues(mStatusSuccess, mSupplicantVariables.requirePmf);
878            }
879        }).when(mISupplicantStaNetworkMock)
880                .getRequirePmf(any(ISupplicantStaNetwork.getRequirePmfCallback.class));
881
882        /** PSK passphrase */
883        doAnswer(new AnswerWithArguments() {
884            public SupplicantStatus answer(String pskPassphrase) throws RemoteException {
885                mSupplicantVariables.pskPassphrase = pskPassphrase;
886                return mStatusSuccess;
887            }
888        }).when(mISupplicantStaNetworkMock).setPskPassphrase(any(String.class));
889        doAnswer(new AnswerWithArguments() {
890            public void answer(ISupplicantStaNetwork.getPskPassphraseCallback cb)
891                    throws RemoteException {
892                cb.onValues(mStatusSuccess, mSupplicantVariables.pskPassphrase);
893            }
894        }).when(mISupplicantStaNetworkMock)
895                .getPskPassphrase(any(ISupplicantStaNetwork.getPskPassphraseCallback.class));
896
897        /** PSK */
898        doAnswer(new AnswerWithArguments() {
899            public SupplicantStatus answer(byte[] psk) throws RemoteException {
900                mSupplicantVariables.psk = psk;
901                return mStatusSuccess;
902            }
903        }).when(mISupplicantStaNetworkMock).setPsk(any(byte[].class));
904        doAnswer(new AnswerWithArguments() {
905            public void answer(ISupplicantStaNetwork.getPskCallback cb)
906                    throws RemoteException {
907                cb.onValues(mStatusSuccess, mSupplicantVariables.psk);
908            }
909        }).when(mISupplicantStaNetworkMock)
910                .getPsk(any(ISupplicantStaNetwork.getPskCallback.class));
911
912        /** WEP keys **/
913        doAnswer(new AnswerWithArguments() {
914            public SupplicantStatus answer(int keyIdx, ArrayList<Byte> key) throws RemoteException {
915                mSupplicantVariables.wepKey[keyIdx] = key;
916                return mStatusSuccess;
917            }
918        }).when(mISupplicantStaNetworkMock).setWepKey(any(int.class), any(ArrayList.class));
919        doAnswer(new AnswerWithArguments() {
920            public void answer(int keyIdx, ISupplicantStaNetwork.getWepKeyCallback cb)
921                    throws RemoteException {
922                cb.onValues(mStatusSuccess, mSupplicantVariables.wepKey[keyIdx]);
923            }
924        }).when(mISupplicantStaNetworkMock)
925                .getWepKey(any(int.class), any(ISupplicantStaNetwork.getWepKeyCallback.class));
926
927        doAnswer(new AnswerWithArguments() {
928            public SupplicantStatus answer(int keyIdx) throws RemoteException {
929                mSupplicantVariables.wepTxKeyIdx = keyIdx;
930                return mStatusSuccess;
931            }
932        }).when(mISupplicantStaNetworkMock).setWepTxKeyIdx(any(int.class));
933        doAnswer(new AnswerWithArguments() {
934            public void answer(ISupplicantStaNetwork.getWepTxKeyIdxCallback cb)
935                    throws RemoteException {
936                cb.onValues(mStatusSuccess, mSupplicantVariables.wepTxKeyIdx);
937            }
938        }).when(mISupplicantStaNetworkMock)
939                .getWepTxKeyIdx(any(ISupplicantStaNetwork.getWepTxKeyIdxCallback.class));
940
941        /** allowedKeyManagement */
942        doAnswer(new AnswerWithArguments() {
943            public SupplicantStatus answer(int mask) throws RemoteException {
944                mSupplicantVariables.keyMgmtMask = mask;
945                return mStatusSuccess;
946            }
947        }).when(mISupplicantStaNetworkMock).setKeyMgmt(any(int.class));
948        doAnswer(new AnswerWithArguments() {
949            public void answer(ISupplicantStaNetwork.getKeyMgmtCallback cb) throws RemoteException {
950                cb.onValues(mStatusSuccess, mSupplicantVariables.keyMgmtMask);
951            }
952        }).when(mISupplicantStaNetworkMock)
953                .getKeyMgmt(any(ISupplicantStaNetwork.getKeyMgmtCallback.class));
954
955        /** allowedProtocols */
956        doAnswer(new AnswerWithArguments() {
957            public SupplicantStatus answer(int mask) throws RemoteException {
958                mSupplicantVariables.protoMask = mask;
959                return mStatusSuccess;
960            }
961        }).when(mISupplicantStaNetworkMock).setProto(any(int.class));
962        doAnswer(new AnswerWithArguments() {
963            public void answer(ISupplicantStaNetwork.getProtoCallback cb) throws RemoteException {
964                cb.onValues(mStatusSuccess, mSupplicantVariables.protoMask);
965            }
966        }).when(mISupplicantStaNetworkMock)
967                .getProto(any(ISupplicantStaNetwork.getProtoCallback.class));
968
969        /** allowedAuthAlgorithms */
970        doAnswer(new AnswerWithArguments() {
971            public SupplicantStatus answer(int mask) throws RemoteException {
972                mSupplicantVariables.authAlgMask = mask;
973                return mStatusSuccess;
974            }
975        }).when(mISupplicantStaNetworkMock).setAuthAlg(any(int.class));
976        doAnswer(new AnswerWithArguments() {
977            public void answer(ISupplicantStaNetwork.getAuthAlgCallback cb) throws RemoteException {
978                cb.onValues(mStatusSuccess, mSupplicantVariables.authAlgMask);
979            }
980        }).when(mISupplicantStaNetworkMock)
981                .getAuthAlg(any(ISupplicantStaNetwork.getAuthAlgCallback.class));
982
983        /** allowedGroupCiphers */
984        doAnswer(new AnswerWithArguments() {
985            public SupplicantStatus answer(int mask) throws RemoteException {
986                mSupplicantVariables.groupCipherMask = mask;
987                return mStatusSuccess;
988            }
989        }).when(mISupplicantStaNetworkMock).setGroupCipher(any(int.class));
990        doAnswer(new AnswerWithArguments() {
991            public void answer(ISupplicantStaNetwork.getGroupCipherCallback cb)
992                    throws RemoteException {
993                cb.onValues(mStatusSuccess, mSupplicantVariables.groupCipherMask);
994            }
995        }).when(mISupplicantStaNetworkMock)
996                .getGroupCipher(any(ISupplicantStaNetwork.getGroupCipherCallback.class));
997
998        /** allowedPairwiseCiphers */
999        doAnswer(new AnswerWithArguments() {
1000            public SupplicantStatus answer(int mask) throws RemoteException {
1001                mSupplicantVariables.pairwiseCipherMask = mask;
1002                return mStatusSuccess;
1003            }
1004        }).when(mISupplicantStaNetworkMock).setPairwiseCipher(any(int.class));
1005        doAnswer(new AnswerWithArguments() {
1006            public void answer(ISupplicantStaNetwork.getPairwiseCipherCallback cb)
1007                    throws RemoteException {
1008                cb.onValues(mStatusSuccess, mSupplicantVariables.pairwiseCipherMask);
1009            }
1010        }).when(mISupplicantStaNetworkMock)
1011                .getPairwiseCipher(any(ISupplicantStaNetwork.getPairwiseCipherCallback.class));
1012
1013        /** metadata: idstr */
1014        doAnswer(new AnswerWithArguments() {
1015            public SupplicantStatus answer(String idStr) throws RemoteException {
1016                mSupplicantVariables.idStr = idStr;
1017                return mStatusSuccess;
1018            }
1019        }).when(mISupplicantStaNetworkMock).setIdStr(any(String.class));
1020        doAnswer(new AnswerWithArguments() {
1021            public void answer(ISupplicantStaNetwork.getIdStrCallback cb) throws RemoteException {
1022                cb.onValues(mStatusSuccess, mSupplicantVariables.idStr);
1023            }
1024        }).when(mISupplicantStaNetworkMock)
1025                .getIdStr(any(ISupplicantStaNetwork.getIdStrCallback.class));
1026
1027        /** UpdateIdentifier */
1028        doAnswer(new AnswerWithArguments() {
1029            public SupplicantStatus answer(int identifier) throws RemoteException {
1030                mSupplicantVariables.updateIdentifier = identifier;
1031                return mStatusSuccess;
1032            }
1033        }).when(mISupplicantStaNetworkMock).setUpdateIdentifier(any(int.class));
1034
1035        /** EAP method */
1036        doAnswer(new AnswerWithArguments() {
1037            public SupplicantStatus answer(int method) throws RemoteException {
1038                mSupplicantVariables.eapMethod = method;
1039                return mStatusSuccess;
1040            }
1041        }).when(mISupplicantStaNetworkMock).setEapMethod(any(int.class));
1042        doAnswer(new AnswerWithArguments() {
1043            public void answer(ISupplicantStaNetwork.getEapMethodCallback cb)
1044                    throws RemoteException {
1045                // When not set, return failure.
1046                if (mSupplicantVariables.eapMethod == -1) {
1047                    cb.onValues(mStatusFailure, mSupplicantVariables.eapMethod);
1048                } else {
1049                    cb.onValues(mStatusSuccess, mSupplicantVariables.eapMethod);
1050                }
1051            }
1052        }).when(mISupplicantStaNetworkMock)
1053                .getEapMethod(any(ISupplicantStaNetwork.getEapMethodCallback.class));
1054
1055        /** EAP Phase 2 method */
1056        doAnswer(new AnswerWithArguments() {
1057            public SupplicantStatus answer(int method) throws RemoteException {
1058                mSupplicantVariables.eapPhase2Method = method;
1059                return mStatusSuccess;
1060            }
1061        }).when(mISupplicantStaNetworkMock).setEapPhase2Method(any(int.class));
1062        doAnswer(new AnswerWithArguments() {
1063            public void answer(ISupplicantStaNetwork.getEapPhase2MethodCallback cb)
1064                    throws RemoteException {
1065                // When not set, return failure.
1066                if (mSupplicantVariables.eapPhase2Method == -1) {
1067                    cb.onValues(mStatusFailure, mSupplicantVariables.eapPhase2Method);
1068                } else {
1069                    cb.onValues(mStatusSuccess, mSupplicantVariables.eapPhase2Method);
1070                }
1071            }
1072        }).when(mISupplicantStaNetworkMock)
1073                .getEapPhase2Method(any(ISupplicantStaNetwork.getEapPhase2MethodCallback.class));
1074
1075        /** EAP Identity */
1076        doAnswer(new AnswerWithArguments() {
1077            public SupplicantStatus answer(ArrayList<Byte> identity) throws RemoteException {
1078                mSupplicantVariables.eapIdentity = identity;
1079                return mStatusSuccess;
1080            }
1081        }).when(mISupplicantStaNetworkMock).setEapIdentity(any(ArrayList.class));
1082        doAnswer(new AnswerWithArguments() {
1083            public void answer(ISupplicantStaNetwork.getEapIdentityCallback cb)
1084                    throws RemoteException {
1085                cb.onValues(mStatusSuccess, mSupplicantVariables.eapIdentity);
1086            }
1087        }).when(mISupplicantStaNetworkMock)
1088                .getEapIdentity(any(ISupplicantStaNetwork.getEapIdentityCallback.class));
1089
1090        /** EAP Anonymous Identity */
1091        doAnswer(new AnswerWithArguments() {
1092            public SupplicantStatus answer(ArrayList<Byte> identity) throws RemoteException {
1093                mSupplicantVariables.eapAnonymousIdentity = identity;
1094                return mStatusSuccess;
1095            }
1096        }).when(mISupplicantStaNetworkMock).setEapAnonymousIdentity(any(ArrayList.class));
1097        doAnswer(new AnswerWithArguments() {
1098            public void answer(ISupplicantStaNetwork.getEapAnonymousIdentityCallback cb)
1099                    throws RemoteException {
1100                cb.onValues(mStatusSuccess, mSupplicantVariables.eapAnonymousIdentity);
1101            }
1102        }).when(mISupplicantStaNetworkMock)
1103                .getEapAnonymousIdentity(
1104                        any(ISupplicantStaNetwork.getEapAnonymousIdentityCallback.class));
1105
1106        /** EAP Password */
1107        doAnswer(new AnswerWithArguments() {
1108            public SupplicantStatus answer(ArrayList<Byte> password) throws RemoteException {
1109                mSupplicantVariables.eapPassword = password;
1110                return mStatusSuccess;
1111            }
1112        }).when(mISupplicantStaNetworkMock).setEapPassword(any(ArrayList.class));
1113        doAnswer(new AnswerWithArguments() {
1114            public void answer(ISupplicantStaNetwork.getEapPasswordCallback cb)
1115                    throws RemoteException {
1116                cb.onValues(mStatusSuccess, mSupplicantVariables.eapPassword);
1117            }
1118        }).when(mISupplicantStaNetworkMock)
1119                .getEapPassword(any(ISupplicantStaNetwork.getEapPasswordCallback.class));
1120
1121        /** EAP Client Cert */
1122        doAnswer(new AnswerWithArguments() {
1123            public SupplicantStatus answer(String cert) throws RemoteException {
1124                mSupplicantVariables.eapClientCert = cert;
1125                return mStatusSuccess;
1126            }
1127        }).when(mISupplicantStaNetworkMock).setEapClientCert(any(String.class));
1128        doAnswer(new AnswerWithArguments() {
1129            public void answer(ISupplicantStaNetwork.getEapClientCertCallback cb)
1130                    throws RemoteException {
1131                cb.onValues(mStatusSuccess, mSupplicantVariables.eapClientCert);
1132            }
1133        }).when(mISupplicantStaNetworkMock)
1134                .getEapClientCert(any(ISupplicantStaNetwork.getEapClientCertCallback.class));
1135
1136        /** EAP CA Cert */
1137        doAnswer(new AnswerWithArguments() {
1138            public SupplicantStatus answer(String cert) throws RemoteException {
1139                mSupplicantVariables.eapCACert = cert;
1140                return mStatusSuccess;
1141            }
1142        }).when(mISupplicantStaNetworkMock).setEapCACert(any(String.class));
1143        doAnswer(new AnswerWithArguments() {
1144            public void answer(ISupplicantStaNetwork.getEapCACertCallback cb)
1145                    throws RemoteException {
1146                cb.onValues(mStatusSuccess, mSupplicantVariables.eapCACert);
1147            }
1148        }).when(mISupplicantStaNetworkMock)
1149                .getEapCACert(any(ISupplicantStaNetwork.getEapCACertCallback.class));
1150
1151        /** EAP Subject Match */
1152        doAnswer(new AnswerWithArguments() {
1153            public SupplicantStatus answer(String match) throws RemoteException {
1154                mSupplicantVariables.eapSubjectMatch = match;
1155                return mStatusSuccess;
1156            }
1157        }).when(mISupplicantStaNetworkMock).setEapSubjectMatch(any(String.class));
1158        doAnswer(new AnswerWithArguments() {
1159            public void answer(ISupplicantStaNetwork.getEapSubjectMatchCallback cb)
1160                    throws RemoteException {
1161                cb.onValues(mStatusSuccess, mSupplicantVariables.eapSubjectMatch);
1162            }
1163        }).when(mISupplicantStaNetworkMock)
1164                .getEapSubjectMatch(any(ISupplicantStaNetwork.getEapSubjectMatchCallback.class));
1165
1166        /** EAP Engine */
1167        doAnswer(new AnswerWithArguments() {
1168            public SupplicantStatus answer(boolean enable) throws RemoteException {
1169                mSupplicantVariables.eapEngine = enable;
1170                return mStatusSuccess;
1171            }
1172        }).when(mISupplicantStaNetworkMock).setEapEngine(any(boolean.class));
1173        doAnswer(new AnswerWithArguments() {
1174            public void answer(ISupplicantStaNetwork.getEapEngineCallback cb)
1175                    throws RemoteException {
1176                cb.onValues(mStatusSuccess, mSupplicantVariables.eapEngine);
1177            }
1178        }).when(mISupplicantStaNetworkMock)
1179                .getEapEngine(any(ISupplicantStaNetwork.getEapEngineCallback.class));
1180
1181        /** EAP Engine ID */
1182        doAnswer(new AnswerWithArguments() {
1183            public SupplicantStatus answer(String id) throws RemoteException {
1184                mSupplicantVariables.eapEngineID = id;
1185                return mStatusSuccess;
1186            }
1187        }).when(mISupplicantStaNetworkMock).setEapEngineID(any(String.class));
1188        doAnswer(new AnswerWithArguments() {
1189            public void answer(ISupplicantStaNetwork.getEapEngineIDCallback cb)
1190                    throws RemoteException {
1191                cb.onValues(mStatusSuccess, mSupplicantVariables.eapEngineID);
1192            }
1193        }).when(mISupplicantStaNetworkMock)
1194                .getEapEngineID(any(ISupplicantStaNetwork.getEapEngineIDCallback.class));
1195
1196        /** EAP Private Key */
1197        doAnswer(new AnswerWithArguments() {
1198            public SupplicantStatus answer(String key) throws RemoteException {
1199                mSupplicantVariables.eapPrivateKeyId = key;
1200                return mStatusSuccess;
1201            }
1202        }).when(mISupplicantStaNetworkMock).setEapPrivateKeyId(any(String.class));
1203        doAnswer(new AnswerWithArguments() {
1204            public void answer(ISupplicantStaNetwork.getEapPrivateKeyIdCallback cb)
1205                    throws RemoteException {
1206                cb.onValues(mStatusSuccess, mSupplicantVariables.eapPrivateKeyId);
1207            }
1208        }).when(mISupplicantStaNetworkMock)
1209                .getEapPrivateKeyId(any(ISupplicantStaNetwork.getEapPrivateKeyIdCallback.class));
1210
1211        /** EAP Alt Subject Match */
1212        doAnswer(new AnswerWithArguments() {
1213            public SupplicantStatus answer(String match) throws RemoteException {
1214                mSupplicantVariables.eapAltSubjectMatch = match;
1215                return mStatusSuccess;
1216            }
1217        }).when(mISupplicantStaNetworkMock).setEapAltSubjectMatch(any(String.class));
1218        doAnswer(new AnswerWithArguments() {
1219            public void answer(ISupplicantStaNetwork.getEapAltSubjectMatchCallback cb)
1220                    throws RemoteException {
1221                cb.onValues(mStatusSuccess, mSupplicantVariables.eapAltSubjectMatch);
1222            }
1223        }).when(mISupplicantStaNetworkMock)
1224                .getEapAltSubjectMatch(
1225                        any(ISupplicantStaNetwork.getEapAltSubjectMatchCallback.class));
1226
1227        /** EAP Domain Suffix Match */
1228        doAnswer(new AnswerWithArguments() {
1229            public SupplicantStatus answer(String match) throws RemoteException {
1230                mSupplicantVariables.eapDomainSuffixMatch = match;
1231                return mStatusSuccess;
1232            }
1233        }).when(mISupplicantStaNetworkMock).setEapDomainSuffixMatch(any(String.class));
1234        doAnswer(new AnswerWithArguments() {
1235            public void answer(ISupplicantStaNetwork.getEapDomainSuffixMatchCallback cb)
1236                    throws RemoteException {
1237                cb.onValues(mStatusSuccess, mSupplicantVariables.eapDomainSuffixMatch);
1238            }
1239        }).when(mISupplicantStaNetworkMock)
1240                .getEapDomainSuffixMatch(
1241                        any(ISupplicantStaNetwork.getEapDomainSuffixMatchCallback.class));
1242
1243        /** EAP CA Path*/
1244        doAnswer(new AnswerWithArguments() {
1245            public SupplicantStatus answer(String path) throws RemoteException {
1246                mSupplicantVariables.eapCAPath = path;
1247                return mStatusSuccess;
1248            }
1249        }).when(mISupplicantStaNetworkMock).setEapCAPath(any(String.class));
1250        doAnswer(new AnswerWithArguments() {
1251            public void answer(ISupplicantStaNetwork.getEapCAPathCallback cb)
1252                    throws RemoteException {
1253                cb.onValues(mStatusSuccess, mSupplicantVariables.eapCAPath);
1254            }
1255        }).when(mISupplicantStaNetworkMock)
1256                .getEapCAPath(any(ISupplicantStaNetwork.getEapCAPathCallback.class));
1257
1258        /** EAP Proactive Key Caching */
1259        doAnswer(new AnswerWithArguments() {
1260            public SupplicantStatus answer(boolean enable) throws RemoteException {
1261                mSupplicantVariables.eapProactiveKeyCaching = enable;
1262                return mStatusSuccess;
1263            }
1264        }).when(mISupplicantStaNetworkMock).setProactiveKeyCaching(any(boolean.class));
1265
1266        /** Callback registeration */
1267        doAnswer(new AnswerWithArguments() {
1268            public SupplicantStatus answer(ISupplicantStaNetworkCallback cb)
1269                    throws RemoteException {
1270                mISupplicantStaNetworkCallback = cb;
1271                return mStatusSuccess;
1272            }
1273        }).when(mISupplicantStaNetworkMock)
1274                .registerCallback(any(ISupplicantStaNetworkCallback.class));
1275    }
1276
1277    private SupplicantStatus createSupplicantStatus(int code) {
1278        SupplicantStatus status = new SupplicantStatus();
1279        status.code = code;
1280        return status;
1281    }
1282
1283    /**
1284     * Need this for tests which wants to manipulate context before creating the instance.
1285     */
1286    private void createSupplicantStaNetwork() {
1287        mSupplicantNetwork =
1288                new SupplicantStaNetworkHal(
1289                        mISupplicantStaNetworkMock, IFACE_NAME, mContext, mWifiMonitor);
1290    }
1291
1292    // Private class to to store/inspect values set via the HIDL mock.
1293    private class SupplicantNetworkVariables {
1294        public ArrayList<Byte> ssid;
1295        public int networkId;
1296        public byte[/* 6 */] bssid;
1297        public int keyMgmtMask;
1298        public int protoMask;
1299        public int authAlgMask;
1300        public int groupCipherMask;
1301        public int pairwiseCipherMask;
1302        public boolean scanSsid;
1303        public boolean requirePmf;
1304        public String idStr;
1305        public int updateIdentifier;
1306        public String pskPassphrase;
1307        public byte[] psk;
1308        public ArrayList<Byte>[] wepKey = new ArrayList[4];
1309        public int wepTxKeyIdx;
1310        public int eapMethod = -1;
1311        public int eapPhase2Method = -1;
1312        public ArrayList<Byte> eapIdentity;
1313        public ArrayList<Byte> eapAnonymousIdentity;
1314        public ArrayList<Byte> eapPassword;
1315        public String eapCACert;
1316        public String eapCAPath;
1317        public String eapClientCert;
1318        public String eapPrivateKeyId;
1319        public String eapSubjectMatch;
1320        public String eapAltSubjectMatch;
1321        public boolean eapEngine;
1322        public String eapEngineID;
1323        public String eapDomainSuffixMatch;
1324        public boolean eapProactiveKeyCaching;
1325    }
1326}
1327