• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 package com.android.server.wifi;
17 
18 import static android.net.wifi.WifiManager.WIFI_FEATURE_DPP;
19 import static android.net.wifi.WifiManager.WIFI_FEATURE_DPP_ENROLLEE_RESPONDER;
20 import static android.net.wifi.WifiManager.WIFI_FEATURE_FILS_SHA256;
21 import static android.net.wifi.WifiManager.WIFI_FEATURE_FILS_SHA384;
22 import static android.net.wifi.WifiManager.WIFI_FEATURE_MBO;
23 import static android.net.wifi.WifiManager.WIFI_FEATURE_OCE;
24 import static android.net.wifi.WifiManager.WIFI_FEATURE_OWE;
25 import static android.net.wifi.WifiManager.WIFI_FEATURE_WAPI;
26 import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SAE;
27 import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SUITE_B;
28 
29 import static org.junit.Assert.assertArrayEquals;
30 import static org.junit.Assert.assertEquals;
31 import static org.junit.Assert.assertFalse;
32 import static org.junit.Assert.assertNotNull;
33 import static org.junit.Assert.assertNull;
34 import static org.junit.Assert.assertTrue;
35 import static org.mockito.Matchers.any;
36 import static org.mockito.Matchers.anyBoolean;
37 import static org.mockito.Matchers.anyInt;
38 import static org.mockito.Matchers.anyLong;
39 import static org.mockito.Matchers.anyShort;
40 import static org.mockito.Matchers.anyString;
41 import static org.mockito.Matchers.eq;
42 import static org.mockito.Mockito.doAnswer;
43 import static org.mockito.Mockito.doThrow;
44 import static org.mockito.Mockito.inOrder;
45 import static org.mockito.Mockito.mock;
46 import static org.mockito.Mockito.never;
47 import static org.mockito.Mockito.reset;
48 import static org.mockito.Mockito.spy;
49 import static org.mockito.Mockito.times;
50 import static org.mockito.Mockito.verify;
51 import static org.mockito.Mockito.verifyNoMoreInteractions;
52 import static org.mockito.Mockito.when;
53 
54 import android.annotation.NonNull;
55 import android.app.test.MockAnswerUtil;
56 import android.app.test.MockAnswerUtil.AnswerWithArguments;
57 import android.content.Context;
58 import android.hardware.wifi.V1_0.WifiChannelWidthInMhz;
59 import android.hardware.wifi.supplicant.DebugLevel;
60 import android.hardware.wifi.supplicant.V1_0.ISupplicant;
61 import android.hardware.wifi.supplicant.V1_0.ISupplicantIface;
62 import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIface;
63 import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback;
64 import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback.BssidChangeReason;
65 import android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetwork;
66 import android.hardware.wifi.supplicant.V1_0.IfaceType;
67 import android.hardware.wifi.supplicant.V1_0.SupplicantStatus;
68 import android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode;
69 import android.hardware.wifi.supplicant.V1_0.WpsConfigMethods;
70 import android.hardware.wifi.supplicant.V1_3.ISupplicantStaIfaceCallback.BssTmData;
71 import android.hardware.wifi.supplicant.V1_3.WifiTechnology;
72 import android.hardware.wifi.supplicant.V1_4.ConnectionCapabilities;
73 import android.hardware.wifi.supplicant.V1_4.ISupplicantStaIfaceCallback.AssociationRejectionData;
74 import android.hardware.wifi.supplicant.V1_4.LegacyMode;
75 import android.hidl.manager.V1_0.IServiceManager;
76 import android.hidl.manager.V1_0.IServiceNotification;
77 import android.net.MacAddress;
78 import android.net.wifi.ScanResult;
79 import android.net.wifi.SecurityParams;
80 import android.net.wifi.SupplicantState;
81 import android.net.wifi.WifiConfiguration;
82 import android.net.wifi.WifiManager;
83 import android.net.wifi.WifiSsid;
84 import android.os.Handler;
85 import android.os.IHwBinder;
86 import android.os.RemoteException;
87 import android.os.test.TestLooper;
88 import android.text.TextUtils;
89 
90 import androidx.test.filters.SmallTest;
91 
92 import com.android.server.wifi.MboOceController.BtmFrameData;
93 import com.android.server.wifi.hotspot2.AnqpEvent;
94 import com.android.server.wifi.hotspot2.IconEvent;
95 import com.android.server.wifi.hotspot2.WnmData;
96 import com.android.server.wifi.util.NativeUtil;
97 
98 import org.junit.Before;
99 import org.junit.Test;
100 import org.mockito.ArgumentCaptor;
101 import org.mockito.InOrder;
102 import org.mockito.Mock;
103 import org.mockito.MockitoAnnotations;
104 import org.mockito.stubbing.Answer;
105 
106 import java.nio.ByteBuffer;
107 import java.nio.ByteOrder;
108 import java.util.ArrayList;
109 import java.util.Arrays;
110 import java.util.HashMap;
111 import java.util.List;
112 import java.util.Map;
113 import java.util.Random;
114 
115 /**
116  * Unit tests for SupplicantStaIfaceHalHidlImpl
117  */
118 @SmallTest
119 public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
120     private static final Map<Integer, String> NETWORK_ID_TO_SSID = Map.of(
121             1, "\"ssid1\"",
122             2, "\"ssid2\"",
123             3, "\"ssid3\"");
124     private static final int SUPPLICANT_NETWORK_ID = 2;
125     private static final String SUPPLICANT_SSID = NETWORK_ID_TO_SSID.get(SUPPLICANT_NETWORK_ID);
126     private static final WifiSsid TRANSLATED_SUPPLICANT_SSID =
127             WifiSsid.fromString("\"translated ssid\"");
128     private static final int ROAM_NETWORK_ID = 4;
129     private static final String BSSID = "fa:45:23:23:12:12";
130     private static final String WLAN0_IFACE_NAME = "wlan0";
131     private static final String WLAN1_IFACE_NAME = "wlan1";
132     private static final String P2P_IFACE_NAME = "p2p0";
133     private static final String ICON_FILE_NAME  = "blahblah";
134     private static final int ICON_FILE_SIZE = 72;
135     private static final String HS20_URL = "http://blahblah";
136     private static final long PMK_CACHE_EXPIRATION_IN_SEC = 1024;
137     private static final byte[] CONNECTED_MAC_ADDRESS_BYTES =
138             {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
139 
140     private @Mock IServiceManager mServiceManagerMock;
141     private @Mock ISupplicant mISupplicantMock;
142     private @Mock android.hardware.wifi.supplicant.V1_1.ISupplicant mISupplicantMockV11;
143     private @Mock android.hardware.wifi.supplicant.V1_2.ISupplicant mISupplicantMockV12;
144     private @Mock android.hardware.wifi.supplicant.V1_3.ISupplicant mISupplicantMockV13;
145     private @Mock android.hardware.wifi.supplicant.V1_3.ISupplicant mISupplicantMockV14;
146     private @Mock ISupplicantIface mISupplicantIfaceMock;
147     private @Mock ISupplicantStaIface mISupplicantStaIfaceMock;
148     private @Mock android.hardware.wifi.supplicant.V1_1.ISupplicantStaIface
149             mISupplicantStaIfaceMockV11;
150     private @Mock android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface
151             mISupplicantStaIfaceMockV12;
152     private @Mock android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
153             mISupplicantStaIfaceMockV13;
154     private @Mock android.hardware.wifi.supplicant.V1_4.ISupplicantStaIface
155             mISupplicantStaIfaceMockV14;
156     private @Mock Context mContext;
157     private @Mock WifiMonitor mWifiMonitor;
158     private @Mock FrameworkFacade mFrameworkFacade;
159     private @Mock SupplicantStaNetworkHalHidlImpl mSupplicantStaNetworkMock;
160     private @Mock WifiNative.SupplicantDeathEventHandler mSupplicantHalDeathHandler;
161     private @Mock Clock mClock;
162     private @Mock WifiMetrics mWifiMetrics;
163     private @Mock WifiGlobals mWifiGlobals;
164     private @Mock SsidTranslator mSsidTranslator;
165     private @Mock PmkCacheManager mPmkCacheManager;
166 
167     SupplicantStatus mStatusSuccess;
168     SupplicantStatus mStatusFailure;
169     android.hardware.wifi.supplicant.V1_4.SupplicantStatus mStatusSuccessV14;
170     android.hardware.wifi.supplicant.V1_4.SupplicantStatus mStatusFailureV14;
171     ISupplicant.IfaceInfo mStaIface0;
172     ISupplicant.IfaceInfo mStaIface1;
173     ISupplicant.IfaceInfo mP2pIface;
174     ArrayList<ISupplicant.IfaceInfo> mIfaceInfoList;
175     ISupplicantStaIfaceCallback mISupplicantStaIfaceCallback;
176     android.hardware.wifi.supplicant.V1_1.ISupplicantStaIfaceCallback
177             mISupplicantStaIfaceCallbackV11;
178     android.hardware.wifi.supplicant.V1_2.ISupplicantStaIfaceCallback
179             mISupplicantStaIfaceCallbackV12;
180     android.hardware.wifi.supplicant.V1_3.ISupplicantStaIfaceCallback
181             mISupplicantStaIfaceCallbackV13 = null;
182     android.hardware.wifi.supplicant.V1_4.ISupplicantStaIfaceCallback
183             mISupplicantStaIfaceCallbackV14 = null;
184 
185     private TestLooper mLooper = new TestLooper();
186     private Handler mHandler = null;
187     private SupplicantStaIfaceHalSpy mDut;
188     private ArgumentCaptor<IHwBinder.DeathRecipient> mServiceManagerDeathCaptor =
189             ArgumentCaptor.forClass(IHwBinder.DeathRecipient.class);
190     private ArgumentCaptor<IHwBinder.DeathRecipient> mSupplicantDeathCaptor =
191             ArgumentCaptor.forClass(IHwBinder.DeathRecipient.class);
192     private ArgumentCaptor<IHwBinder.DeathRecipient> mSupplicantStaIfaceDeathCaptor =
193             ArgumentCaptor.forClass(IHwBinder.DeathRecipient.class);
194     private ArgumentCaptor<IServiceNotification.Stub> mServiceNotificationCaptor =
195             ArgumentCaptor.forClass(IServiceNotification.Stub.class);
196     private ArgumentCaptor<Long> mDeathRecipientCookieCaptor = ArgumentCaptor.forClass(Long.class);
197     private InOrder mInOrder;
198 
199     private class SupplicantStaIfaceHalSpy extends SupplicantStaIfaceHalHidlImpl {
200         SupplicantStaNetworkHalHidlImpl mStaNetwork;
201 
SupplicantStaIfaceHalSpy()202         SupplicantStaIfaceHalSpy() {
203             super(mContext, mWifiMonitor, mFrameworkFacade,
204                     mHandler, mClock, mWifiMetrics, mWifiGlobals, mSsidTranslator);
205             mStaNetwork = mSupplicantStaNetworkMock;
206         }
207 
208         @Override
getServiceManagerMockable()209         protected IServiceManager getServiceManagerMockable() throws RemoteException {
210             return mServiceManagerMock;
211         }
212 
213         @Override
getSupplicantMockable()214         protected ISupplicant getSupplicantMockable() throws RemoteException {
215             return mISupplicantMock;
216         }
217 
218         @Override
getSupplicantMockableV1_1()219         protected android.hardware.wifi.supplicant.V1_1.ISupplicant getSupplicantMockableV1_1()
220                 throws RemoteException {
221             return mISupplicantMockV11;
222         }
223 
224         @Override
getStaIfaceMockable(ISupplicantIface iface)225         protected ISupplicantStaIface getStaIfaceMockable(ISupplicantIface iface) {
226             return mISupplicantStaIfaceMock;
227         }
228 
229         @Override
230         protected android.hardware.wifi.supplicant.V1_1.ISupplicantStaIface
getStaIfaceMockableV1_1(ISupplicantIface iface)231                 getStaIfaceMockableV1_1(ISupplicantIface iface) {
232             return mISupplicantStaIfaceMockV11;
233         }
234 
235         @Override
236         protected android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface
getStaIfaceMockableV1_2(ISupplicantIface iface)237                 getStaIfaceMockableV1_2(ISupplicantIface iface) {
238             return mISupplicantStaIfaceMockV12;
239         }
240 
241         @Override
242         protected android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
getStaIfaceMockableV1_3(ISupplicantIface iface)243                 getStaIfaceMockableV1_3(ISupplicantIface iface) {
244             return (mISupplicantMockV13 != null)
245                     ? mISupplicantStaIfaceMockV13
246                     : null;
247         }
248 
249         @Override
250         protected android.hardware.wifi.supplicant.V1_4.ISupplicantStaIface
getStaIfaceMockableV1_4(ISupplicantIface iface)251                 getStaIfaceMockableV1_4(ISupplicantIface iface) {
252             return (mISupplicantMockV14 != null)
253                     ? mISupplicantStaIfaceMockV14
254                     : null;
255         }
256 
257         @Override
getStaNetworkMockable( @onNull String ifaceName, ISupplicantStaNetwork iSupplicantStaNetwork)258         protected SupplicantStaNetworkHalHidlImpl getStaNetworkMockable(
259                 @NonNull String ifaceName,
260                 ISupplicantStaNetwork iSupplicantStaNetwork) {
261             return mStaNetwork;
262         }
263 
setStaNetworkMockable(SupplicantStaNetworkHalHidlImpl network)264         private void setStaNetworkMockable(SupplicantStaNetworkHalHidlImpl network) {
265             mStaNetwork = network;
266         }
267     }
268 
269     @Before
setUp()270     public void setUp() throws Exception {
271         MockitoAnnotations.initMocks(this);
272         mStatusSuccess = createSupplicantStatus(SupplicantStatusCode.SUCCESS);
273         mStatusFailure = createSupplicantStatus(SupplicantStatusCode.FAILURE_UNKNOWN);
274         mStatusSuccessV14 = createSupplicantStatusV1_4(
275                 android.hardware.wifi.supplicant.V1_4.SupplicantStatusCode.SUCCESS);
276         mStatusFailureV14 = createSupplicantStatusV1_4(
277                 android.hardware.wifi.supplicant.V1_4.SupplicantStatusCode.FAILURE_UNKNOWN);
278         mStaIface0 = createIfaceInfo(IfaceType.STA, WLAN0_IFACE_NAME);
279         mStaIface1 = createIfaceInfo(IfaceType.STA, WLAN1_IFACE_NAME);
280         mP2pIface = createIfaceInfo(IfaceType.P2P, P2P_IFACE_NAME);
281 
282         mIfaceInfoList = new ArrayList<>();
283         mIfaceInfoList.add(mStaIface0);
284         mIfaceInfoList.add(mStaIface1);
285         mIfaceInfoList.add(mP2pIface);
286         when(mServiceManagerMock.getTransport(anyString(), anyString()))
287                 .thenReturn(IServiceManager.Transport.EMPTY);
288         when(mServiceManagerMock.linkToDeath(any(IHwBinder.DeathRecipient.class),
289                 anyLong())).thenReturn(true);
290         when(mServiceManagerMock.registerForNotifications(anyString(), anyString(),
291                 any(IServiceNotification.Stub.class))).thenReturn(true);
292         when(mISupplicantMock.linkToDeath(any(IHwBinder.DeathRecipient.class),
293                 anyLong())).thenReturn(true);
294         when(mISupplicantMockV11.linkToDeath(any(IHwBinder.DeathRecipient.class),
295                 anyLong())).thenReturn(true);
296         doAnswer(new AnswerWithArguments() {
297             public void answer(ISupplicantStaIface.getMacAddressCallback cb) {
298                 cb.onValues(mStatusSuccess, CONNECTED_MAC_ADDRESS_BYTES);
299             }
300         })
301         .when(mISupplicantStaIfaceMock)
302                 .getMacAddress(any(ISupplicantStaIface.getMacAddressCallback.class));
303         when(mFrameworkFacade.startSupplicant()).thenReturn(true);
304         mHandler = spy(new Handler(mLooper.getLooper()));
305         when(mSsidTranslator.getTranslatedSsidForStaIface(any(), anyString()))
306                 .thenReturn(TRANSLATED_SUPPLICANT_SSID);
307         when(mSsidTranslator.getOriginalSsid(any())).thenAnswer((Answer<WifiSsid>) invocation ->
308                 WifiSsid.fromString(((WifiConfiguration) invocation.getArgument(0)).SSID));
309         when(mSsidTranslator.getAllPossibleOriginalSsids(TRANSLATED_SUPPLICANT_SSID)).thenAnswer(
310                 (Answer<List<WifiSsid>>) invocation -> {
311                     List<WifiSsid> ssids = new ArrayList<>();
312                     ssids.add(TRANSLATED_SUPPLICANT_SSID);
313                     return ssids;
314                 });
315         mDut = new SupplicantStaIfaceHalSpy();
316     }
317 
318     /**
319      * Sunny day scenario for SupplicantStaIfaceHalHidlImpl initialization
320      * Asserts successful initialization
321      */
322     @Test
testInitialize_success()323     public void testInitialize_success() throws Exception {
324         executeAndValidateInitializationSequence(false, false, false, false);
325     }
326 
327     /**
328      * Tests the initialization flow, with a RemoteException occurring when 'getInterface' is called
329      * Ensures initialization fails.
330      */
331     @Test
testInitialize_remoteExceptionFailure()332     public void testInitialize_remoteExceptionFailure() throws Exception {
333         executeAndValidateInitializationSequence(true, false, false, false);
334     }
335 
336     /**
337      * Tests the initialization flow, with listInterfaces returning 0 interfaces.
338      * Ensures failure
339      */
340     @Test
testInitialize_zeroInterfacesFailure()341     public void testInitialize_zeroInterfacesFailure() throws Exception {
342         executeAndValidateInitializationSequence(false, true, false, false);
343     }
344 
345     /**
346      * Tests the initialization flow, with a null interface being returned by getInterface.
347      * Ensures initialization fails.
348      */
349     @Test
testInitialize_nullInterfaceFailure()350     public void testInitialize_nullInterfaceFailure() throws Exception {
351         executeAndValidateInitializationSequence(false, false, true, false);
352     }
353 
354     /**
355      * Tests the initialization flow, with a callback registration failure.
356      * Ensures initialization fails.
357      */
358     @Test
testInitialize_callbackRegistrationFailure()359     public void testInitialize_callbackRegistrationFailure() throws Exception {
360         executeAndValidateInitializationSequence(false, false, false, true);
361     }
362 
363     /**
364      * Sunny day scenario for SupplicantStaIfaceHal initialization
365      * Asserts successful initialization
366      */
367     @Test
testInitialize_successV1_1()368     public void testInitialize_successV1_1() throws Exception {
369         setupMocksForHalV1_1();
370         executeAndValidateInitializationSequenceV1_1(false, false);
371     }
372 
373     /**
374      * Sunny day scenario for SupplicantStaIfaceHal initialization
375      * Asserts successful initialization
376      */
377     @Test
testInitialize_successV1_2()378     public void testInitialize_successV1_2() throws Exception {
379         setupMocksForHalV1_2();
380         executeAndValidateInitializationSequenceV1_2();
381     }
382 
383     /**
384      * Sunny day scenario for SupplicantStaIfaceHal initialization
385      * Asserts successful initialization
386      */
387     @Test
testInitialize_successV1_3()388     public void testInitialize_successV1_3() throws Exception {
389         setupMocksForHalV1_3();
390         executeAndValidateInitializationSequenceV1_3();
391     }
392 
393     /**
394      * Sunny day scenario for SupplicantStaIfaceHal initialization
395      * Asserts successful initialization
396      */
397     @Test
testInitialize_successV1_4()398     public void testInitialize_successV1_4() throws Exception {
399         setupMocksForHalV1_4();
400         executeAndValidateInitializationSequenceV1_4();
401     }
402 
403     /**
404      * Tests the initialization flow, with a RemoteException occurring when 'getInterface' is called
405      * Ensures initialization fails.
406      */
407     @Test
testInitialize_remoteExceptionFailureV1_1()408     public void testInitialize_remoteExceptionFailureV1_1() throws Exception {
409         setupMocksForHalV1_1();
410         executeAndValidateInitializationSequenceV1_1(true, false);
411     }
412 
413     /**
414      * Tests the initialization flow, with a null interface being returned by getInterface.
415      * Ensures initialization fails.
416      */
417     @Test
testInitialize_nullInterfaceFailureV1_1()418     public void testInitialize_nullInterfaceFailureV1_1() throws Exception {
419         setupMocksForHalV1_1();
420         executeAndValidateInitializationSequenceV1_1(false, true);
421     }
422 
423     /**
424      * Ensures that we do not allow operations on an interface until it's setup.
425      */
426     @Test
testEnsureOperationFailsUntilSetupInterfaces()427     public void testEnsureOperationFailsUntilSetupInterfaces() throws Exception {
428         executeAndValidateInitializationSequence(false, false, false, false);
429 
430         // Ensure that the cancel wps operation is failed because wlan1 interface is not yet setup.
431         assertFalse(mDut.cancelWps(WLAN1_IFACE_NAME));
432         verify(mISupplicantStaIfaceMock, never()).cancelWps();
433 
434         // Now setup the wlan1 interface and Ensure that the cancel wps operation is successful.
435         assertTrue(mDut.setupIface(WLAN1_IFACE_NAME));
436         when(mISupplicantStaIfaceMock.cancelWps()).thenReturn(mStatusSuccess);
437         assertTrue(mDut.cancelWps(WLAN1_IFACE_NAME));
438         verify(mISupplicantStaIfaceMock).cancelWps();
439     }
440 
441     /**
442      * Ensures that reject addition of an existing iface.
443      */
444     @Test
testDuplicateSetupIfaceV1_1_Fails()445     public void testDuplicateSetupIfaceV1_1_Fails() throws Exception {
446         setupMocksForHalV1_1();
447         executeAndValidateInitializationSequenceV1_1(false, false);
448 
449         // Trying setting up the wlan0 interface again & ensure it fails.
450         assertFalse(mDut.setupIface(WLAN0_IFACE_NAME));
451         verify(mISupplicantMockV11)
452                 .setDebugParams(eq(DebugLevel.INFO), eq(false), eq(false));
453         verifyNoMoreInteractions(mISupplicantMockV11);
454     }
455 
456     /**
457      * Sunny day scenario for SupplicantStaIfaceHal interface teardown.
458      */
459     @Test
testTeardownInterface()460     public void testTeardownInterface() throws Exception {
461         testInitialize_success();
462         assertTrue(mDut.teardownIface(WLAN0_IFACE_NAME));
463 
464         // Ensure that the cancel wps operation is failed because there are no interfaces setup.
465         assertFalse(mDut.cancelWps(WLAN0_IFACE_NAME));
466         verify(mISupplicantStaIfaceMock, never()).cancelWps();
467     }
468 
469     /**
470      * Sunny day scenario for SupplicantStaIfaceHal interface teardown.
471      */
472     @Test
testTeardownInterfaceV1_1()473     public void testTeardownInterfaceV1_1() throws Exception {
474         testInitialize_successV1_1();
475 
476         when(mISupplicantMockV11.removeInterface(any())).thenReturn(mStatusSuccess);
477         assertTrue(mDut.teardownIface(WLAN0_IFACE_NAME));
478         verify(mISupplicantMockV11).removeInterface(any());
479 
480         // Ensure that the cancel wps operation is failed because there are no interfaces setup.
481         assertFalse(mDut.cancelWps(WLAN0_IFACE_NAME));
482         verify(mISupplicantStaIfaceMock, never()).cancelWps();
483     }
484 
485     /**
486      * Ensures that we reject removal of an invalid iface.
487      */
488     @Test
testInvalidTeardownInterfaceV1_1_Fails()489     public void testInvalidTeardownInterfaceV1_1_Fails() throws Exception {
490         assertFalse(mDut.teardownIface(WLAN0_IFACE_NAME));
491         verifyNoMoreInteractions(mISupplicantMock);
492     }
493 
494     /**
495      * Sunny day scenario for SupplicantStaIfaceHal initialization
496      * Asserts successful initialization of second interface
497      */
498     @Test
testSetupTwoInterfaces()499     public void testSetupTwoInterfaces() throws Exception {
500         executeAndValidateInitializationSequence(false, false, false, false);
501         assertTrue(mDut.setupIface(WLAN1_IFACE_NAME));
502     }
503 
504     /**
505      * Sunny day scenario for SupplicantStaIfaceHal interface teardown.
506      * Asserts successful initialization of second interface
507      */
508     @Test
testTeardownTwoInterfaces()509     public void testTeardownTwoInterfaces() throws Exception {
510         testSetupTwoInterfaces();
511         assertTrue(mDut.teardownIface(WLAN0_IFACE_NAME));
512         assertTrue(mDut.teardownIface(WLAN1_IFACE_NAME));
513 
514         // Ensure that the cancel wps operation is failed because there are no interfaces setup.
515         assertFalse(mDut.cancelWps(WLAN0_IFACE_NAME));
516         verify(mISupplicantStaIfaceMock, never()).cancelWps();
517     }
518 
519     /**
520      * Tests connection to a specified network with empty existing network.
521      */
522     @Test
testConnectWithEmptyExistingNetwork()523     public void testConnectWithEmptyExistingNetwork() throws Exception {
524         executeAndValidateInitializationSequence();
525         executeAndValidateConnectSequence(0, false, TRANSLATED_SUPPLICANT_SSID.toString());
526     }
527 
528     @Test
testConnectToNetworkWithDifferentConfigReplacesNetworkInSupplicant()529     public void testConnectToNetworkWithDifferentConfigReplacesNetworkInSupplicant()
530             throws Exception {
531         executeAndValidateInitializationSequence();
532         WifiConfiguration config = executeAndValidateConnectSequence(
533                 SUPPLICANT_NETWORK_ID, false, TRANSLATED_SUPPLICANT_SSID.toString());
534         // Reset mocks for mISupplicantStaIfaceMock because we finished the first connection.
535         reset(mISupplicantStaIfaceMock);
536         setupMocksForConnectSequence(true /*haveExistingNetwork*/);
537         // Make this network different by changing SSID.
538         config.SSID = "\"ADifferentSSID\"";
539         assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, config));
540         verify(mISupplicantStaIfaceMock).removeNetwork(SUPPLICANT_NETWORK_ID);
541         verify(mISupplicantStaIfaceMock)
542                 .addNetwork(any(ISupplicantStaIface.addNetworkCallback.class));
543     }
544 
545     @Test
connectToNetworkWithSameNetworkDoesNotRemoveNetworkFromSupplicant()546     public void connectToNetworkWithSameNetworkDoesNotRemoveNetworkFromSupplicant()
547             throws Exception {
548         executeAndValidateInitializationSequence();
549         WifiConfiguration config = executeAndValidateConnectSequence(SUPPLICANT_NETWORK_ID, false,
550                 TRANSLATED_SUPPLICANT_SSID.toString());
551         // Reset mocks for mISupplicantStaIfaceMock because we finished the first connection.
552         reset(mISupplicantStaIfaceMock);
553         setupMocksForConnectSequence(true /*haveExistingNetwork*/);
554         assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, config));
555         verify(mISupplicantStaIfaceMock, never()).removeNetwork(anyInt());
556         verify(mISupplicantStaIfaceMock, never())
557                 .addNetwork(any(ISupplicantStaIface.addNetworkCallback.class));
558     }
559 
560     @Test
connectToNetworkWithSameNetworkButDifferentBssidUpdatesNetworkFromSupplicant()561     public void connectToNetworkWithSameNetworkButDifferentBssidUpdatesNetworkFromSupplicant()
562             throws Exception {
563         executeAndValidateInitializationSequence();
564         WifiConfiguration config = executeAndValidateConnectSequence(SUPPLICANT_NETWORK_ID, false,
565                 TRANSLATED_SUPPLICANT_SSID.toString());
566         String testBssid = "11:22:33:44:55:66";
567         when(mSupplicantStaNetworkMock.setBssid(eq(testBssid))).thenReturn(true);
568 
569         // Reset mocks for mISupplicantStaIfaceMock because we finished the first connection.
570         reset(mISupplicantStaIfaceMock);
571         setupMocksForConnectSequence(true /*haveExistingNetwork*/);
572         // Change the BSSID and connect to the same network.
573         assertFalse(TextUtils.equals(
574                 testBssid, config.getNetworkSelectionStatus().getNetworkSelectionBSSID()));
575         config.getNetworkSelectionStatus().setNetworkSelectionBSSID(testBssid);
576         assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, config));
577         verify(mSupplicantStaNetworkMock).setBssid(eq(testBssid));
578         verify(mISupplicantStaIfaceMock, never()).removeNetwork(anyInt());
579         verify(mISupplicantStaIfaceMock, never())
580                 .addNetwork(any(ISupplicantStaIface.addNetworkCallback.class));
581     }
582 
583     /**
584      * Tests connection to a specified network failure due to network add.
585      */
586     @Test
testConnectFailureDueToNetworkAddFailure()587     public void testConnectFailureDueToNetworkAddFailure() throws Exception {
588         executeAndValidateInitializationSequence();
589         setupMocksForConnectSequence(false);
590         doAnswer(new MockAnswerUtil.AnswerWithArguments() {
591             public void answer(ISupplicantStaIface.addNetworkCallback cb) throws RemoteException {
592                 cb.onValues(mStatusFailure, mock(ISupplicantStaNetwork.class));
593                 return;
594             }
595         }).when(mISupplicantStaIfaceMock).addNetwork(
596                 any(ISupplicantStaIface.addNetworkCallback.class));
597 
598         assertFalse(mDut.connectToNetwork(WLAN0_IFACE_NAME, createTestWifiConfiguration()));
599     }
600 
601     /**
602      * Tests connection to a specified network failure due to network save.
603      */
604     @Test
testConnectFailureDueToNetworkSaveFailure()605     public void testConnectFailureDueToNetworkSaveFailure() throws Exception {
606         executeAndValidateInitializationSequence();
607         setupMocksForConnectSequence(true);
608 
609         when(mSupplicantStaNetworkMock.saveWifiConfiguration(any(WifiConfiguration.class)))
610                 .thenReturn(false);
611 
612         assertFalse(mDut.connectToNetwork(WLAN0_IFACE_NAME, createTestWifiConfiguration()));
613         // We should have removed the existing network once before connection and once more
614         // on failure to save network configuration.
615         verify(mISupplicantStaIfaceMock, times(2)).removeNetwork(anyInt());
616     }
617 
618     /**
619      * Tests connection to a specified network failure due to exception in network save.
620      */
621     @Test
testConnectFailureDueToNetworkSaveException()622     public void testConnectFailureDueToNetworkSaveException() throws Exception {
623         executeAndValidateInitializationSequence();
624         setupMocksForConnectSequence(true);
625 
626         doThrow(new IllegalArgumentException("Some error!!!"))
627                 .when(mSupplicantStaNetworkMock).saveWifiConfiguration(
628                         any(WifiConfiguration.class));
629 
630         assertFalse(mDut.connectToNetwork(WLAN0_IFACE_NAME, createTestWifiConfiguration()));
631         // We should have removed the existing network once before connection and once more
632         // on failure to save network configuration.
633         verify(mISupplicantStaIfaceMock, times(2)).removeNetwork(anyInt());
634     }
635 
636     /**
637      * Tests connection to a specified network failure due to network select.
638      */
639     @Test
testConnectFailureDueToNetworkSelectFailure()640     public void testConnectFailureDueToNetworkSelectFailure() throws Exception {
641         executeAndValidateInitializationSequence();
642         setupMocksForConnectSequence(false);
643 
644         when(mSupplicantStaNetworkMock.select()).thenReturn(false);
645 
646         assertFalse(mDut.connectToNetwork(WLAN0_IFACE_NAME, createTestWifiConfiguration()));
647     }
648 
649     /**
650      * Tests roaming to the same network as the currently connected one.
651      */
652     @Test
testRoamToSameNetwork()653     public void testRoamToSameNetwork() throws Exception {
654         executeAndValidateInitializationSequence();
655         executeAndValidateRoamSequence(true, false);
656         assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, createTestWifiConfiguration()));
657     }
658 
659     /**
660      * Tests roaming to a different network.
661      */
662     @Test
testRoamToDifferentNetwork()663     public void testRoamToDifferentNetwork() throws Exception {
664         executeAndValidateInitializationSequence();
665         executeAndValidateRoamSequence(false, false);
666     }
667 
668     /**
669      * Tests framework roaming to a linked network.
670      */
671     @Test
testRoamToLinkedNetwork()672     public void testRoamToLinkedNetwork() throws Exception {
673         executeAndValidateInitializationSequence();
674         executeAndValidateRoamSequence(false, true);
675     }
676 
677     /**
678      * Tests updating linked networks for a network id
679      */
680     @Test
testUpdateLinkedNetworks()681     public void testUpdateLinkedNetworks() throws Exception {
682         executeAndValidateInitializationSequence();
683 
684         final int frameworkNetId = 1;
685         final int supplicantNetId = 10;
686 
687         // No current network in supplicant, return false
688         assertFalse(mDut.updateLinkedNetworks(
689                 WLAN0_IFACE_NAME, SUPPLICANT_NETWORK_ID, null));
690 
691         WifiConfiguration config = executeAndValidateConnectSequence(
692                 frameworkNetId, false, TRANSLATED_SUPPLICANT_SSID.toString());
693 
694         // Mismatched framework network id, return false
695         assertFalse(mDut.updateLinkedNetworks(WLAN0_IFACE_NAME, frameworkNetId + 1, null));
696 
697         // Supplicant network id is invalid, return false
698         when(mSupplicantStaNetworkMock.getNetworkId()).thenReturn(-1);
699         assertFalse(mDut.updateLinkedNetworks(WLAN0_IFACE_NAME, frameworkNetId, null));
700 
701         // Supplicant failed to return network list, return false
702         when(mSupplicantStaNetworkMock.getNetworkId()).thenReturn(supplicantNetId);
703         doAnswer(new AnswerWithArguments() {
704             public void answer(ISupplicantStaIface.listNetworksCallback cb) {
705                 cb.onValues(mStatusFailure, new ArrayList<>());
706             }
707         }).when(mISupplicantStaIfaceMock)
708                 .listNetworks(any(ISupplicantStaIface.listNetworksCallback.class));
709         assertFalse(mDut.updateLinkedNetworks(
710                 WLAN0_IFACE_NAME, frameworkNetId, null));
711 
712         // Supplicant returned a null network list, return false
713         doAnswer(new AnswerWithArguments() {
714             public void answer(ISupplicantStaIface.listNetworksCallback cb) {
715                 cb.onValues(mStatusSuccess, null);
716             }
717         }).when(mISupplicantStaIfaceMock)
718                 .listNetworks(any(ISupplicantStaIface.listNetworksCallback.class));
719         assertFalse(mDut.updateLinkedNetworks(
720                 WLAN0_IFACE_NAME, frameworkNetId, null));
721 
722         // Successfully link a network to the current network
723         final ArrayList<Integer> supplicantNetIds = new ArrayList<>();
724         supplicantNetIds.add(supplicantNetId);
725         doAnswer(new AnswerWithArguments() {
726             public void answer(ISupplicantStaIface.listNetworksCallback cb) {
727                 cb.onValues(mStatusSuccess, supplicantNetIds);
728             }
729         }).when(mISupplicantStaIfaceMock)
730                 .listNetworks(any(ISupplicantStaIface.listNetworksCallback.class));
731         WifiConfiguration linkedConfig = new WifiConfiguration();
732         linkedConfig.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
733         Map<String, WifiConfiguration> linkedNetworks = new HashMap<>();
734         linkedNetworks.put(linkedConfig.getProfileKey(), linkedConfig);
735         SupplicantStaNetworkHalHidlImpl linkedNetworkHandle =
736                 mock(SupplicantStaNetworkHalHidlImpl.class);
737         when(linkedNetworkHandle.getNetworkId()).thenReturn(supplicantNetId + 1);
738         when(linkedNetworkHandle.saveWifiConfiguration(linkedConfig)).thenReturn(true);
739         when(linkedNetworkHandle.select()).thenReturn(true);
740         mDut.setStaNetworkMockable(linkedNetworkHandle);
741         assertTrue(mDut.updateLinkedNetworks(
742                 WLAN0_IFACE_NAME, frameworkNetId, linkedNetworks));
743 
744         // Successfully remove linked network but not the current network from supplicant
745         supplicantNetIds.add(supplicantNetId + 1);
746         doAnswer(new AnswerWithArguments() {
747             public void answer(ISupplicantStaIface.listNetworksCallback cb) {
748                 cb.onValues(mStatusSuccess, supplicantNetIds);
749             }
750         }).when(mISupplicantStaIfaceMock)
751                 .listNetworks(any(ISupplicantStaIface.listNetworksCallback.class));
752         doAnswer(new AnswerWithArguments() {
753             public SupplicantStatus answer(int id) {
754                 return mStatusSuccess;
755             }
756         }).when(mISupplicantStaIfaceMock).removeNetwork(supplicantNetId + 1);
757         assertTrue(mDut.updateLinkedNetworks(
758                 WLAN0_IFACE_NAME, frameworkNetId, null));
759         verify(mISupplicantStaIfaceMock).removeNetwork(supplicantNetId + 1);
760         verify(mISupplicantStaIfaceMock, never()).removeNetwork(supplicantNetId);
761     }
762 
763     /**
764      * Tests roaming failure because of unable to set bssid.
765      */
766     @Test
testRoamFailureDueToBssidSet()767     public void testRoamFailureDueToBssidSet() throws Exception {
768         executeAndValidateInitializationSequence();
769         int connectedNetworkId = 5;
770         executeAndValidateConnectSequence(connectedNetworkId, false,
771                 TRANSLATED_SUPPLICANT_SSID.toString());
772         when(mSupplicantStaNetworkMock.setBssid(anyString())).thenReturn(false);
773 
774         WifiConfiguration roamingConfig = new WifiConfiguration();
775         roamingConfig.networkId = connectedNetworkId;
776         roamingConfig.getNetworkSelectionStatus().setNetworkSelectionBSSID("45:34:23:23:ab:ed");
777         assertFalse(mDut.roamToNetwork(WLAN0_IFACE_NAME, roamingConfig));
778     }
779 
780     /**
781      * Tests removal of all configured networks from wpa_supplicant.
782      */
783     @Test
testRemoveAllNetworks()784     public void testRemoveAllNetworks() throws Exception {
785         executeAndValidateInitializationSequence();
786         doAnswer(new MockAnswerUtil.AnswerWithArguments() {
787             public void answer(ISupplicantStaIface.listNetworksCallback cb) {
788                 cb.onValues(mStatusSuccess, new ArrayList<>(NETWORK_ID_TO_SSID.keySet()));
789             }
790         }).when(mISupplicantStaIfaceMock)
791                 .listNetworks(any(ISupplicantStaIface.listNetworksCallback.class));
792         doAnswer(new MockAnswerUtil.AnswerWithArguments() {
793             public SupplicantStatus answer(int id) {
794                 assertTrue(NETWORK_ID_TO_SSID.containsKey(id));
795                 return mStatusSuccess;
796             }
797         }).when(mISupplicantStaIfaceMock).removeNetwork(anyInt());
798 
799         assertTrue(mDut.removeAllNetworks(WLAN0_IFACE_NAME));
800         verify(mISupplicantStaIfaceMock, times(NETWORK_ID_TO_SSID.size())).removeNetwork(anyInt());
801     }
802 
803     /**
804      * Remove all networks while connected, verify that the current network info is resetted.
805      */
806     @Test
testRemoveAllNetworksWhileConnected()807     public void testRemoveAllNetworksWhileConnected() throws Exception {
808         String testBssid = "11:22:33:44:55:66";
809         when(mSupplicantStaNetworkMock.setBssid(eq(testBssid))).thenReturn(true);
810 
811         executeAndValidateInitializationSequence();
812 
813         // Connect to a network and verify current network is set.
814         executeAndValidateConnectSequence(4, false, TRANSLATED_SUPPLICANT_SSID.toString());
815         assertTrue(mDut.setCurrentNetworkBssid(WLAN0_IFACE_NAME, testBssid));
816         verify(mSupplicantStaNetworkMock).setBssid(eq(testBssid));
817         reset(mSupplicantStaNetworkMock);
818 
819         // Remove all networks and verify current network info is resetted.
820         assertTrue(mDut.removeAllNetworks(WLAN0_IFACE_NAME));
821         assertFalse(mDut.setCurrentNetworkBssid(WLAN0_IFACE_NAME, testBssid));
822         verify(mSupplicantStaNetworkMock, never()).setBssid(eq(testBssid));
823     }
824 
825     /**
826      * Tests roaming failure because of unable to reassociate.
827      */
828     @Test
testRoamFailureDueToReassociate()829     public void testRoamFailureDueToReassociate() throws Exception {
830         executeAndValidateInitializationSequence();
831         int connectedNetworkId = 5;
832         executeAndValidateConnectSequence(connectedNetworkId, false,
833                 TRANSLATED_SUPPLICANT_SSID.toString());
834 
835         doAnswer(new MockAnswerUtil.AnswerWithArguments() {
836             public SupplicantStatus answer() throws RemoteException {
837                 return mStatusFailure;
838             }
839         }).when(mISupplicantStaIfaceMock).reassociate();
840         when(mSupplicantStaNetworkMock.setBssid(anyString())).thenReturn(true);
841 
842         WifiConfiguration roamingConfig = new WifiConfiguration();
843         roamingConfig.networkId = connectedNetworkId;
844         roamingConfig.getNetworkSelectionStatus().setNetworkSelectionBSSID("45:34:23:23:ab:ed");
845         assertFalse(mDut.roamToNetwork(WLAN0_IFACE_NAME, roamingConfig));
846     }
847 
848     /**
849      * Tests the retrieval of WPS NFC token.
850      */
851     @Test
testGetCurrentNetworkWpsNfcConfigurationToken()852     public void testGetCurrentNetworkWpsNfcConfigurationToken() throws Exception {
853         String token = "45adbc1";
854         when(mSupplicantStaNetworkMock.getWpsNfcConfigurationToken()).thenReturn(token);
855 
856         executeAndValidateInitializationSequence();
857         // Return null when not connected to the network.
858         assertTrue(mDut.getCurrentNetworkWpsNfcConfigurationToken(WLAN0_IFACE_NAME) == null);
859         verify(mSupplicantStaNetworkMock, never()).getWpsNfcConfigurationToken();
860         executeAndValidateConnectSequence(4, false, TRANSLATED_SUPPLICANT_SSID.toString());
861         assertEquals(token, mDut.getCurrentNetworkWpsNfcConfigurationToken(WLAN0_IFACE_NAME));
862         verify(mSupplicantStaNetworkMock).getWpsNfcConfigurationToken();
863     }
864 
865     /**
866      * Tests the setting of BSSID.
867      */
868     @Test
testSetCurrentNetworkBssid()869     public void testSetCurrentNetworkBssid() throws Exception {
870         String bssidStr = "34:34:12:12:12:90";
871         when(mSupplicantStaNetworkMock.setBssid(eq(bssidStr))).thenReturn(true);
872 
873         executeAndValidateInitializationSequence();
874         // Fail when not connected to a network.
875         assertFalse(mDut.setCurrentNetworkBssid(WLAN0_IFACE_NAME, bssidStr));
876         verify(mSupplicantStaNetworkMock, never()).setBssid(eq(bssidStr));
877         executeAndValidateConnectSequence(4, false, TRANSLATED_SUPPLICANT_SSID.toString());
878         assertTrue(mDut.setCurrentNetworkBssid(WLAN0_IFACE_NAME, bssidStr));
879         verify(mSupplicantStaNetworkMock).setBssid(eq(bssidStr));
880     }
881 
882     /**
883      * Tests the sending identity response for the current network.
884      */
885     @Test
testSetCurrentNetworkEapIdentityResponse()886     public void testSetCurrentNetworkEapIdentityResponse() throws Exception {
887         String identity = "blah@blah.com";
888         String encryptedIdentity = "blah2@blah.com";
889         when(mSupplicantStaNetworkMock.sendNetworkEapIdentityResponse(eq(identity),
890                 eq(encryptedIdentity)))
891                 .thenReturn(true);
892 
893         executeAndValidateInitializationSequence();
894         // Fail when not connected to a network.
895         assertFalse(mDut.sendCurrentNetworkEapIdentityResponse(WLAN0_IFACE_NAME, identity,
896                 encryptedIdentity));
897         verify(mSupplicantStaNetworkMock, never()).sendNetworkEapIdentityResponse(eq(identity),
898                 eq(encryptedIdentity));
899         executeAndValidateConnectSequence(4, false, TRANSLATED_SUPPLICANT_SSID.toString());
900         assertTrue(mDut.sendCurrentNetworkEapIdentityResponse(WLAN0_IFACE_NAME, identity,
901                 encryptedIdentity));
902         verify(mSupplicantStaNetworkMock).sendNetworkEapIdentityResponse(eq(identity),
903                 eq(encryptedIdentity));
904     }
905 
906     /**
907      * Tests the getting of anonymous identity for the current network.
908      */
909     @Test
testGetCurrentNetworkEapAnonymousIdentity()910     public void testGetCurrentNetworkEapAnonymousIdentity() throws Exception {
911         String anonymousIdentity = "aaa@bbb.ccc";
912         when(mSupplicantStaNetworkMock.fetchEapAnonymousIdentity())
913                 .thenReturn(anonymousIdentity);
914         executeAndValidateInitializationSequence();
915 
916         // Return null when not connected to the network.
917         assertEquals(null, mDut.getCurrentNetworkEapAnonymousIdentity(WLAN0_IFACE_NAME));
918         executeAndValidateConnectSequence(4, false, TRANSLATED_SUPPLICANT_SSID.toString());
919         // Return anonymous identity for the current network.
920         assertEquals(
921                 anonymousIdentity, mDut.getCurrentNetworkEapAnonymousIdentity(WLAN0_IFACE_NAME));
922     }
923 
924     /**
925      * Tests the sending gsm auth response for the current network.
926      */
927     @Test
testSetCurrentNetworkEapSimGsmAuthResponse()928     public void testSetCurrentNetworkEapSimGsmAuthResponse() throws Exception {
929         String params = "test";
930         when(mSupplicantStaNetworkMock.sendNetworkEapSimGsmAuthResponse(eq(params)))
931                 .thenReturn(true);
932 
933         executeAndValidateInitializationSequence();
934         // Fail when not connected to a network.
935         assertFalse(mDut.sendCurrentNetworkEapSimGsmAuthResponse(WLAN0_IFACE_NAME, params));
936         verify(mSupplicantStaNetworkMock, never()).sendNetworkEapSimGsmAuthResponse(eq(params));
937         executeAndValidateConnectSequence(4, false, TRANSLATED_SUPPLICANT_SSID.toString());
938         assertTrue(mDut.sendCurrentNetworkEapSimGsmAuthResponse(WLAN0_IFACE_NAME, params));
939         verify(mSupplicantStaNetworkMock).sendNetworkEapSimGsmAuthResponse(eq(params));
940     }
941 
942     /**
943      * Tests the sending umts auth response for the current network.
944      */
945     @Test
testSetCurrentNetworkEapSimUmtsAuthResponse()946     public void testSetCurrentNetworkEapSimUmtsAuthResponse() throws Exception {
947         String params = "test";
948         when(mSupplicantStaNetworkMock.sendNetworkEapSimUmtsAuthResponse(eq(params)))
949                 .thenReturn(true);
950 
951         executeAndValidateInitializationSequence();
952         // Fail when not connected to a network.
953         assertFalse(mDut.sendCurrentNetworkEapSimUmtsAuthResponse(WLAN0_IFACE_NAME, params));
954         verify(mSupplicantStaNetworkMock, never()).sendNetworkEapSimUmtsAuthResponse(eq(params));
955         executeAndValidateConnectSequence(4, false, TRANSLATED_SUPPLICANT_SSID.toString());
956         assertTrue(mDut.sendCurrentNetworkEapSimUmtsAuthResponse(WLAN0_IFACE_NAME, params));
957         verify(mSupplicantStaNetworkMock).sendNetworkEapSimUmtsAuthResponse(eq(params));
958     }
959 
960     /**
961      * Tests the sending umts auts response for the current network.
962      */
963     @Test
testSetCurrentNetworkEapSimUmtsAutsResponse()964     public void testSetCurrentNetworkEapSimUmtsAutsResponse() throws Exception {
965         String params = "test";
966         when(mSupplicantStaNetworkMock.sendNetworkEapSimUmtsAutsResponse(eq(params)))
967                 .thenReturn(true);
968 
969         executeAndValidateInitializationSequence();
970         // Fail when not connected to a network.
971         assertFalse(mDut.sendCurrentNetworkEapSimUmtsAutsResponse(WLAN0_IFACE_NAME, params));
972         verify(mSupplicantStaNetworkMock, never()).sendNetworkEapSimUmtsAutsResponse(eq(params));
973         executeAndValidateConnectSequence(4, false, TRANSLATED_SUPPLICANT_SSID.toString());
974         assertTrue(mDut.sendCurrentNetworkEapSimUmtsAutsResponse(WLAN0_IFACE_NAME, params));
975         verify(mSupplicantStaNetworkMock).sendNetworkEapSimUmtsAutsResponse(eq(params));
976     }
977 
978     /**
979      * Tests the setting of WPS device type.
980      */
981     @Test
testSetWpsDeviceType()982     public void testSetWpsDeviceType() throws Exception {
983         String validDeviceTypeStr = "10-0050F204-5";
984         byte[] expectedDeviceType = { 0x0, 0xa, 0x0, 0x50, (byte) 0xf2, 0x04, 0x0, 0x05};
985         String invalidDeviceType1Str = "10-02050F204-5";
986         String invalidDeviceType2Str = "10-0050F204-534";
987         when(mISupplicantStaIfaceMock.setWpsDeviceType(any(byte[].class)))
988                 .thenReturn(mStatusSuccess);
989 
990         executeAndValidateInitializationSequence();
991 
992         // This should work.
993         assertTrue(mDut.setWpsDeviceType(WLAN0_IFACE_NAME, validDeviceTypeStr));
994         verify(mISupplicantStaIfaceMock).setWpsDeviceType(eq(expectedDeviceType));
995 
996         // This should not work
997         assertFalse(mDut.setWpsDeviceType(WLAN0_IFACE_NAME, invalidDeviceType1Str));
998         // This should not work
999         assertFalse(mDut.setWpsDeviceType(WLAN0_IFACE_NAME, invalidDeviceType2Str));
1000     }
1001 
1002     /**
1003      * Tests the setting of WPS config methods.
1004      */
1005     @Test
testSetWpsConfigMethods()1006     public void testSetWpsConfigMethods() throws Exception {
1007         String validConfigMethodsStr = "physical_display virtual_push_button";
1008         Short expectedConfigMethods =
1009                 WpsConfigMethods.PHY_DISPLAY | WpsConfigMethods.VIRT_PUSHBUTTON;
1010         String invalidConfigMethodsStr = "physical_display virtual_push_button test";
1011         when(mISupplicantStaIfaceMock.setWpsConfigMethods(anyShort())).thenReturn(mStatusSuccess);
1012 
1013         executeAndValidateInitializationSequence();
1014 
1015         // This should work.
1016         assertTrue(mDut.setWpsConfigMethods(WLAN0_IFACE_NAME, validConfigMethodsStr));
1017         verify(mISupplicantStaIfaceMock).setWpsConfigMethods(eq(expectedConfigMethods));
1018 
1019         // This should throw an illegal argument exception.
1020         try {
1021             assertFalse(mDut.setWpsConfigMethods(WLAN0_IFACE_NAME, invalidConfigMethodsStr));
1022         } catch (IllegalArgumentException e) {
1023             return;
1024         }
1025         assertTrue(false);
1026     }
1027 
1028     /**
1029      * Tests the handling of ANQP done callback.
1030      * Note: Since the ANQP element parsing methods are static, this can only test the negative test
1031      * where all the parsing fails because the data is empty. It'll be non-trivial and unnecessary
1032      * to test out the parsing logic here.
1033      */
1034     @Test
testAnqpDoneCallback()1035     public void testAnqpDoneCallback() throws Exception {
1036         executeAndValidateInitializationSequence();
1037         assertNotNull(mISupplicantStaIfaceCallback);
1038         byte[] bssid = NativeUtil.macAddressToByteArray(BSSID);
1039         mISupplicantStaIfaceCallback.onAnqpQueryDone(
1040                 bssid, new ISupplicantStaIfaceCallback.AnqpData(),
1041                 new ISupplicantStaIfaceCallback.Hs20AnqpData());
1042 
1043         ArgumentCaptor<AnqpEvent> anqpEventCaptor = ArgumentCaptor.forClass(AnqpEvent.class);
1044         verify(mWifiMonitor).broadcastAnqpDoneEvent(
1045                 eq(WLAN0_IFACE_NAME), anqpEventCaptor.capture());
1046         assertEquals(
1047                 ByteBufferReader.readInteger(
1048                         ByteBuffer.wrap(bssid), ByteOrder.BIG_ENDIAN, bssid.length),
1049                 anqpEventCaptor.getValue().getBssid());
1050     }
1051 
1052     /**
1053      * Tests the handling of ANQP done callback.
1054      * Note: Since the ANQP element parsing methods are static, this can only test the negative test
1055      * where all the parsing fails because the data is empty. It'll be non-trivial and unnecessary
1056      * to test out the parsing logic here.
1057      */
1058     @Test
testAnqpDoneCallback_1_4()1059     public void testAnqpDoneCallback_1_4() throws Exception {
1060         setupMocksForHalV1_4();
1061         executeAndValidateInitializationSequenceV1_4();
1062         assertNotNull(mISupplicantStaIfaceCallbackV14);
1063         byte[] bssid = NativeUtil.macAddressToByteArray(BSSID);
1064         mISupplicantStaIfaceCallbackV14.onAnqpQueryDone_1_4(
1065                 bssid,
1066                 new android.hardware.wifi.supplicant.V1_4.ISupplicantStaIfaceCallback.AnqpData(),
1067                 new ISupplicantStaIfaceCallback.Hs20AnqpData());
1068 
1069         ArgumentCaptor<AnqpEvent> anqpEventCaptor = ArgumentCaptor.forClass(AnqpEvent.class);
1070         verify(mWifiMonitor).broadcastAnqpDoneEvent(
1071                 eq(WLAN0_IFACE_NAME), anqpEventCaptor.capture());
1072         assertEquals(
1073                 ByteBufferReader.readInteger(
1074                         ByteBuffer.wrap(bssid), ByteOrder.BIG_ENDIAN, bssid.length),
1075                 anqpEventCaptor.getValue().getBssid());
1076     }
1077 
1078     /**
1079      * Tests the handling of Icon done callback.
1080      */
1081     @Test
testIconDoneCallback()1082     public void testIconDoneCallback() throws Exception {
1083         executeAndValidateInitializationSequence();
1084         assertNotNull(mISupplicantStaIfaceCallback);
1085 
1086         byte[] bssid = NativeUtil.macAddressToByteArray(BSSID);
1087         byte[] iconData = new byte[ICON_FILE_SIZE];
1088         new Random().nextBytes(iconData);
1089         mISupplicantStaIfaceCallback.onHs20IconQueryDone(
1090                 bssid, ICON_FILE_NAME, NativeUtil.byteArrayToArrayList(iconData));
1091 
1092         ArgumentCaptor<IconEvent> iconEventCaptor = ArgumentCaptor.forClass(IconEvent.class);
1093         verify(mWifiMonitor).broadcastIconDoneEvent(
1094                 eq(WLAN0_IFACE_NAME), iconEventCaptor.capture());
1095         assertEquals(
1096                 ByteBufferReader.readInteger(
1097                         ByteBuffer.wrap(bssid), ByteOrder.BIG_ENDIAN, bssid.length),
1098                 iconEventCaptor.getValue().getBSSID());
1099         assertEquals(ICON_FILE_NAME, iconEventCaptor.getValue().getFileName());
1100         assertArrayEquals(iconData, iconEventCaptor.getValue().getData());
1101     }
1102 
1103     /**
1104      * Tests the handling of HS20 subscription remediation callback.
1105      */
1106     @Test
testHs20SubscriptionRemediationCallback()1107     public void testHs20SubscriptionRemediationCallback() throws Exception {
1108         executeAndValidateInitializationSequence();
1109         assertNotNull(mISupplicantStaIfaceCallback);
1110 
1111         byte[] bssid = NativeUtil.macAddressToByteArray(BSSID);
1112         byte osuMethod = ISupplicantStaIfaceCallback.OsuMethod.OMA_DM;
1113         mISupplicantStaIfaceCallback.onHs20SubscriptionRemediation(
1114                 bssid, osuMethod, HS20_URL);
1115 
1116         ArgumentCaptor<WnmData> wnmDataCaptor = ArgumentCaptor.forClass(WnmData.class);
1117         verify(mWifiMonitor).broadcastWnmEvent(eq(WLAN0_IFACE_NAME), wnmDataCaptor.capture());
1118         assertEquals(
1119                 ByteBufferReader.readInteger(
1120                         ByteBuffer.wrap(bssid), ByteOrder.BIG_ENDIAN, bssid.length),
1121                 wnmDataCaptor.getValue().getBssid());
1122         assertEquals(osuMethod, wnmDataCaptor.getValue().getMethod());
1123         assertEquals(HS20_URL, wnmDataCaptor.getValue().getUrl());
1124     }
1125 
1126     /**
1127      * Tests the handling of HS20 deauth imminent callback.
1128      */
1129     @Test
testHs20DeauthImminentCallbackWithEssReasonCode()1130     public void testHs20DeauthImminentCallbackWithEssReasonCode() throws Exception {
1131         executeAndValidateHs20DeauthImminentCallback(true);
1132     }
1133 
1134     /**
1135      * Tests the handling of HS20 deauth imminent callback.
1136      */
1137     @Test
testHs20DeauthImminentCallbackWithNonEssReasonCode()1138     public void testHs20DeauthImminentCallbackWithNonEssReasonCode() throws Exception {
1139         executeAndValidateHs20DeauthImminentCallback(false);
1140     }
1141 
1142     /**
1143      * Tests the handling of HS20 Terms & Conditions acceptance callback.
1144      */
1145     @Test
testHs20TermsAndConditionsAcceptance()1146     public void testHs20TermsAndConditionsAcceptance() throws Exception {
1147         executeAndValidateHs20TermsAndConditionsCallback();
1148     }
1149 
1150     /**
1151      * Tests the handling of state change notification without any configured network.
1152      */
1153     @Test
testStateChangeCallbackWithNoConfiguredNetwork()1154     public void testStateChangeCallbackWithNoConfiguredNetwork() throws Exception {
1155         executeAndValidateInitializationSequence();
1156         assertNotNull(mISupplicantStaIfaceCallback);
1157 
1158         mISupplicantStaIfaceCallback.onStateChanged(
1159                 ISupplicantStaIfaceCallback.State.INACTIVE,
1160                 NativeUtil.macAddressToByteArray(BSSID), SUPPLICANT_NETWORK_ID,
1161                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
1162 
1163         // Can't compare WifiSsid instances because they lack an equals.
1164         verify(mWifiMonitor).broadcastSupplicantStateChangeEvent(
1165                 eq(WLAN0_IFACE_NAME), eq(WifiConfiguration.INVALID_NETWORK_ID),
1166                 eq(TRANSLATED_SUPPLICANT_SSID), eq(BSSID), eq(0), eq(SupplicantState.INACTIVE));
1167     }
1168 
1169     /**
1170      * Tests the handling of state change notification to associated after configuring a network.
1171      */
1172     @Test
testStateChangeToAssociatedCallback()1173     public void testStateChangeToAssociatedCallback() throws Exception {
1174         executeAndValidateInitializationSequence();
1175         int frameworkNetworkId = 6;
1176         executeAndValidateConnectSequence(frameworkNetworkId, false,
1177                 TRANSLATED_SUPPLICANT_SSID.toString());
1178         assertNotNull(mISupplicantStaIfaceCallback);
1179 
1180         mISupplicantStaIfaceCallback.onStateChanged(
1181                 ISupplicantStaIfaceCallback.State.ASSOCIATED,
1182                 NativeUtil.macAddressToByteArray(BSSID), SUPPLICANT_NETWORK_ID,
1183                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
1184 
1185         verify(mWifiMonitor).broadcastSupplicantStateChangeEvent(
1186                 eq(WLAN0_IFACE_NAME), eq(frameworkNetworkId),
1187                 eq(TRANSLATED_SUPPLICANT_SSID), eq(BSSID), eq(0), eq(SupplicantState.ASSOCIATED));
1188     }
1189 
1190     /**
1191      * Tests the handling of state change notification to completed after configuring a network.
1192      */
1193     @Test
testStateChangeToCompletedCallback()1194     public void testStateChangeToCompletedCallback() throws Exception {
1195         InOrder wifiMonitorInOrder = inOrder(mWifiMonitor);
1196         executeAndValidateInitializationSequence();
1197         int frameworkNetworkId = 6;
1198         executeAndValidateConnectSequence(frameworkNetworkId, false,
1199                 TRANSLATED_SUPPLICANT_SSID.toString());
1200         assertNotNull(mISupplicantStaIfaceCallback);
1201 
1202         mISupplicantStaIfaceCallback.onStateChanged(
1203                 ISupplicantStaIfaceCallback.State.COMPLETED,
1204                 NativeUtil.macAddressToByteArray(BSSID), SUPPLICANT_NETWORK_ID,
1205                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
1206 
1207         wifiMonitorInOrder.verify(mWifiMonitor).broadcastNetworkConnectionEvent(
1208                 eq(WLAN0_IFACE_NAME), eq(frameworkNetworkId), eq(false),
1209                 eq(TRANSLATED_SUPPLICANT_SSID), eq(BSSID));
1210         wifiMonitorInOrder.verify(mWifiMonitor).broadcastSupplicantStateChangeEvent(
1211                 eq(WLAN0_IFACE_NAME), eq(frameworkNetworkId),
1212                 eq(TRANSLATED_SUPPLICANT_SSID), eq(BSSID), eq(0), eq(SupplicantState.COMPLETED));
1213     }
1214 
1215     /**
1216      * Tests the handling of network disconnected notification.
1217      */
1218     @Test
testDisconnectedCallback()1219     public void testDisconnectedCallback() throws Exception {
1220         executeAndValidateInitializationSequence();
1221         assertNotNull(mISupplicantStaIfaceCallback);
1222 
1223         // Set the SSID for the current connection.
1224         mISupplicantStaIfaceCallback.onStateChanged(
1225                 ISupplicantStaIfaceCallback.State.ASSOCIATING,
1226                 NativeUtil.macAddressToByteArray(BSSID),
1227                 SUPPLICANT_NETWORK_ID,
1228                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
1229         int reasonCode = 5;
1230         mISupplicantStaIfaceCallback.onDisconnected(
1231                 NativeUtil.macAddressToByteArray(BSSID), true, reasonCode);
1232         verify(mWifiMonitor).broadcastNetworkDisconnectionEvent(
1233                 eq(WLAN0_IFACE_NAME), eq(true), eq(reasonCode),
1234                 eq(TRANSLATED_SUPPLICANT_SSID.toString()), eq(BSSID));
1235 
1236         mISupplicantStaIfaceCallback.onDisconnected(
1237                 NativeUtil.macAddressToByteArray(BSSID), false, reasonCode);
1238         verify(mWifiMonitor).broadcastNetworkDisconnectionEvent(
1239                 eq(WLAN0_IFACE_NAME), eq(false), eq(reasonCode),
1240                 eq(TRANSLATED_SUPPLICANT_SSID.toString()), eq(BSSID));
1241     }
1242 
1243     /**
1244      * Tests the handling of incorrect network passwords.
1245      */
1246     @Test
testAuthFailurePasswordOnDisconnect()1247     public void testAuthFailurePasswordOnDisconnect() throws Exception {
1248         executeAndValidateInitializationSequence();
1249         assertNotNull(mISupplicantStaIfaceCallback);
1250         executeAndValidateConnectSequenceWithKeyMgmt(0, false,
1251                 TRANSLATED_SUPPLICANT_SSID.toString(), WifiConfiguration.SECURITY_TYPE_PSK, null);
1252 
1253         int reasonCode = 3;
1254         mISupplicantStaIfaceCallback.onDisconnected(
1255                 NativeUtil.macAddressToByteArray(BSSID), true, reasonCode);
1256         verify(mWifiMonitor, times(0))
1257                 .broadcastAuthenticationFailureEvent(any(), anyInt(), anyInt(), any(), any());
1258 
1259         mISupplicantStaIfaceCallback.onDisconnected(
1260                 NativeUtil.macAddressToByteArray(BSSID), false, reasonCode);
1261         verify(mWifiMonitor, times(0))
1262                 .broadcastAuthenticationFailureEvent(any(), anyInt(), anyInt(), any(), any());
1263 
1264         mISupplicantStaIfaceCallback.onStateChanged(
1265                 ISupplicantStaIfaceCallback.State.ASSOCIATING,
1266                 NativeUtil.macAddressToByteArray(BSSID),
1267                 SUPPLICANT_NETWORK_ID,
1268                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
1269         mISupplicantStaIfaceCallback.onStateChanged(
1270                 ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE,
1271                 NativeUtil.macAddressToByteArray(BSSID),
1272                 SUPPLICANT_NETWORK_ID,
1273                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
1274         mISupplicantStaIfaceCallback.onDisconnected(
1275                 NativeUtil.macAddressToByteArray(BSSID), false, reasonCode);
1276 
1277         verify(mWifiMonitor).broadcastAuthenticationFailureEvent(
1278                 eq(WLAN0_IFACE_NAME), eq(WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD), eq(-1),
1279                 eq(TRANSLATED_SUPPLICANT_SSID.toString()), eq(MacAddress.fromString(BSSID)));
1280     }
1281 
1282     /**
1283      * Tests that connection failure due to wrong password in WAPI-PSK network is notified.
1284      */
1285     @Test
testWapiPskWrongPasswordNotification()1286     public void testWapiPskWrongPasswordNotification() throws Exception {
1287         executeAndValidateInitializationSequence();
1288         assertNotNull(mISupplicantStaIfaceCallback);
1289         executeAndValidateConnectSequenceWithKeyMgmt(0, false,
1290                 TRANSLATED_SUPPLICANT_SSID.toString(), WifiConfiguration.SECURITY_TYPE_WAPI_PSK,
1291                 null);
1292 
1293         mISupplicantStaIfaceCallback.onStateChanged(
1294                 ISupplicantStaIfaceCallback.State.ASSOCIATING,
1295                 NativeUtil.macAddressToByteArray(BSSID),
1296                 SUPPLICANT_NETWORK_ID,
1297                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
1298         mISupplicantStaIfaceCallback.onStateChanged(
1299                 ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE,
1300                 NativeUtil.macAddressToByteArray(BSSID),
1301                 SUPPLICANT_NETWORK_ID,
1302                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
1303         mISupplicantStaIfaceCallback.onDisconnected(
1304                 NativeUtil.macAddressToByteArray(BSSID), false, 3);
1305 
1306         verify(mWifiMonitor).broadcastAuthenticationFailureEvent(
1307                 eq(WLAN0_IFACE_NAME), eq(WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD), eq(-1),
1308                 eq(TRANSLATED_SUPPLICANT_SSID.toString()), eq(MacAddress.fromString(BSSID)));
1309     }
1310 
1311     /**
1312      * Tests the handling of EAP failure disconnects.
1313      */
1314     @Test
testAuthFailureEapOnDisconnect()1315     public void testAuthFailureEapOnDisconnect() throws Exception {
1316         executeAndValidateInitializationSequence();
1317         assertNotNull(mISupplicantStaIfaceCallback);
1318         executeAndValidateConnectSequenceWithKeyMgmt(0, false,
1319                 TRANSLATED_SUPPLICANT_SSID.toString(), WifiConfiguration.SECURITY_TYPE_EAP, null);
1320 
1321         int reasonCode = 3;
1322         mISupplicantStaIfaceCallback.onDisconnected(
1323                 NativeUtil.macAddressToByteArray(BSSID), true, reasonCode);
1324         verify(mWifiMonitor, times(0))
1325                 .broadcastAuthenticationFailureEvent(any(), anyInt(), anyInt(), any(), any());
1326 
1327         mISupplicantStaIfaceCallback.onDisconnected(
1328                 NativeUtil.macAddressToByteArray(BSSID), false, reasonCode);
1329         verify(mWifiMonitor, times(0))
1330                 .broadcastAuthenticationFailureEvent(any(), anyInt(), anyInt(), any(), any());
1331 
1332         mISupplicantStaIfaceCallback.onStateChanged(
1333                 ISupplicantStaIfaceCallback.State.ASSOCIATING,
1334                 NativeUtil.macAddressToByteArray(BSSID),
1335                 SUPPLICANT_NETWORK_ID,
1336                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
1337         mISupplicantStaIfaceCallback.onStateChanged(
1338                 ISupplicantStaIfaceCallback.State.ASSOCIATED,
1339                 NativeUtil.macAddressToByteArray(BSSID),
1340                 SUPPLICANT_NETWORK_ID,
1341                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
1342         // Ensure we don't lose our prev state with this state changed event.
1343         mISupplicantStaIfaceCallback.onStateChanged(
1344                 ISupplicantStaIfaceCallback.State.DISCONNECTED,
1345                 NativeUtil.macAddressToByteArray(BSSID),
1346                 SUPPLICANT_NETWORK_ID,
1347                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
1348         mISupplicantStaIfaceCallback.onDisconnected(
1349                 NativeUtil.macAddressToByteArray(BSSID), false, reasonCode);
1350 
1351         verify(mWifiMonitor).broadcastAuthenticationFailureEvent(
1352                 eq(WLAN0_IFACE_NAME), eq(WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE), eq(-1),
1353                 eq(TRANSLATED_SUPPLICANT_SSID.toString()), eq(MacAddress.fromString(BSSID)));
1354     }
1355 
1356     /**
1357      * Tests the handling of EAP failure disconnects.
1358      */
1359     @Test
testOnlyOneAuthFailureEap()1360     public void testOnlyOneAuthFailureEap() throws Exception {
1361         executeAndValidateInitializationSequence();
1362         assertNotNull(mISupplicantStaIfaceCallback);
1363         executeAndValidateConnectSequenceWithKeyMgmt(0, false,
1364                 TRANSLATED_SUPPLICANT_SSID.toString(), WifiConfiguration.SECURITY_TYPE_EAP, null);
1365 
1366         int reasonCode = 3;
1367         mISupplicantStaIfaceCallback.onStateChanged(
1368                 ISupplicantStaIfaceCallback.State.ASSOCIATING,
1369                 NativeUtil.macAddressToByteArray(BSSID),
1370                 SUPPLICANT_NETWORK_ID,
1371                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
1372         mISupplicantStaIfaceCallback.onStateChanged(
1373                 ISupplicantStaIfaceCallback.State.ASSOCIATED,
1374                 NativeUtil.macAddressToByteArray(BSSID),
1375                 SUPPLICANT_NETWORK_ID,
1376                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
1377         mISupplicantStaIfaceCallback.onEapFailure();
1378         verify(mWifiMonitor).broadcastAuthenticationFailureEvent(
1379                 eq(WLAN0_IFACE_NAME), eq(WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE), eq(-1),
1380                 eq(TRANSLATED_SUPPLICANT_SSID.toString()), eq(MacAddress.BROADCAST_ADDRESS));
1381 
1382         // Ensure that the disconnect is ignored.
1383         mISupplicantStaIfaceCallback.onDisconnected(
1384                 NativeUtil.macAddressToByteArray(BSSID), false, reasonCode);
1385         verify(mWifiMonitor, times(1)).broadcastAuthenticationFailureEvent(
1386                 eq(WLAN0_IFACE_NAME), eq(WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE), eq(-1),
1387                 eq(TRANSLATED_SUPPLICANT_SSID.toString()), eq(MacAddress.BROADCAST_ADDRESS));
1388     }
1389 
1390     /**
1391      * Tests the handling of incorrect network passwords for WPA3-Personal networks
1392      */
1393     @Test
testWpa3AuthRejectionPassword()1394     public void testWpa3AuthRejectionPassword() throws Exception {
1395         executeAndValidateInitializationSequence();
1396         assertNotNull(mISupplicantStaIfaceCallback);
1397 
1398         executeAndValidateConnectSequenceWithKeyMgmt(SUPPLICANT_NETWORK_ID, false,
1399                 TRANSLATED_SUPPLICANT_SSID.toString(), WifiConfiguration.SECURITY_TYPE_SAE, null);
1400 
1401         mISupplicantStaIfaceCallback.onStateChanged(
1402                 ISupplicantStaIfaceCallback.State.ASSOCIATING,
1403                 NativeUtil.macAddressToByteArray(BSSID),
1404                 SUPPLICANT_NETWORK_ID,
1405                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
1406         int statusCode = ISupplicantStaIfaceCallback.StatusCode.UNSPECIFIED_FAILURE;
1407         mISupplicantStaIfaceCallback.onAssociationRejected(
1408                 NativeUtil.macAddressToByteArray(BSSID), statusCode, false);
1409         verify(mWifiMonitor).broadcastAuthenticationFailureEvent(eq(WLAN0_IFACE_NAME),
1410                 eq(WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD), eq(-1),
1411                 eq(TRANSLATED_SUPPLICANT_SSID.toString()), eq(MacAddress.fromString(BSSID)));
1412         ArgumentCaptor<AssocRejectEventInfo> assocRejectEventInfoCaptor =
1413                 ArgumentCaptor.forClass(AssocRejectEventInfo.class);
1414         verify(mWifiMonitor).broadcastAssociationRejectionEvent(
1415                 eq(WLAN0_IFACE_NAME), assocRejectEventInfoCaptor.capture());
1416         AssocRejectEventInfo assocRejectEventInfo =
1417                 (AssocRejectEventInfo) assocRejectEventInfoCaptor.getValue();
1418         assertNotNull(assocRejectEventInfo);
1419         assertEquals(TRANSLATED_SUPPLICANT_SSID.toString(), assocRejectEventInfo.ssid);
1420         assertEquals(BSSID, assocRejectEventInfo.bssid);
1421         assertEquals(statusCode, assocRejectEventInfo.statusCode);
1422         assertFalse(assocRejectEventInfo.timedOut);
1423         assertNull(assocRejectEventInfo.oceRssiBasedAssocRejectInfo);
1424         assertNull(assocRejectEventInfo.mboAssocDisallowedInfo);
1425     }
1426 
1427     /**
1428      * Tests the handling of incorrect network passwords for WPA3-Personal networks using
1429      * callback V1_4.
1430      */
1431     @Test
testWpa3AuthRejectionPassword_1_4()1432     public void testWpa3AuthRejectionPassword_1_4() throws Exception {
1433         setupMocksForHalV1_4();
1434         executeAndValidateInitializationSequenceV1_4();
1435         assertNotNull(mISupplicantStaIfaceCallbackV14);
1436 
1437         executeAndValidateConnectSequenceWithKeyMgmt(SUPPLICANT_NETWORK_ID, false,
1438                 TRANSLATED_SUPPLICANT_SSID.toString(), WifiConfiguration.SECURITY_TYPE_SAE, null);
1439 
1440         int statusCode = ISupplicantStaIfaceCallback.StatusCode.UNSPECIFIED_FAILURE;
1441         AssociationRejectionData rejectionData = new AssociationRejectionData();
1442         rejectionData.ssid = NativeUtil.decodeSsid(SUPPLICANT_SSID);
1443         rejectionData.bssid = NativeUtil.macAddressToByteArray(BSSID);
1444         rejectionData.statusCode = statusCode;
1445         rejectionData.timedOut = false;
1446         rejectionData.isMboAssocDisallowedReasonCodePresent = false;
1447         rejectionData.isOceRssiBasedAssocRejectAttrPresent = false;
1448 
1449         mISupplicantStaIfaceCallbackV14.onAssociationRejected_1_4(rejectionData);
1450         verify(mWifiMonitor).broadcastAuthenticationFailureEvent(eq(WLAN0_IFACE_NAME),
1451                 eq(WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD), eq(-1),
1452                 eq(TRANSLATED_SUPPLICANT_SSID.toString()), eq(MacAddress.fromString(BSSID)));
1453         ArgumentCaptor<AssocRejectEventInfo> assocRejectEventInfoCaptor =
1454                 ArgumentCaptor.forClass(AssocRejectEventInfo.class);
1455         verify(mWifiMonitor).broadcastAssociationRejectionEvent(
1456                 eq(WLAN0_IFACE_NAME), assocRejectEventInfoCaptor.capture());
1457         AssocRejectEventInfo assocRejectEventInfo = assocRejectEventInfoCaptor.getValue();
1458         assertNotNull(assocRejectEventInfo);
1459         assertEquals(TRANSLATED_SUPPLICANT_SSID.toString(), assocRejectEventInfo.ssid);
1460         assertEquals(BSSID, assocRejectEventInfo.bssid);
1461         assertEquals(statusCode, assocRejectEventInfo.statusCode);
1462         assertFalse(assocRejectEventInfo.timedOut);
1463         assertNull(assocRejectEventInfo.oceRssiBasedAssocRejectInfo);
1464         assertNull(assocRejectEventInfo.mboAssocDisallowedInfo);
1465     }
1466 
1467     /**
1468      * Tests the handling of association rejection for WPA3-Personal networks
1469      */
1470     @Test
testWpa3AuthRejectionEverConnected()1471     public void testWpa3AuthRejectionEverConnected() throws Exception {
1472         executeAndValidateInitializationSequence();
1473         assertNotNull(mISupplicantStaIfaceCallback);
1474 
1475         WifiConfiguration config = executeAndValidateConnectSequenceWithKeyMgmt(
1476                 SUPPLICANT_NETWORK_ID, false, TRANSLATED_SUPPLICANT_SSID.toString(),
1477                 WifiConfiguration.SECURITY_TYPE_SAE, null, true);
1478         mISupplicantStaIfaceCallback.onStateChanged(
1479                 ISupplicantStaIfaceCallback.State.ASSOCIATING,
1480                 NativeUtil.macAddressToByteArray(BSSID),
1481                 SUPPLICANT_NETWORK_ID,
1482                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
1483         int statusCode = ISupplicantStaIfaceCallback.StatusCode.UNSPECIFIED_FAILURE;
1484         mISupplicantStaIfaceCallback.onAssociationRejected(
1485                 NativeUtil.macAddressToByteArray(BSSID), statusCode, false);
1486         verify(mWifiMonitor, never()).broadcastAuthenticationFailureEvent(eq(WLAN0_IFACE_NAME),
1487                 anyInt(), anyInt(), any(), any());
1488         ArgumentCaptor<AssocRejectEventInfo> assocRejectEventInfoCaptor =
1489                 ArgumentCaptor.forClass(AssocRejectEventInfo.class);
1490         verify(mWifiMonitor).broadcastAssociationRejectionEvent(
1491                 eq(WLAN0_IFACE_NAME), assocRejectEventInfoCaptor.capture());
1492         AssocRejectEventInfo assocRejectEventInfo =
1493                 (AssocRejectEventInfo) assocRejectEventInfoCaptor.getValue();
1494         assertNotNull(assocRejectEventInfo);
1495         assertEquals(TRANSLATED_SUPPLICANT_SSID.toString(), assocRejectEventInfo.ssid);
1496         assertEquals(BSSID, assocRejectEventInfo.bssid);
1497         assertEquals(statusCode, assocRejectEventInfo.statusCode);
1498         assertFalse(assocRejectEventInfo.timedOut);
1499         assertNull(assocRejectEventInfo.oceRssiBasedAssocRejectInfo);
1500         assertNull(assocRejectEventInfo.mboAssocDisallowedInfo);
1501     }
1502 
1503     /**
1504      * Tests the handling of incorrect network passwords for WEP networks.
1505      */
1506     @Test
testWepAuthRejectionPassword()1507     public void testWepAuthRejectionPassword() throws Exception {
1508         executeAndValidateInitializationSequence();
1509         assertNotNull(mISupplicantStaIfaceCallback);
1510 
1511         executeAndValidateConnectSequenceWithKeyMgmt(SUPPLICANT_NETWORK_ID, false,
1512                 TRANSLATED_SUPPLICANT_SSID.toString(), WifiConfiguration.SECURITY_TYPE_WEP,
1513                 "97CA326539");
1514 
1515         mISupplicantStaIfaceCallback.onStateChanged(
1516                 ISupplicantStaIfaceCallback.State.ASSOCIATING,
1517                 NativeUtil.macAddressToByteArray(BSSID),
1518                 SUPPLICANT_NETWORK_ID,
1519                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
1520         int statusCode = ISupplicantStaIfaceCallback.StatusCode.CHALLENGE_FAIL;
1521         mISupplicantStaIfaceCallback.onAssociationRejected(
1522                 NativeUtil.macAddressToByteArray(BSSID), statusCode, false);
1523         verify(mWifiMonitor).broadcastAuthenticationFailureEvent(eq(WLAN0_IFACE_NAME),
1524                 eq(WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD), eq(-1),
1525                 eq(TRANSLATED_SUPPLICANT_SSID.toString()), eq(MacAddress.fromString(BSSID)));
1526         ArgumentCaptor<AssocRejectEventInfo> assocRejectEventInfoCaptor =
1527                 ArgumentCaptor.forClass(AssocRejectEventInfo.class);
1528         verify(mWifiMonitor).broadcastAssociationRejectionEvent(
1529                 eq(WLAN0_IFACE_NAME), assocRejectEventInfoCaptor.capture());
1530         AssocRejectEventInfo assocRejectEventInfo =
1531                 (AssocRejectEventInfo) assocRejectEventInfoCaptor.getValue();
1532         assertNotNull(assocRejectEventInfo);
1533         assertEquals(TRANSLATED_SUPPLICANT_SSID.toString(), assocRejectEventInfo.ssid);
1534         assertEquals(BSSID, assocRejectEventInfo.bssid);
1535         assertEquals(statusCode, assocRejectEventInfo.statusCode);
1536         assertFalse(assocRejectEventInfo.timedOut);
1537         assertNull(assocRejectEventInfo.oceRssiBasedAssocRejectInfo);
1538         assertNull(assocRejectEventInfo.mboAssocDisallowedInfo);
1539     }
1540 
1541     /**
1542      * Tests the handling of incorrect network passwords, edge case.
1543      *
1544      * If the network is removed during 4-way handshake, do not call it a password mismatch.
1545      */
1546     @Test
testNetworkRemovedDuring4way()1547     public void testNetworkRemovedDuring4way() throws Exception {
1548         executeAndValidateInitializationSequence();
1549         assertNotNull(mISupplicantStaIfaceCallback);
1550 
1551         int reasonCode = 3;
1552 
1553         mISupplicantStaIfaceCallback.onStateChanged(
1554                 ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE,
1555                 NativeUtil.macAddressToByteArray(BSSID),
1556                 SUPPLICANT_NETWORK_ID,
1557                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
1558         mISupplicantStaIfaceCallback.onNetworkRemoved(SUPPLICANT_NETWORK_ID);
1559         mISupplicantStaIfaceCallback.onDisconnected(
1560                 NativeUtil.macAddressToByteArray(BSSID), true, reasonCode);
1561         verify(mWifiMonitor, times(0)).broadcastAuthenticationFailureEvent(any(), anyInt(),
1562                 anyInt(), any(), any());
1563     }
1564 
1565      /**
1566       * Tests the handling of incorrect network passwords, edge case.
1567       *
1568       * If the disconnect reason is "IE in 4way differs", do not call it a password mismatch.
1569       */
1570     @Test
testIeDiffers()1571     public void testIeDiffers() throws Exception {
1572         executeAndValidateInitializationSequence();
1573         assertNotNull(mISupplicantStaIfaceCallback);
1574 
1575         int reasonCode = ISupplicantStaIfaceCallback.ReasonCode.IE_IN_4WAY_DIFFERS;
1576 
1577         mISupplicantStaIfaceCallback.onStateChanged(
1578                 ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE,
1579                 NativeUtil.macAddressToByteArray(BSSID),
1580                 SUPPLICANT_NETWORK_ID,
1581                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
1582         mISupplicantStaIfaceCallback.onDisconnected(
1583                 NativeUtil.macAddressToByteArray(BSSID), true, reasonCode);
1584         verify(mWifiMonitor, times(0)).broadcastAuthenticationFailureEvent(any(), anyInt(),
1585                 anyInt(), any(), any());
1586     }
1587 
1588     /**
1589      * Tests the handling of eap failure during disconnect.
1590      */
1591     @Test
testEapFailure()1592     public void testEapFailure() throws Exception {
1593         executeAndValidateInitializationSequence();
1594         assertNotNull(mISupplicantStaIfaceCallback);
1595 
1596         int reasonCode = ISupplicantStaIfaceCallback.ReasonCode.IEEE_802_1X_AUTH_FAILED;
1597         mISupplicantStaIfaceCallback.onDisconnected(
1598                 NativeUtil.macAddressToByteArray(BSSID), false, reasonCode);
1599         verify(mWifiMonitor, times(0)).broadcastAuthenticationFailureEvent(any(), anyInt(),
1600                 anyInt(), any(), any());
1601     }
1602 
1603     /**
1604      * Tests the handling of association rejection notification.
1605      */
1606     @Test
testAssociationRejectionCallback()1607     public void testAssociationRejectionCallback() throws Exception {
1608         executeAndValidateInitializationSequence();
1609         assertNotNull(mISupplicantStaIfaceCallback);
1610 
1611         mISupplicantStaIfaceCallback.onStateChanged(
1612                 ISupplicantStaIfaceCallback.State.ASSOCIATING,
1613                 NativeUtil.macAddressToByteArray(BSSID),
1614                 SUPPLICANT_NETWORK_ID,
1615                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
1616         int statusCode = 7;
1617         mISupplicantStaIfaceCallback.onAssociationRejected(
1618                 NativeUtil.macAddressToByteArray(BSSID), statusCode, false);
1619         ArgumentCaptor<AssocRejectEventInfo> assocRejectEventInfoCaptor =
1620                 ArgumentCaptor.forClass(AssocRejectEventInfo.class);
1621         verify(mWifiMonitor).broadcastAssociationRejectionEvent(
1622                 eq(WLAN0_IFACE_NAME), assocRejectEventInfoCaptor.capture());
1623         AssocRejectEventInfo assocRejectEventInfo =
1624                 (AssocRejectEventInfo) assocRejectEventInfoCaptor.getValue();
1625         assertNotNull(assocRejectEventInfo);
1626         assertEquals(TRANSLATED_SUPPLICANT_SSID.toString(), assocRejectEventInfo.ssid);
1627         assertEquals(BSSID, assocRejectEventInfo.bssid);
1628         assertEquals(statusCode, assocRejectEventInfo.statusCode);
1629         assertFalse(assocRejectEventInfo.timedOut);
1630         assertNull(assocRejectEventInfo.oceRssiBasedAssocRejectInfo);
1631         assertNull(assocRejectEventInfo.mboAssocDisallowedInfo);
1632     }
1633 
1634     /**
1635      * Tests the handling of authentication timeout notification.
1636      */
1637     @Test
testAuthenticationTimeoutCallback()1638     public void testAuthenticationTimeoutCallback() throws Exception {
1639         executeAndValidateInitializationSequence();
1640         assertNotNull(mISupplicantStaIfaceCallback);
1641 
1642         mISupplicantStaIfaceCallback.onStateChanged(
1643                 ISupplicantStaIfaceCallback.State.ASSOCIATING,
1644                 NativeUtil.macAddressToByteArray(BSSID),
1645                 SUPPLICANT_NETWORK_ID,
1646                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
1647         mISupplicantStaIfaceCallback.onAuthenticationTimeout(
1648                 NativeUtil.macAddressToByteArray(BSSID));
1649         verify(mWifiMonitor).broadcastAuthenticationFailureEvent(eq(WLAN0_IFACE_NAME),
1650                 eq(WifiManager.ERROR_AUTH_FAILURE_TIMEOUT), eq(-1),
1651                 eq(TRANSLATED_SUPPLICANT_SSID.toString()), eq(MacAddress.fromString(BSSID)));
1652     }
1653 
1654     /**
1655      * Tests the handling of bssid change notification.
1656      */
1657     @Test
testBssidChangedCallback()1658     public void testBssidChangedCallback() throws Exception {
1659         executeAndValidateInitializationSequence();
1660         assertNotNull(mISupplicantStaIfaceCallback);
1661 
1662         mISupplicantStaIfaceCallback.onBssidChanged(
1663                 BssidChangeReason.ASSOC_START, NativeUtil.macAddressToByteArray(BSSID));
1664         verify(mWifiMonitor).broadcastTargetBssidEvent(eq(WLAN0_IFACE_NAME), eq(BSSID));
1665         verify(mWifiMonitor, never()).broadcastAssociatedBssidEvent(
1666                 eq(WLAN0_IFACE_NAME), eq(BSSID));
1667 
1668         reset(mWifiMonitor);
1669         mISupplicantStaIfaceCallback.onBssidChanged(
1670                 BssidChangeReason.ASSOC_COMPLETE, NativeUtil.macAddressToByteArray(BSSID));
1671         verify(mWifiMonitor, never()).broadcastTargetBssidEvent(eq(WLAN0_IFACE_NAME), eq(BSSID));
1672         verify(mWifiMonitor).broadcastAssociatedBssidEvent(eq(WLAN0_IFACE_NAME), eq(BSSID));
1673 
1674         reset(mWifiMonitor);
1675         mISupplicantStaIfaceCallback.onBssidChanged(
1676                 BssidChangeReason.DISASSOC, NativeUtil.macAddressToByteArray(BSSID));
1677         verify(mWifiMonitor, never()).broadcastTargetBssidEvent(eq(WLAN0_IFACE_NAME), eq(BSSID));
1678         verify(mWifiMonitor, never()).broadcastAssociatedBssidEvent(
1679                 eq(WLAN0_IFACE_NAME), eq(BSSID));
1680     }
1681 
1682     /**
1683      * Tests the handling of EAP failure notification.
1684      */
1685     @Test
testEapFailureCallback()1686     public void testEapFailureCallback() throws Exception {
1687         int eapFailureCode = WifiNative.EAP_SIM_VENDOR_SPECIFIC_CERT_EXPIRED;
1688         testInitialize_successV1_1();
1689         assertNotNull(mISupplicantStaIfaceCallbackV11);
1690 
1691         mISupplicantStaIfaceCallbackV11.onStateChanged(
1692                 ISupplicantStaIfaceCallback.State.ASSOCIATING,
1693                 NativeUtil.macAddressToByteArray(BSSID),
1694                 SUPPLICANT_NETWORK_ID,
1695                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
1696         mISupplicantStaIfaceCallbackV11.onEapFailure_1_1(eapFailureCode);
1697         verify(mWifiMonitor).broadcastAuthenticationFailureEvent(
1698                 eq(WLAN0_IFACE_NAME), eq(WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE),
1699                 eq(eapFailureCode), eq(TRANSLATED_SUPPLICANT_SSID.toString()),
1700                 eq(MacAddress.BROADCAST_ADDRESS));
1701     }
1702 
1703     /**
1704      * Tests the handling of EAP failure notification.
1705      */
1706     @Test
testEapFailureCallback1_3()1707     public void testEapFailureCallback1_3() throws Exception {
1708         int eapFailureCode = WifiNative.EAP_SIM_VENDOR_SPECIFIC_CERT_EXPIRED;
1709         testInitialize_successV1_3();
1710         assertNotNull(mISupplicantStaIfaceCallbackV13);
1711 
1712         mISupplicantStaIfaceCallbackV13.onStateChanged(
1713                 ISupplicantStaIfaceCallback.State.ASSOCIATING,
1714                 NativeUtil.macAddressToByteArray(BSSID),
1715                 SUPPLICANT_NETWORK_ID,
1716                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
1717         mISupplicantStaIfaceCallbackV13.onEapFailure_1_3(eapFailureCode);
1718         verify(mWifiMonitor).broadcastAuthenticationFailureEvent(
1719                 eq(WLAN0_IFACE_NAME), eq(WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE),
1720                 eq(eapFailureCode), eq(TRANSLATED_SUPPLICANT_SSID.toString()),
1721                 eq(MacAddress.BROADCAST_ADDRESS));
1722     }
1723 
1724     /**
1725      * Tests the handling of Wps success notification.
1726      */
1727     @Test
testWpsSuccessCallback()1728     public void testWpsSuccessCallback() throws Exception {
1729         executeAndValidateInitializationSequence();
1730         assertNotNull(mISupplicantStaIfaceCallback);
1731 
1732         mISupplicantStaIfaceCallback.onWpsEventSuccess();
1733         verify(mWifiMonitor).broadcastWpsSuccessEvent(eq(WLAN0_IFACE_NAME));
1734     }
1735 
1736     /**
1737      * Tests the handling of Wps fail notification.
1738      */
1739     @Test
testWpsFailureCallback()1740     public void testWpsFailureCallback() throws Exception {
1741         executeAndValidateInitializationSequence();
1742         assertNotNull(mISupplicantStaIfaceCallback);
1743 
1744         short cfgError = ISupplicantStaIfaceCallback.WpsConfigError.MULTIPLE_PBC_DETECTED;
1745         short errorInd = ISupplicantStaIfaceCallback.WpsErrorIndication.SECURITY_WEP_PROHIBITED;
1746         mISupplicantStaIfaceCallback.onWpsEventFail(
1747                 NativeUtil.macAddressToByteArray(BSSID), cfgError, errorInd);
1748         verify(mWifiMonitor).broadcastWpsFailEvent(eq(WLAN0_IFACE_NAME),
1749                 eq((int) cfgError), eq((int) errorInd));
1750     }
1751 
1752     /**
1753      * Tests the handling of Wps fail notification.
1754      */
1755     @Test
testWpsTimeoutCallback()1756     public void testWpsTimeoutCallback() throws Exception {
1757         executeAndValidateInitializationSequence();
1758         assertNotNull(mISupplicantStaIfaceCallback);
1759 
1760         short cfgError = ISupplicantStaIfaceCallback.WpsConfigError.MSG_TIMEOUT;
1761         short errorInd = ISupplicantStaIfaceCallback.WpsErrorIndication.NO_ERROR;
1762         mISupplicantStaIfaceCallback.onWpsEventFail(
1763                 NativeUtil.macAddressToByteArray(BSSID), cfgError, errorInd);
1764         verify(mWifiMonitor).broadcastWpsTimeoutEvent(eq(WLAN0_IFACE_NAME));
1765     }
1766 
1767     /**
1768      * Tests the handling of Wps pbc overlap notification.
1769      */
1770     @Test
testWpsPbcOverlapCallback()1771     public void testWpsPbcOverlapCallback() throws Exception {
1772         executeAndValidateInitializationSequence();
1773         assertNotNull(mISupplicantStaIfaceCallback);
1774 
1775         mISupplicantStaIfaceCallback.onWpsEventPbcOverlap();
1776         verify(mWifiMonitor).broadcastWpsOverlapEvent(eq(WLAN0_IFACE_NAME));
1777     }
1778 
1779     /**
1780      * Tests the handling of service manager death notification.
1781      */
1782     @Test
testServiceManagerDeathCallback()1783     public void testServiceManagerDeathCallback() throws Exception {
1784         executeAndValidateInitializationSequence();
1785         assertNotNull(mServiceManagerDeathCaptor.getValue());
1786         assertTrue(mDut.isInitializationComplete());
1787         assertTrue(mDut.registerDeathHandler(mSupplicantHalDeathHandler));
1788 
1789         mServiceManagerDeathCaptor.getValue().serviceDied(5L);
1790         mLooper.dispatchAll();
1791 
1792         assertFalse(mDut.isInitializationComplete());
1793         verify(mSupplicantHalDeathHandler).onDeath();
1794     }
1795 
1796     /**
1797      * Tests the handling of supplicant death notification.
1798      */
1799     @Test
testSupplicantDeathCallback()1800     public void testSupplicantDeathCallback() throws Exception {
1801         executeAndValidateInitializationSequence();
1802         assertNotNull(mSupplicantDeathCaptor.getValue());
1803         assertTrue(mDut.isInitializationComplete());
1804         assertTrue(mDut.registerDeathHandler(mSupplicantHalDeathHandler));
1805 
1806         mSupplicantDeathCaptor.getValue().serviceDied(mDeathRecipientCookieCaptor.getValue());
1807         mLooper.dispatchAll();
1808 
1809         assertFalse(mDut.isInitializationComplete());
1810         verify(mSupplicantHalDeathHandler).onDeath();
1811     }
1812 
1813     /**
1814      * Tests the handling of supplicant death notification.
1815      */
1816     @Test
testSupplicantStaleDeathCallback()1817     public void testSupplicantStaleDeathCallback() throws Exception {
1818         executeAndValidateInitializationSequence();
1819         assertNotNull(mSupplicantDeathCaptor.getValue());
1820         assertTrue(mDut.isInitializationComplete());
1821         assertTrue(mDut.registerDeathHandler(mSupplicantHalDeathHandler));
1822 
1823         mSupplicantDeathCaptor.getValue().serviceDied(mDeathRecipientCookieCaptor.getValue() - 1);
1824         mLooper.dispatchAll();
1825 
1826         assertTrue(mDut.isInitializationComplete());
1827         verify(mSupplicantHalDeathHandler, never()).onDeath();
1828     }
1829 
1830     /**
1831      * When wpa_supplicant is dead, we could end up getting a remote exception on a hwbinder call
1832      * and then the death notification.
1833      */
1834     @Test
testHandleRemoteExceptionAndDeathNotification()1835     public void testHandleRemoteExceptionAndDeathNotification() throws Exception {
1836         executeAndValidateInitializationSequence();
1837         assertTrue(mDut.registerDeathHandler(mSupplicantHalDeathHandler));
1838         assertTrue(mDut.isInitializationComplete());
1839 
1840         // Throw remote exception on hwbinder call.
1841         when(mISupplicantStaIfaceMock.setPowerSave(anyBoolean()))
1842                 .thenThrow(new RemoteException());
1843         assertFalse(mDut.setPowerSave(WLAN0_IFACE_NAME, true));
1844         verify(mISupplicantStaIfaceMock).setPowerSave(true);
1845 
1846         // Check that remote exception cleared all internal state.
1847         assertFalse(mDut.isInitializationComplete());
1848 
1849         // Ensure that further calls fail because the remote exception clears any state.
1850         assertFalse(mDut.setPowerSave(WLAN0_IFACE_NAME, true));
1851         //.. No call to ISupplicantStaIface object
1852 
1853         // Now trigger a death notification and ensure it's handled.
1854         assertNotNull(mSupplicantDeathCaptor.getValue());
1855         mSupplicantDeathCaptor.getValue().serviceDied(mDeathRecipientCookieCaptor.getValue());
1856         mLooper.dispatchAll();
1857 
1858         // External death notification fires only once!
1859         verify(mSupplicantHalDeathHandler).onDeath();
1860     }
1861 
1862     /**
1863      * Tests the setting of log level.
1864      */
1865     @Test
testSetLogLevel()1866     public void testSetLogLevel() throws Exception {
1867         when(mISupplicantMock.setDebugParams(anyInt(), anyBoolean(), anyBoolean()))
1868                 .thenReturn(mStatusSuccess);
1869 
1870         // Fail before initialization is performed.
1871         assertFalse(mDut.setLogLevel(true));
1872 
1873         executeAndValidateInitializationSequence();
1874 
1875         // This should work.
1876         assertTrue(mDut.setLogLevel(true));
1877         verify(mISupplicantMock)
1878                 .setDebugParams(eq(ISupplicant.DebugLevel.DEBUG), eq(false), eq(false));
1879     }
1880 
1881     /**
1882      * Tests the setting of log level with show key enabled.
1883      */
1884     @Test
testSetLogLevelWithShowKeyEnabled()1885     public void testSetLogLevelWithShowKeyEnabled() throws Exception {
1886         when(mWifiGlobals.getShowKeyVerboseLoggingModeEnabled())
1887                 .thenReturn(true);
1888         when(mISupplicantMock.setDebugParams(anyInt(), anyBoolean(), anyBoolean()))
1889                 .thenReturn(mStatusSuccess);
1890 
1891         executeAndValidateInitializationSequence();
1892 
1893         // This should work.
1894         assertTrue(mDut.setLogLevel(true));
1895         verify(mISupplicantMock)
1896                 .setDebugParams(eq(ISupplicant.DebugLevel.DEBUG), eq(false), eq(true));
1897     }
1898 
1899     /**
1900      * Tests that show key is not enabled when verbose logging is not enabled.
1901      */
1902     @Test
testVerboseLoggingDisabledWithShowKeyEnabled()1903     public void testVerboseLoggingDisabledWithShowKeyEnabled() throws Exception {
1904         when(mWifiGlobals.getShowKeyVerboseLoggingModeEnabled())
1905                 .thenReturn(true);
1906         when(mISupplicantMock.setDebugParams(anyInt(), anyBoolean(), anyBoolean()))
1907                 .thenReturn(mStatusSuccess);
1908 
1909         executeAndValidateInitializationSequence();
1910 
1911         // If verbose logging is not enabled, show key should not be enabled.
1912         assertTrue(mDut.setLogLevel(false));
1913         verify(mISupplicantMock, times(2))
1914                 .setDebugParams(eq(ISupplicant.DebugLevel.INFO), eq(false), eq(false));
1915     }
1916 
1917     /**
1918      * Tests the setting of concurrency priority.
1919      */
1920     @Test
testConcurrencyPriority()1921     public void testConcurrencyPriority() throws Exception {
1922         when(mISupplicantMock.setConcurrencyPriority(anyInt())).thenReturn(mStatusSuccess);
1923 
1924         // Fail before initialization is performed.
1925         assertFalse(mDut.setConcurrencyPriority(false));
1926 
1927         executeAndValidateInitializationSequence();
1928 
1929         // This should work.
1930         assertTrue(mDut.setConcurrencyPriority(false));
1931         verify(mISupplicantMock).setConcurrencyPriority(eq(IfaceType.P2P));
1932         assertTrue(mDut.setConcurrencyPriority(true));
1933         verify(mISupplicantMock).setConcurrencyPriority(eq(IfaceType.STA));
1934     }
1935 
1936     /**
1937      * Tests the start of wps registrar.
1938      */
1939     @Test
testStartWpsRegistrar()1940     public void testStartWpsRegistrar() throws Exception {
1941         when(mISupplicantStaIfaceMock.startWpsRegistrar(any(byte[].class), anyString()))
1942                 .thenReturn(mStatusSuccess);
1943 
1944         // Fail before initialization is performed.
1945         assertFalse(mDut.startWpsRegistrar(WLAN0_IFACE_NAME, null, null));
1946 
1947         executeAndValidateInitializationSequence();
1948 
1949         assertFalse(mDut.startWpsRegistrar(WLAN0_IFACE_NAME, null, null));
1950         verify(mISupplicantStaIfaceMock, never()).startWpsRegistrar(any(byte[].class), anyString());
1951 
1952         assertFalse(mDut.startWpsRegistrar(WLAN0_IFACE_NAME, new String(), "452233"));
1953         verify(mISupplicantStaIfaceMock, never()).startWpsRegistrar(any(byte[].class), anyString());
1954 
1955         assertTrue(mDut.startWpsRegistrar(WLAN0_IFACE_NAME, "45:23:12:12:12:98", "562535"));
1956         verify(mISupplicantStaIfaceMock).startWpsRegistrar(any(byte[].class), anyString());
1957     }
1958 
1959     /**
1960      * Tests the start of wps PBC.
1961      */
1962     @Test
testStartWpsPbc()1963     public void testStartWpsPbc() throws Exception {
1964         when(mISupplicantStaIfaceMock.startWpsPbc(any(byte[].class))).thenReturn(mStatusSuccess);
1965         String bssid = "45:23:12:12:12:98";
1966         byte[] bssidBytes = {0x45, 0x23, 0x12, 0x12, 0x12, (byte) 0x98};
1967         byte[] anyBssidBytes = {0, 0, 0, 0, 0, 0};
1968 
1969         // Fail before initialization is performed.
1970         assertFalse(mDut.startWpsPbc(WLAN0_IFACE_NAME, bssid));
1971         verify(mISupplicantStaIfaceMock, never()).startWpsPbc(any(byte[].class));
1972 
1973         executeAndValidateInitializationSequence();
1974 
1975         assertTrue(mDut.startWpsPbc(WLAN0_IFACE_NAME, bssid));
1976         verify(mISupplicantStaIfaceMock).startWpsPbc(eq(bssidBytes));
1977 
1978         assertTrue(mDut.startWpsPbc(WLAN0_IFACE_NAME, null));
1979         verify(mISupplicantStaIfaceMock).startWpsPbc(eq(anyBssidBytes));
1980     }
1981 
1982     /**
1983      * Tests country code setter
1984      */
1985     @Test
testSetCountryCode()1986     public void testSetCountryCode() throws Exception {
1987         when(mISupplicantStaIfaceMock.setCountryCode(any(byte[].class))).thenReturn(mStatusSuccess);
1988         String testCountryCode = "US";
1989 
1990         // Fail before initialization is performed.
1991         assertFalse(mDut.setCountryCode(WLAN0_IFACE_NAME, testCountryCode));
1992         verify(mISupplicantStaIfaceMock, never()).setCountryCode(any(byte[].class));
1993 
1994         executeAndValidateInitializationSequence();
1995 
1996         assertTrue(mDut.setCountryCode(WLAN0_IFACE_NAME, testCountryCode));
1997         verify(mISupplicantStaIfaceMock).setCountryCode(eq(testCountryCode.getBytes()));
1998 
1999         // Bad input values should fail the call.
2000         reset(mISupplicantStaIfaceMock);
2001 
2002         assertFalse(mDut.setCountryCode(WLAN0_IFACE_NAME, null));
2003         verify(mISupplicantStaIfaceMock, never()).setCountryCode(any(byte[].class));
2004 
2005         assertFalse(mDut.setCountryCode(WLAN0_IFACE_NAME, "U"));
2006         verify(mISupplicantStaIfaceMock, never()).setCountryCode(any(byte[].class));
2007     }
2008 
2009     /**
2010      * Tests the start daemon for V1_0 service.
2011      */
2012     @Test
testStartDaemonV1_0()2013     public void testStartDaemonV1_0() throws Exception {
2014         executeAndValidateInitializationSequence();
2015         verify(mFrameworkFacade).startSupplicant();
2016     }
2017 
2018     /**
2019      * Tests the start daemon for V1_1 service.
2020      */
2021     @Test
testStartDaemonV1_1()2022     public void testStartDaemonV1_1() throws Exception {
2023         setupMocksForHalV1_1();
2024 
2025         executeAndValidateInitializationSequenceV1_1(false, false);
2026         assertTrue(mDut.startDaemon());
2027         verify(mFrameworkFacade, never()).startSupplicant();
2028     }
2029 
2030     /**
2031      * Tests the terminate for V1_0 service.
2032      */
2033     @Test
testTerminateV1_0()2034     public void testTerminateV1_0() throws Exception {
2035         executeAndValidateInitializationSequence();
2036 
2037         mDut.terminate();
2038         mSupplicantDeathCaptor.getValue().serviceDied(mDeathRecipientCookieCaptor.getValue());
2039         mLooper.dispatchAll();
2040         verify(mFrameworkFacade).stopSupplicant();
2041 
2042         // Check that terminate cleared all internal state.
2043         assertFalse(mDut.isInitializationComplete());
2044     }
2045 
2046     /**
2047      * Tests the start daemon for V1_1 service.
2048      */
2049     @Test
testTerminateV1_1()2050     public void testTerminateV1_1() throws Exception {
2051         setupMocksForHalV1_1();
2052 
2053         executeAndValidateInitializationSequenceV1_1(false, false);
2054         mDut.terminate();
2055         mSupplicantDeathCaptor.getValue().serviceDied(mDeathRecipientCookieCaptor.getValue());
2056         mLooper.dispatchAll();
2057         verify(mFrameworkFacade, never()).stopSupplicant();
2058         verify(mISupplicantMockV11).terminate();
2059 
2060         // Check that terminate cleared all internal state.
2061         assertFalse(mDut.isInitializationComplete());
2062     }
2063 
2064     private class GetKeyMgmtCapabilitiesAnswer extends MockAnswerUtil.AnswerWithArguments {
2065         private int mKeyMgmtCapabilities;
2066 
GetKeyMgmtCapabilitiesAnswer(int keyMgmtCapabilities)2067         GetKeyMgmtCapabilitiesAnswer(int keyMgmtCapabilities) {
2068             mKeyMgmtCapabilities = keyMgmtCapabilities;
2069         }
2070 
answer(android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface .getKeyMgmtCapabilitiesCallback cb)2071         public void answer(android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface
2072                 .getKeyMgmtCapabilitiesCallback cb) {
2073             cb.onValues(mStatusSuccess, mKeyMgmtCapabilities);
2074         }
2075     }
2076 
2077     private class GetKeyMgmtCapabilities_1_3Answer extends MockAnswerUtil.AnswerWithArguments {
2078         private int mKeyMgmtCapabilities;
2079 
GetKeyMgmtCapabilities_1_3Answer(int keyMgmtCapabilities)2080         GetKeyMgmtCapabilities_1_3Answer(int keyMgmtCapabilities) {
2081             mKeyMgmtCapabilities = keyMgmtCapabilities;
2082         }
2083 
answer(android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface .getKeyMgmtCapabilities_1_3Callback cb)2084         public void answer(android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
2085                 .getKeyMgmtCapabilities_1_3Callback cb) {
2086             cb.onValues(mStatusSuccess, mKeyMgmtCapabilities);
2087         }
2088     }
2089 
2090     /**
2091      * Test get advanced capabilities API on old HAL, should return 0 (not supported)
2092      */
2093     @Test
testGetKeyMgmtCapabilitiesOldHal()2094     public void testGetKeyMgmtCapabilitiesOldHal() throws Exception {
2095         setupMocksForHalV1_1();
2096 
2097         executeAndValidateInitializationSequenceV1_1(false, false);
2098 
2099         assertTrue(mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME) == 0);
2100     }
2101 
2102     /**
2103      * Test WPA3-Personal SAE key may management support
2104      */
2105     @Test
testGetKeyMgmtCapabilitiesWpa3Sae()2106     public void testGetKeyMgmtCapabilitiesWpa3Sae() throws Exception {
2107         setupMocksForHalV1_2();
2108 
2109         executeAndValidateInitializationSequenceV1_2();
2110 
2111         doAnswer(new GetKeyMgmtCapabilitiesAnswer(android.hardware.wifi.supplicant.V1_2
2112                 .ISupplicantStaNetwork.KeyMgmtMask.SAE))
2113                 .when(mISupplicantStaIfaceMockV12).getKeyMgmtCapabilities(any(
2114                 android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface
2115                         .getKeyMgmtCapabilitiesCallback.class));
2116 
2117         assertEquals(WIFI_FEATURE_WPA3_SAE, mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME));
2118     }
2119 
2120     /**
2121      * Test WPA3-Enterprise Suite-B-192 key may management support
2122      */
2123     @Test
testGetKeyMgmtCapabilitiesWpa3SuiteB()2124     public void testGetKeyMgmtCapabilitiesWpa3SuiteB() throws Exception {
2125         setupMocksForHalV1_2();
2126 
2127         executeAndValidateInitializationSequenceV1_2();
2128 
2129         doAnswer(new GetKeyMgmtCapabilitiesAnswer(android.hardware.wifi.supplicant.V1_2
2130                 .ISupplicantStaNetwork.KeyMgmtMask.SUITE_B_192))
2131                 .when(mISupplicantStaIfaceMockV12).getKeyMgmtCapabilities(any(
2132                 android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface
2133                         .getKeyMgmtCapabilitiesCallback.class));
2134 
2135         assertEquals(WIFI_FEATURE_WPA3_SUITE_B,
2136                 mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME));
2137     }
2138 
2139     /**
2140      * Test Enhanced Open (OWE) key may management support
2141      */
2142     @Test
testGetKeyMgmtCapabilitiesOwe()2143     public void testGetKeyMgmtCapabilitiesOwe() throws Exception {
2144         setupMocksForHalV1_2();
2145 
2146         executeAndValidateInitializationSequenceV1_2();
2147 
2148         doAnswer(new GetKeyMgmtCapabilitiesAnswer(android.hardware.wifi.supplicant.V1_2
2149                 .ISupplicantStaNetwork.KeyMgmtMask.OWE))
2150                 .when(mISupplicantStaIfaceMockV12).getKeyMgmtCapabilities(any(
2151                 android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface
2152                         .getKeyMgmtCapabilitiesCallback.class));
2153 
2154         assertEquals(WIFI_FEATURE_OWE, mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME));
2155     }
2156 
2157     /**
2158      * Test Enhanced Open (OWE) and SAE key may management support
2159      */
2160     @Test
testGetKeyMgmtCapabilitiesOweAndSae()2161     public void testGetKeyMgmtCapabilitiesOweAndSae() throws Exception {
2162         setupMocksForHalV1_2();
2163 
2164         executeAndValidateInitializationSequenceV1_2();
2165 
2166         doAnswer(new GetKeyMgmtCapabilitiesAnswer(android.hardware.wifi.supplicant.V1_2
2167                 .ISupplicantStaNetwork.KeyMgmtMask.OWE
2168                 | android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask.SAE))
2169                 .when(mISupplicantStaIfaceMockV12).getKeyMgmtCapabilities(any(
2170                 android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface
2171                         .getKeyMgmtCapabilitiesCallback.class));
2172 
2173         assertEquals(WIFI_FEATURE_OWE | WIFI_FEATURE_WPA3_SAE,
2174                 mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME));
2175     }
2176 
2177     /**
2178      * Test Easy Connect (DPP) key may management support
2179      */
2180     @Test
testGetKeyMgmtCapabilitiesDpp()2181     public void testGetKeyMgmtCapabilitiesDpp() throws Exception {
2182         setupMocksForHalV1_2();
2183 
2184         executeAndValidateInitializationSequenceV1_2();
2185 
2186         doAnswer(new GetKeyMgmtCapabilitiesAnswer(android.hardware.wifi.supplicant.V1_2
2187                 .ISupplicantStaNetwork.KeyMgmtMask.DPP))
2188                 .when(mISupplicantStaIfaceMockV12).getKeyMgmtCapabilities(any(
2189                 android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface
2190                         .getKeyMgmtCapabilitiesCallback.class));
2191 
2192         assertEquals(WIFI_FEATURE_DPP, mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME));
2193     }
2194 
2195     /**
2196      * Test Easy Connect (DPP) Enrollee Responder mode supported on supplicant HAL V1_4
2197      */
2198     @Test
testGetDppEnrolleeResponderModeSupport()2199     public void testGetDppEnrolleeResponderModeSupport() throws Exception {
2200         setupMocksForHalV1_4();
2201         executeAndValidateInitializationSequenceV1_4();
2202 
2203         doAnswer(new GetKeyMgmtCapabilities_1_3Answer(android.hardware.wifi.supplicant.V1_2
2204                 .ISupplicantStaNetwork.KeyMgmtMask.DPP))
2205                 .when(mISupplicantStaIfaceMockV13).getKeyMgmtCapabilities_1_3(any(
2206                 android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
2207                         .getKeyMgmtCapabilities_1_3Callback.class));
2208 
2209         assertTrue((WIFI_FEATURE_DPP_ENROLLEE_RESPONDER
2210                 & mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME))
2211                 == WIFI_FEATURE_DPP_ENROLLEE_RESPONDER);
2212     }
2213 
2214     /**
2215      * Test Easy Connect (DPP) Enrollee Responder mode is not supported on supplicant HAL
2216      * V1_3 or less.
2217      */
2218     @Test
testDppEnrolleeResponderModeNotSupportedOnHalV1_3OrLess()2219     public void testDppEnrolleeResponderModeNotSupportedOnHalV1_3OrLess() throws Exception {
2220         setupMocksForHalV1_3();
2221         executeAndValidateInitializationSequenceV1_3();
2222 
2223         doAnswer(new GetKeyMgmtCapabilities_1_3Answer(android.hardware.wifi.supplicant.V1_2
2224                 .ISupplicantStaNetwork.KeyMgmtMask.DPP))
2225                 .when(mISupplicantStaIfaceMockV13).getKeyMgmtCapabilities_1_3(any(
2226                 android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
2227                         .getKeyMgmtCapabilities_1_3Callback.class));
2228 
2229         assertFalse((WIFI_FEATURE_DPP_ENROLLEE_RESPONDER
2230                 & mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME))
2231                 == WIFI_FEATURE_DPP_ENROLLEE_RESPONDER);
2232     }
2233 
2234     /**
2235      * Test WAPI key may management support
2236      */
2237     @Test
testGetKeyMgmtCapabilitiesWapi()2238     public void testGetKeyMgmtCapabilitiesWapi() throws Exception {
2239         setupMocksForHalV1_3();
2240 
2241         executeAndValidateInitializationSequenceV1_3();
2242 
2243         doAnswer(new GetKeyMgmtCapabilities_1_3Answer(android.hardware.wifi.supplicant.V1_3
2244                 .ISupplicantStaNetwork.KeyMgmtMask.WAPI_PSK))
2245                 .when(mISupplicantStaIfaceMockV13).getKeyMgmtCapabilities_1_3(any(
2246                 android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
2247                         .getKeyMgmtCapabilities_1_3Callback.class));
2248 
2249         assertEquals(WIFI_FEATURE_WAPI, mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME));
2250     }
2251 
2252     /**
2253      * Test FILS SHA256 key management support.
2254      */
2255     @Test
testGetKeyMgmtCapabilitiesFilsSha256()2256     public void testGetKeyMgmtCapabilitiesFilsSha256() throws Exception {
2257         setupMocksForHalV1_3();
2258 
2259         executeAndValidateInitializationSequenceV1_3();
2260 
2261         doAnswer(new GetKeyMgmtCapabilities_1_3Answer(android.hardware.wifi.supplicant.V1_3
2262                 .ISupplicantStaNetwork.KeyMgmtMask.FILS_SHA256))
2263                 .when(mISupplicantStaIfaceMockV13).getKeyMgmtCapabilities_1_3(any(
2264                 android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
2265                         .getKeyMgmtCapabilities_1_3Callback.class));
2266 
2267         assertEquals(WIFI_FEATURE_FILS_SHA256,
2268                 mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME));
2269     }
2270 
2271     /**
2272      * Test FILS SHA384 key management support.
2273      */
2274     @Test
testGetKeyMgmtCapabilitiesFilsSha384()2275     public void testGetKeyMgmtCapabilitiesFilsSha384() throws Exception {
2276         setupMocksForHalV1_3();
2277 
2278         executeAndValidateInitializationSequenceV1_3();
2279 
2280         doAnswer(new GetKeyMgmtCapabilities_1_3Answer(android.hardware.wifi.supplicant.V1_3
2281                 .ISupplicantStaNetwork.KeyMgmtMask.FILS_SHA384))
2282                 .when(mISupplicantStaIfaceMockV13).getKeyMgmtCapabilities_1_3(any(
2283                 android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
2284                         .getKeyMgmtCapabilities_1_3Callback.class));
2285 
2286         assertEquals(WIFI_FEATURE_FILS_SHA384,
2287                 mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME));
2288     }
2289 
2290     /**
2291      * Test Easy Connect (DPP) calls return failure if hal version is less than 1_2
2292      */
2293     @Test
testDppFailsWithOldHal()2294     public void testDppFailsWithOldHal() throws Exception {
2295         assertEquals(-1, mDut.addDppPeerUri(WLAN0_IFACE_NAME, "/blah"));
2296         assertFalse(mDut.removeDppUri(WLAN0_IFACE_NAME, 0));
2297         assertFalse(mDut.stopDppInitiator(WLAN0_IFACE_NAME));
2298         assertFalse(mDut.startDppConfiguratorInitiator(WLAN0_IFACE_NAME,
2299                 1, 2, "Buckle", "My", "Shoe",
2300                 3, 4, null));
2301         assertFalse(mDut.startDppEnrolleeInitiator(WLAN0_IFACE_NAME, 3, 14));
2302         WifiNative.DppBootstrapQrCodeInfo bootstrapInfo =
2303                 mDut.generateDppBootstrapInfoForResponder(WLAN0_IFACE_NAME, "00:11:22:33:44:55",
2304                         "PRODUCT_INFO", SupplicantStaIfaceHal.DppCurve.PRIME256V1);
2305         assertEquals(-1, bootstrapInfo.bootstrapId);
2306         assertFalse(mDut.startDppEnrolleeResponder(WLAN0_IFACE_NAME, 6));
2307     }
2308 
2309     /**
2310      * Test adding PMK cache entry to the supplicant.
2311      */
2312     @Test
testSetPmkSuccess()2313     public void testSetPmkSuccess() throws Exception {
2314         int testFrameworkNetworkId = 9;
2315         WifiConfiguration config = new WifiConfiguration();
2316         config.networkId = testFrameworkNetworkId;
2317         config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
2318         config.getNetworkSelectionStatus().setCandidateSecurityParams(
2319                 SecurityParams.createSecurityParamsBySecurityType(
2320                         WifiConfiguration.SECURITY_TYPE_EAP));
2321         ArrayList<Byte> pmkCacheData = NativeUtil.byteArrayToArrayList("deadbeef".getBytes());
2322 
2323         setupMocksForHalV1_3();
2324         setupMocksForPmkCache(pmkCacheData, true);
2325         setupMocksForConnectSequence(false);
2326 
2327         executeAndValidateInitializationSequenceV1_3();
2328         assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, config));
2329 
2330         verify(mPmkCacheManager).get(eq(testFrameworkNetworkId));
2331         verify(mSupplicantStaNetworkMock).setPmkCache(eq(pmkCacheData));
2332         verify(mISupplicantStaIfaceCallbackV13)
2333                 .onPmkCacheAdded(eq(PMK_CACHE_EXPIRATION_IN_SEC), eq(pmkCacheData));
2334     }
2335 
2336     /**
2337      * Test adding PMK cache entry to the supplicant when SAE is selected
2338      * for a PSK/SAE configuration.
2339      */
2340     @Test
testSetPmkWhenSaeIsSelected()2341     public void testSetPmkWhenSaeIsSelected() throws Exception {
2342         int testFrameworkNetworkId = 9;
2343         WifiConfiguration config = WifiConfigurationTestUtil.createPskSaeNetwork();
2344         config.networkId = testFrameworkNetworkId;
2345         config.getNetworkSelectionStatus().setCandidateSecurityParams(
2346                 SecurityParams.createSecurityParamsBySecurityType(
2347                         WifiConfiguration.SECURITY_TYPE_SAE));
2348         ArrayList<Byte> pmkCacheData = NativeUtil.byteArrayToArrayList("deadbeef".getBytes());
2349 
2350         setupMocksForHalV1_3();
2351         setupMocksForPmkCache(pmkCacheData, true);
2352         setupMocksForConnectSequence(false);
2353 
2354         executeAndValidateInitializationSequenceV1_3();
2355         assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, config));
2356 
2357         verify(mPmkCacheManager).get(eq(testFrameworkNetworkId));
2358         verify(mSupplicantStaNetworkMock).setPmkCache(eq(pmkCacheData));
2359         verify(mISupplicantStaIfaceCallbackV13)
2360                 .onPmkCacheAdded(eq(PMK_CACHE_EXPIRATION_IN_SEC), eq(pmkCacheData));
2361     }
2362 
2363     /**
2364      * Test PMK cache entry is not added to the supplicant when PSK is selected
2365      * for a PSK/SAE configuration.
2366      */
2367     @Test
testAddPmkEntryNotCalledIfPskIsSelected()2368     public void testAddPmkEntryNotCalledIfPskIsSelected() throws Exception {
2369         int testFrameworkNetworkId = 9;
2370 
2371         WifiConfiguration config = WifiConfigurationTestUtil.createPskSaeNetwork();
2372         config.networkId = testFrameworkNetworkId;
2373         config.getNetworkSelectionStatus().setCandidateSecurityParams(
2374                 SecurityParams.createSecurityParamsBySecurityType(
2375                         WifiConfiguration.SECURITY_TYPE_PSK));
2376 
2377         setupMocksForHalV1_3();
2378         setupMocksForPmkCache(true);
2379         setupMocksForConnectSequence(false);
2380 
2381         executeAndValidateInitializationSequenceV1_3();
2382         assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, config));
2383 
2384         verify(mSupplicantStaNetworkMock, never()).setPmkCache(any());
2385         verify(mISupplicantStaIfaceCallbackV13, never())
2386                 .onPmkCacheAdded(anyLong(), any());
2387     }
2388 
2389     /**
2390      * Test PMK cache entry is not added to the supplicant if no security
2391      * params is selected.
2392      */
2393     @Test
testAddPmkEntryNotCalledIfNoSecurityParamsIsSelected()2394     public void testAddPmkEntryNotCalledIfNoSecurityParamsIsSelected() throws Exception {
2395         int testFrameworkNetworkId = 9;
2396 
2397         WifiConfiguration config = WifiConfigurationTestUtil.createPskSaeNetwork();
2398         config.networkId = testFrameworkNetworkId;
2399         config.getNetworkSelectionStatus().setCandidateSecurityParams(null);
2400 
2401         setupMocksForHalV1_3();
2402         setupMocksForPmkCache(true);
2403         setupMocksForConnectSequence(false);
2404 
2405         executeAndValidateInitializationSequenceV1_3();
2406         assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, config));
2407 
2408         verify(mSupplicantStaNetworkMock, never()).setPmkCache(any());
2409         verify(mISupplicantStaIfaceCallbackV13, never())
2410                 .onPmkCacheAdded(anyLong(), any());
2411     }
2412 
2413     /**
2414      * Test adding PMK cache entry is not called if there is no
2415      * valid PMK cache for a corresponding configuration.
2416      */
2417     @Test
testAddPmkEntryNotCalledIfNoPmkCache()2418     public void testAddPmkEntryNotCalledIfNoPmkCache() throws Exception {
2419         int testFrameworkNetworkId = 9;
2420         WifiConfiguration config = new WifiConfiguration();
2421         config.networkId = testFrameworkNetworkId;
2422         config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
2423 
2424         setupMocksForHalV1_3();
2425         setupMocksForPmkCache(null, true);
2426         setupMocksForConnectSequence(false);
2427         executeAndValidateInitializationSequenceV1_3();
2428         assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, config));
2429 
2430         verify(mSupplicantStaNetworkMock, never()).setPmkCache(any(ArrayList.class));
2431         verify(mISupplicantStaIfaceCallbackV13, never()).onPmkCacheAdded(
2432                 anyLong(), any(ArrayList.class));
2433     }
2434 
2435     /**
2436      * Test adding PMK cache entry returns faliure if this is a psk network.
2437      */
2438     @Test
testAddPmkEntryIsOmittedWithPskNetwork()2439     public void testAddPmkEntryIsOmittedWithPskNetwork() throws Exception {
2440         int testFrameworkNetworkId = 9;
2441         WifiConfiguration config = new WifiConfiguration();
2442         config.networkId = testFrameworkNetworkId;
2443         config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
2444 
2445         setupMocksForHalV1_3();
2446         setupMocksForPmkCache(true);
2447         setupMocksForConnectSequence(false);
2448         executeAndValidateInitializationSequenceV1_3();
2449         assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, config));
2450 
2451         verify(mPmkCacheManager, never()).add(any(), anyInt(), any(), anyLong(), any());
2452         verify(mSupplicantStaNetworkMock, never()).setPmkCache(any(ArrayList.class));
2453         verify(mISupplicantStaIfaceCallbackV13, never()).onPmkCacheAdded(
2454                 anyLong(), any(ArrayList.class));
2455     }
2456 
2457     /**
2458      * Test adding PMK cache entry returns faliure if HAL version is less than 1_3
2459      */
2460     @Test
testAddPmkEntryIsOmittedWithOldHal()2461     public void testAddPmkEntryIsOmittedWithOldHal() throws Exception {
2462         int testFrameworkNetworkId = 9;
2463         WifiConfiguration config = new WifiConfiguration();
2464         config.networkId = testFrameworkNetworkId;
2465         config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
2466         config.getNetworkSelectionStatus().setCandidateSecurityParams(
2467                 SecurityParams.createSecurityParamsBySecurityType(
2468                         WifiConfiguration.SECURITY_TYPE_EAP));
2469         ArrayList<Byte> pmkCacheData = NativeUtil.byteArrayToArrayList("deadbeef".getBytes());
2470         setupMocksForPmkCache(pmkCacheData, false);
2471 
2472         setupMocksForConnectSequence(false);
2473         executeAndValidateInitializationSequence();
2474         assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, config));
2475 
2476         verify(mSupplicantStaNetworkMock).setPmkCache(eq(pmkCacheData));
2477         assertNull(mISupplicantStaIfaceCallbackV13);
2478     }
2479 
2480     /**
2481      * Tests the handling of assoc reject for PMK cache
2482      */
2483     @Test
testRemovePmkEntryOnReceivingAssocReject()2484     public void testRemovePmkEntryOnReceivingAssocReject() throws Exception {
2485         int testFrameworkNetworkId = 9;
2486         WifiConfiguration config = new WifiConfiguration();
2487         config.networkId = testFrameworkNetworkId;
2488         config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
2489 
2490         setupMocksForHalV1_3();
2491         setupMocksForPmkCache(true);
2492         setupMocksForConnectSequence(false);
2493 
2494         executeAndValidateInitializationSequenceV1_3();
2495         assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, config));
2496         mISupplicantStaIfaceCallbackV13.onStateChanged(
2497                 ISupplicantStaIfaceCallback.State.ASSOCIATING,
2498                 NativeUtil.macAddressToByteArray(BSSID),
2499                 SUPPLICANT_NETWORK_ID,
2500                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
2501         int statusCode = 7;
2502         mISupplicantStaIfaceCallbackV13.onAssociationRejected(
2503                 NativeUtil.macAddressToByteArray(BSSID), statusCode, false);
2504         verify(mPmkCacheManager).remove(eq(testFrameworkNetworkId));
2505     }
2506 
2507     /**
2508      * Test getConnectionCapabilities
2509      * Should fail if running HAL lower than V1_3
2510      */
2511     @Test
testGetConnectionCapabilitiesV1_2()2512     public void testGetConnectionCapabilitiesV1_2() throws Exception {
2513         setupMocksForHalV1_2();
2514         executeAndValidateInitializationSequenceV1_2();
2515         WifiNative.ConnectionCapabilities cap = mDut.getConnectionCapabilities(WLAN0_IFACE_NAME);
2516         assertEquals(ScanResult.WIFI_STANDARD_UNKNOWN, cap.wifiStandard);
2517     }
2518 
2519     private class GetConnCapabilitiesAnswerV1_3 extends MockAnswerUtil.AnswerWithArguments {
2520         private android.hardware.wifi.supplicant.V1_3.ConnectionCapabilities mConnCapabilities;
2521 
GetConnCapabilitiesAnswerV1_3(int wifiTechnology, int channelBandwidth, int maxNumberTxSpatialStreams, int maxNumberRxSpatialStreams)2522         GetConnCapabilitiesAnswerV1_3(int wifiTechnology, int channelBandwidth,
2523                 int maxNumberTxSpatialStreams, int maxNumberRxSpatialStreams) {
2524             mConnCapabilities = new android.hardware.wifi.supplicant.V1_3.ConnectionCapabilities();
2525             mConnCapabilities.technology = wifiTechnology;
2526             mConnCapabilities.channelBandwidth = channelBandwidth;
2527             mConnCapabilities.maxNumberTxSpatialStreams = maxNumberTxSpatialStreams;
2528             mConnCapabilities.maxNumberRxSpatialStreams = maxNumberRxSpatialStreams;
2529         }
2530 
answer(android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface .getConnectionCapabilitiesCallback cb)2531         public void answer(android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
2532                 .getConnectionCapabilitiesCallback cb) {
2533             cb.onValues(mStatusSuccess, mConnCapabilities);
2534         }
2535     }
2536 
2537     private class GetConnCapabilitiesAnswerV1_4 extends MockAnswerUtil.AnswerWithArguments {
2538         private ConnectionCapabilities mConnCapabilities;
2539 
GetConnCapabilitiesAnswerV1_4(int wifiTechnology, int legacyMode, int channelBandwidth, int maxNumberTxSpatialStreams, int maxNumberRxSpatialStreams)2540         GetConnCapabilitiesAnswerV1_4(int wifiTechnology, int legacyMode, int channelBandwidth,
2541                 int maxNumberTxSpatialStreams, int maxNumberRxSpatialStreams) {
2542             mConnCapabilities = new ConnectionCapabilities();
2543             mConnCapabilities.V1_3.technology = wifiTechnology;
2544             mConnCapabilities.legacyMode = legacyMode;
2545             mConnCapabilities.V1_3.channelBandwidth = channelBandwidth;
2546             mConnCapabilities.V1_3.maxNumberTxSpatialStreams = maxNumberTxSpatialStreams;
2547             mConnCapabilities.V1_3.maxNumberRxSpatialStreams = maxNumberRxSpatialStreams;
2548         }
2549 
answer(android.hardware.wifi.supplicant.V1_4.ISupplicantStaIface .getConnectionCapabilities_1_4Callback cb)2550         public void answer(android.hardware.wifi.supplicant.V1_4.ISupplicantStaIface
2551                 .getConnectionCapabilities_1_4Callback cb) {
2552             cb.onValues(mStatusSuccessV14, mConnCapabilities);
2553         }
2554     }
2555 
2556     /**
2557      * Test getConnectionCapabilities if running with HAL V1_3
2558      */
2559     @Test
testGetConnectionCapabilitiesV1_3()2560     public void testGetConnectionCapabilitiesV1_3() throws Exception {
2561         setupMocksForHalV1_3();
2562 
2563         executeAndValidateInitializationSequenceV1_3();
2564         int testWifiTechnologyHal = WifiTechnology.VHT;
2565         int testWifiStandardWifiInfo = ScanResult.WIFI_STANDARD_11AC;
2566         int testChannelBandwidthHal = WifiChannelWidthInMhz.WIDTH_80P80;
2567         int testChannelBandwidth = ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ;
2568         int maxNumberTxSpatialStreams = 3;
2569         int maxNumberRxSpatialStreams = 1;
2570 
2571         doAnswer(new GetConnCapabilitiesAnswerV1_3(testWifiTechnologyHal, testChannelBandwidthHal,
2572                 maxNumberTxSpatialStreams, maxNumberRxSpatialStreams))
2573                 .when(mISupplicantStaIfaceMockV13).getConnectionCapabilities(any(
2574                 android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
2575                         .getConnectionCapabilitiesCallback.class));
2576         WifiNative.ConnectionCapabilities cap = mDut.getConnectionCapabilities(WLAN0_IFACE_NAME);
2577         assertEquals(testWifiStandardWifiInfo, cap.wifiStandard);
2578         assertEquals(false, cap.is11bMode);
2579         assertEquals(testChannelBandwidth, cap.channelBandwidth);
2580         assertEquals(maxNumberTxSpatialStreams, cap.maxNumberTxSpatialStreams);
2581         assertEquals(maxNumberRxSpatialStreams, cap.maxNumberRxSpatialStreams);
2582     }
2583 
2584     /**
2585      * Test getConnectionCapabilities if running with HAL V1_4
2586      */
2587     @Test
testGetConnectionCapabilitiesV1_4()2588     public void testGetConnectionCapabilitiesV1_4() throws Exception {
2589         setupMocksForHalV1_4();
2590 
2591         executeAndValidateInitializationSequenceV1_4();
2592         int testWifiTechnologyHal = WifiTechnology.LEGACY;
2593         int testLegacyMode = LegacyMode.B_MODE;
2594         int testWifiStandardWifiInfo = ScanResult.WIFI_STANDARD_LEGACY;
2595         int testChannelBandwidthHal = WifiChannelWidthInMhz.WIDTH_20;
2596         int testChannelBandwidth = ScanResult.CHANNEL_WIDTH_20MHZ;
2597         int maxNumberTxSpatialStreams = 1;
2598         int maxNumberRxSpatialStreams = 1;
2599 
2600         doAnswer(new GetConnCapabilitiesAnswerV1_4(testWifiTechnologyHal, testLegacyMode,
2601                 testChannelBandwidthHal, maxNumberTxSpatialStreams, maxNumberRxSpatialStreams))
2602                 .when(mISupplicantStaIfaceMockV14).getConnectionCapabilities_1_4(any(
2603                 android.hardware.wifi.supplicant.V1_4.ISupplicantStaIface
2604                         .getConnectionCapabilities_1_4Callback.class));
2605         WifiNative.ConnectionCapabilities cap = mDut.getConnectionCapabilities(WLAN0_IFACE_NAME);
2606         assertEquals(testWifiStandardWifiInfo, cap.wifiStandard);
2607         assertEquals(true, cap.is11bMode);
2608         assertEquals(testChannelBandwidth, cap.channelBandwidth);
2609         assertEquals(maxNumberTxSpatialStreams, cap.maxNumberTxSpatialStreams);
2610         assertEquals(maxNumberRxSpatialStreams, cap.maxNumberRxSpatialStreams);
2611     }
2612 
createTestWifiConfiguration()2613     private WifiConfiguration createTestWifiConfiguration() {
2614         WifiConfiguration config = new WifiConfiguration();
2615         config.networkId = SUPPLICANT_NETWORK_ID;
2616         return config;
2617     }
2618 
executeAndValidateHs20DeauthImminentCallback(boolean isEss)2619     private void executeAndValidateHs20DeauthImminentCallback(boolean isEss) throws Exception {
2620         executeAndValidateInitializationSequence();
2621         assertNotNull(mISupplicantStaIfaceCallback);
2622 
2623         byte[] bssid = NativeUtil.macAddressToByteArray(BSSID);
2624         int reasonCode = isEss ? WnmData.ESS : WnmData.ESS + 1;
2625         int reauthDelay = 5;
2626         mISupplicantStaIfaceCallback.onHs20DeauthImminentNotice(
2627                 bssid, reasonCode, reauthDelay, HS20_URL);
2628 
2629         ArgumentCaptor<WnmData> wnmDataCaptor = ArgumentCaptor.forClass(WnmData.class);
2630         verify(mWifiMonitor).broadcastWnmEvent(eq(WLAN0_IFACE_NAME), wnmDataCaptor.capture());
2631         assertEquals(
2632                 ByteBufferReader.readInteger(
2633                         ByteBuffer.wrap(bssid), ByteOrder.BIG_ENDIAN, bssid.length),
2634                 wnmDataCaptor.getValue().getBssid());
2635         assertEquals(isEss, wnmDataCaptor.getValue().isEss());
2636         assertEquals(reauthDelay, wnmDataCaptor.getValue().getDelay());
2637         assertEquals(HS20_URL, wnmDataCaptor.getValue().getUrl());
2638     }
2639 
executeAndValidateHs20TermsAndConditionsCallback()2640     private void executeAndValidateHs20TermsAndConditionsCallback() throws Exception {
2641         setupMocksForHalV1_4();
2642         executeAndValidateInitializationSequenceV1_4();
2643         assertNotNull(mISupplicantStaIfaceCallbackV14);
2644 
2645         byte[] bssid = NativeUtil.macAddressToByteArray(BSSID);
2646         mISupplicantStaIfaceCallbackV14.onHs20TermsAndConditionsAcceptanceRequestedNotification(
2647                 bssid, HS20_URL);
2648 
2649         //TODO: Add test logic once framework handling is implemented
2650     }
2651 
executeAndValidateInitializationSequence()2652     private void executeAndValidateInitializationSequence() throws  Exception {
2653         executeAndValidateInitializationSequence(false, false, false, false);
2654     }
2655 
2656     /**
2657      * Calls.initialize(), mocking various call back answers and verifying flow, asserting for the
2658      * expected result. Verifies if ISupplicantStaIface manager is initialized or reset.
2659      * Each of the arguments will cause a different failure mode when set true.
2660      */
executeAndValidateInitializationSequence(boolean causeRemoteException, boolean getZeroInterfaces, boolean getNullInterface, boolean causeCallbackRegFailure)2661     private void executeAndValidateInitializationSequence(boolean causeRemoteException,
2662                                                           boolean getZeroInterfaces,
2663                                                           boolean getNullInterface,
2664                                                           boolean causeCallbackRegFailure)
2665             throws Exception {
2666         boolean shouldSucceed =
2667                 !causeRemoteException && !getZeroInterfaces && !getNullInterface
2668                         && !causeCallbackRegFailure;
2669         // Setup callback mock answers
2670         ArrayList<ISupplicant.IfaceInfo> interfaces;
2671         if (getZeroInterfaces) {
2672             interfaces = new ArrayList<>();
2673         } else {
2674             interfaces = mIfaceInfoList;
2675         }
2676         doAnswer(new GetListInterfacesAnswer(interfaces)).when(mISupplicantMock)
2677                 .listInterfaces(any(ISupplicant.listInterfacesCallback.class));
2678         if (causeRemoteException) {
2679             doThrow(new RemoteException("Some error!!!"))
2680                     .when(mISupplicantMock).getInterface(any(ISupplicant.IfaceInfo.class),
2681                     any(ISupplicant.getInterfaceCallback.class));
2682         } else {
2683             doAnswer(new GetGetInterfaceAnswer(getNullInterface))
2684                     .when(mISupplicantMock).getInterface(any(ISupplicant.IfaceInfo.class),
2685                     any(ISupplicant.getInterfaceCallback.class));
2686         }
2687         /** Callback registration */
2688         if (causeCallbackRegFailure) {
2689             doAnswer(new MockAnswerUtil.AnswerWithArguments() {
2690                 public SupplicantStatus answer(ISupplicantStaIfaceCallback cb)
2691                         throws RemoteException {
2692                     return mStatusFailure;
2693                 }
2694             }).when(mISupplicantStaIfaceMock)
2695                     .registerCallback(any(ISupplicantStaIfaceCallback.class));
2696         } else {
2697             doAnswer(new MockAnswerUtil.AnswerWithArguments() {
2698                 public SupplicantStatus answer(ISupplicantStaIfaceCallback cb)
2699                         throws RemoteException {
2700                     mISupplicantStaIfaceCallback = cb;
2701                     return mStatusSuccess;
2702                 }
2703             }).when(mISupplicantStaIfaceMock)
2704                     .registerCallback(any(ISupplicantStaIfaceCallback.class));
2705         }
2706 
2707         mInOrder = inOrder(mServiceManagerMock, mISupplicantMock, mISupplicantStaIfaceMock,
2708                 mWifiMonitor);
2709         // Initialize SupplicantStaIfaceHal, should call serviceManager.registerForNotifications
2710         assertTrue(mDut.initialize());
2711         assertTrue(mDut.startDaemon());
2712         // verify: service manager initialization sequence
2713         mInOrder.verify(mServiceManagerMock).linkToDeath(mServiceManagerDeathCaptor.capture(),
2714                 anyLong());
2715         mInOrder.verify(mServiceManagerMock).registerForNotifications(
2716                 eq(ISupplicant.kInterfaceName), eq(""), mServiceNotificationCaptor.capture());
2717         // act: cause the onRegistration(...) callback to execute
2718         mServiceNotificationCaptor.getValue().onRegistration(ISupplicant.kInterfaceName, "", true);
2719         assertTrue(mDut.isInitializationComplete());
2720         assertEquals(shouldSucceed, mDut.setupIface(WLAN0_IFACE_NAME));
2721         mInOrder.verify(mISupplicantMock).linkToDeath(mSupplicantDeathCaptor.capture(),
2722                 mDeathRecipientCookieCaptor.capture());
2723         // verify: listInterfaces is called
2724         mInOrder.verify(mISupplicantMock).listInterfaces(
2725                 any(ISupplicant.listInterfacesCallback.class));
2726         if (!getZeroInterfaces) {
2727             mInOrder.verify(mISupplicantMock)
2728                     .getInterface(any(ISupplicant.IfaceInfo.class),
2729                             any(ISupplicant.getInterfaceCallback.class));
2730         }
2731         if (!causeRemoteException && !getZeroInterfaces && !getNullInterface) {
2732             mInOrder.verify(mISupplicantStaIfaceMock)
2733                     .registerCallback(any(ISupplicantStaIfaceCallback.class));
2734         }
2735     }
2736 
2737     /**
2738      * Calls.initialize(), mocking various call back answers and verifying flow, asserting for the
2739      * expected result. Verifies if ISupplicantStaIface manager is initialized or reset.
2740      * Each of the arguments will cause a different failure mode when set true.
2741      */
executeAndValidateInitializationSequenceV1_1(boolean causeRemoteException, boolean getNullInterface)2742     private void executeAndValidateInitializationSequenceV1_1(boolean causeRemoteException,
2743                                                                boolean getNullInterface)
2744             throws Exception {
2745         boolean shouldSucceed = !causeRemoteException && !getNullInterface;
2746         // Setup callback mock answers
2747         if (causeRemoteException) {
2748             doThrow(new RemoteException("Some error!!!"))
2749                     .when(mISupplicantMockV11).addInterface(any(ISupplicant.IfaceInfo.class),
2750                     any(android.hardware.wifi.supplicant.V1_1.ISupplicant
2751                             .addInterfaceCallback.class));
2752         } else {
2753             doAnswer(new GetAddInterfaceAnswer(getNullInterface))
2754                     .when(mISupplicantMockV11).addInterface(any(ISupplicant.IfaceInfo.class),
2755                     any(android.hardware.wifi.supplicant.V1_1.ISupplicant
2756                             .addInterfaceCallback.class));
2757         }
2758         /** Callback registration */
2759         doAnswer(new MockAnswerUtil.AnswerWithArguments() {
2760             public SupplicantStatus answer(
2761                     android.hardware.wifi.supplicant.V1_1.ISupplicantStaIfaceCallback cb)
2762                     throws RemoteException {
2763                 mISupplicantStaIfaceCallbackV11 = cb;
2764                 return mStatusSuccess;
2765             }
2766         }).when(mISupplicantStaIfaceMockV11)
2767                 .registerCallback_1_1(
2768                 any(android.hardware.wifi.supplicant.V1_1.ISupplicantStaIfaceCallback.class));
2769 
2770         mInOrder = inOrder(mServiceManagerMock, mISupplicantMock, mISupplicantMockV11,
2771                 mISupplicantStaIfaceMockV11, mWifiMonitor);
2772         // Initialize SupplicantStaIfaceHal, should call serviceManager.registerForNotifications
2773         assertTrue(mDut.initialize());
2774         assertTrue(mDut.startDaemon());
2775         // verify: service manager initialization sequence
2776         mInOrder.verify(mServiceManagerMock).linkToDeath(mServiceManagerDeathCaptor.capture(),
2777                 anyLong());
2778         mInOrder.verify(mServiceManagerMock).registerForNotifications(
2779                 eq(ISupplicant.kInterfaceName), eq(""), mServiceNotificationCaptor.capture());
2780         // act: cause the onRegistration(...) callback to execute
2781         mServiceNotificationCaptor.getValue().onRegistration(ISupplicant.kInterfaceName, "", true);
2782 
2783         assertTrue(mDut.isInitializationComplete());
2784         assertTrue(mDut.setupIface(WLAN0_IFACE_NAME) == shouldSucceed);
2785         mInOrder.verify(mISupplicantMockV11).linkToDeath(mSupplicantDeathCaptor.capture(),
2786                 mDeathRecipientCookieCaptor.capture());
2787         // verify: addInterface is called
2788         mInOrder.verify(mISupplicantMockV11)
2789                 .addInterface(any(ISupplicant.IfaceInfo.class),
2790                         any(android.hardware.wifi.supplicant.V1_1.ISupplicant
2791                                 .addInterfaceCallback.class));
2792         if (!causeRemoteException && !getNullInterface) {
2793             mInOrder.verify(mISupplicantStaIfaceMockV11)
2794                     .registerCallback_1_1(
2795                     any(android.hardware.wifi.supplicant.V1_1.ISupplicantStaIfaceCallback.class));
2796         }
2797 
2798         // Ensure we don't try to use the listInterfaces method from 1.0 version.
2799         verify(mISupplicantMock, never()).listInterfaces(
2800                 any(ISupplicant.listInterfacesCallback.class));
2801         verify(mISupplicantMock, never()).getInterface(any(ISupplicant.IfaceInfo.class),
2802                         any(ISupplicant.getInterfaceCallback.class));
2803     }
2804 
2805     /**
2806      * Calls.initialize(), mocking various call back answers and verifying flow, asserting for the
2807      * expected result. Verifies if ISupplicantStaIface manager is initialized or reset.
2808      * Each of the arguments will cause a different failure mode when set true.
2809      */
executeAndValidateInitializationSequenceV1_2()2810     private void executeAndValidateInitializationSequenceV1_2()
2811             throws Exception {
2812         // Setup callback mock answers
2813         doAnswer(new GetAddInterfaceAnswerV1_2(false))
2814                 .when(mISupplicantMockV11).addInterface(any(ISupplicant.IfaceInfo.class),
2815                 any(android.hardware.wifi.supplicant.V1_2.ISupplicant
2816                         .addInterfaceCallback.class));
2817 
2818         /** Callback registration */
2819         doAnswer(new MockAnswerUtil.AnswerWithArguments() {
2820             public SupplicantStatus answer(
2821                     android.hardware.wifi.supplicant.V1_1.ISupplicantStaIfaceCallback cb)
2822                     throws RemoteException {
2823                 mISupplicantStaIfaceCallbackV11 = cb;
2824                 return mStatusSuccess;
2825             }
2826         }).when(mISupplicantStaIfaceMockV12)
2827                 .registerCallback_1_1(
2828                         any(android.hardware.wifi.supplicant.V1_1.ISupplicantStaIfaceCallback
2829                                 .class));
2830 
2831         doAnswer(new MockAnswerUtil.AnswerWithArguments() {
2832             public SupplicantStatus answer(
2833                     android.hardware.wifi.supplicant.V1_2.ISupplicantStaIfaceCallback cb)
2834                     throws RemoteException {
2835                 mISupplicantStaIfaceCallbackV12 = cb;
2836                 return mStatusSuccess;
2837             }
2838         }).when(mISupplicantStaIfaceMockV12)
2839                 .registerCallback_1_2(
2840                         any(android.hardware.wifi.supplicant.V1_2.ISupplicantStaIfaceCallback
2841                                 .class));
2842 
2843         mInOrder = inOrder(mServiceManagerMock, mISupplicantMock, mISupplicantMockV11,
2844                 mISupplicantStaIfaceMockV12, mWifiMonitor);
2845         // Initialize SupplicantStaIfaceHal, should call serviceManager.registerForNotifications
2846         assertTrue(mDut.initialize());
2847         assertTrue(mDut.startDaemon());
2848         // verify: service manager initialization sequence
2849         mInOrder.verify(mServiceManagerMock).linkToDeath(mServiceManagerDeathCaptor.capture(),
2850                 anyLong());
2851         mInOrder.verify(mServiceManagerMock).registerForNotifications(
2852                 eq(ISupplicant.kInterfaceName), eq(""), mServiceNotificationCaptor.capture());
2853         // act: cause the onRegistration(...) callback to execute
2854         mServiceNotificationCaptor.getValue().onRegistration(ISupplicant.kInterfaceName, "", true);
2855 
2856         assertTrue(mDut.isInitializationComplete());
2857         assertTrue(mDut.setupIface(WLAN0_IFACE_NAME));
2858         mInOrder.verify(mISupplicantMockV11).linkToDeath(mSupplicantDeathCaptor.capture(),
2859                 anyLong());
2860         // verify: addInterface is called
2861         mInOrder.verify(mISupplicantMockV11)
2862                 .addInterface(any(ISupplicant.IfaceInfo.class),
2863                         any(android.hardware.wifi.supplicant.V1_2.ISupplicant
2864                                 .addInterfaceCallback.class));
2865 
2866         mInOrder.verify(mISupplicantStaIfaceMockV12)
2867                 .registerCallback_1_2(
2868                         any(android.hardware.wifi.supplicant.V1_2.ISupplicantStaIfaceCallback
2869                                 .class));
2870 
2871         // Ensure we don't try to use the listInterfaces method from 1.0 version.
2872 //        verify(mISupplicantMock, never()).listInterfaces(
2873 //                any(ISupplicant.listInterfacesCallback.class));
2874 //        verify(mISupplicantMock, never()).getInterface(any(ISupplicant.IfaceInfo.class),
2875 //                any(ISupplicant.getInterfaceCallback.class));
2876     }
2877 
2878     /**
2879      * Calls.initialize(), mocking various call back answers and verifying flow, asserting for the
2880      * expected result. Verifies if ISupplicantStaIface manager is initialized or reset.
2881      * Each of the arguments will cause a different failure mode when set true.
2882      */
executeAndValidateInitializationSequenceV1_3()2883     private void executeAndValidateInitializationSequenceV1_3()
2884             throws Exception {
2885         // Setup callback mock answers
2886         doAnswer(new GetAddInterfaceAnswerV1_3(false))
2887                 .when(mISupplicantMockV11).addInterface(any(ISupplicant.IfaceInfo.class),
2888                 any(android.hardware.wifi.supplicant.V1_1.ISupplicant
2889                         .addInterfaceCallback.class));
2890 
2891         /** Callback registration */
2892         doAnswer(new MockAnswerUtil.AnswerWithArguments() {
2893             public SupplicantStatus answer(
2894                     android.hardware.wifi.supplicant.V1_3.ISupplicantStaIfaceCallback cb)
2895                     throws RemoteException {
2896                 mISupplicantStaIfaceCallbackV13 = spy(cb);
2897                 return mStatusSuccess;
2898             }
2899         }).when(mISupplicantStaIfaceMockV13)
2900                 .registerCallback_1_3(
2901                         any(android.hardware.wifi.supplicant.V1_3.ISupplicantStaIfaceCallback
2902                                 .class));
2903 
2904         mInOrder = inOrder(mServiceManagerMock, mISupplicantMock, mISupplicantMockV11,
2905                 mISupplicantStaIfaceMockV13, mWifiMonitor);
2906         // Initialize SupplicantStaIfaceHal, should call serviceManager.registerForNotifications
2907         assertTrue(mDut.initialize());
2908         assertTrue(mDut.startDaemon());
2909         // verify: service manager initialization sequence
2910         mInOrder.verify(mServiceManagerMock).linkToDeath(mServiceManagerDeathCaptor.capture(),
2911                 anyLong());
2912         mInOrder.verify(mServiceManagerMock).registerForNotifications(
2913                 eq(ISupplicant.kInterfaceName), eq(""), mServiceNotificationCaptor.capture());
2914         // act: cause the onRegistration(...) callback to execute
2915         mServiceNotificationCaptor.getValue().onRegistration(ISupplicant.kInterfaceName, "", true);
2916 
2917         assertTrue(mDut.isInitializationComplete());
2918         assertTrue(mDut.setupIface(WLAN0_IFACE_NAME));
2919         mInOrder.verify(mISupplicantMockV11).linkToDeath(mSupplicantDeathCaptor.capture(),
2920                 anyLong());
2921         // verify: addInterface is called
2922         mInOrder.verify(mISupplicantMockV11)
2923                 .addInterface(any(ISupplicant.IfaceInfo.class),
2924                         any(android.hardware.wifi.supplicant.V1_1.ISupplicant
2925                                 .addInterfaceCallback.class));
2926 
2927         mInOrder.verify(mISupplicantStaIfaceMockV13)
2928                 .registerCallback_1_3(
2929                         any(android.hardware.wifi.supplicant.V1_3.ISupplicantStaIfaceCallback
2930                                 .class));
2931     }
2932 
2933     /**
2934      * Calls.initialize(), mocking various call back answers and verifying flow, asserting for the
2935      * expected result. Verifies if ISupplicantStaIface manager is initialized or reset.
2936      * Each of the arguments will cause a different failure mode when set true.
2937      */
executeAndValidateInitializationSequenceV1_4()2938     private void executeAndValidateInitializationSequenceV1_4()
2939             throws Exception {
2940         // Setup callback mock answers
2941         doAnswer(new GetAddInterfaceAnswerV1_4(false))
2942                 .when(mISupplicantMockV11).addInterface(any(ISupplicant.IfaceInfo.class),
2943                 any(android.hardware.wifi.supplicant.V1_1.ISupplicant
2944                         .addInterfaceCallback.class));
2945 
2946         /** Callback registration */
2947         doAnswer(new MockAnswerUtil.AnswerWithArguments() {
2948             public android.hardware.wifi.supplicant.V1_4.SupplicantStatus answer(
2949                     android.hardware.wifi.supplicant.V1_4.ISupplicantStaIfaceCallback cb)
2950                     throws RemoteException {
2951                 mISupplicantStaIfaceCallbackV14 = spy(cb);
2952                 return mStatusSuccessV14;
2953             }
2954         }).when(mISupplicantStaIfaceMockV14)
2955                 .registerCallback_1_4(
2956                         any(android.hardware.wifi.supplicant.V1_4.ISupplicantStaIfaceCallback
2957                                 .class));
2958 
2959         mInOrder = inOrder(mServiceManagerMock, mISupplicantMock, mISupplicantMockV11,
2960                 mISupplicantStaIfaceMockV14, mWifiMonitor);
2961         // Initialize SupplicantStaIfaceHal, should call serviceManager.registerForNotifications
2962         assertTrue(mDut.initialize());
2963         assertTrue(mDut.startDaemon());
2964         // verify: service manager initialization sequence
2965         mInOrder.verify(mServiceManagerMock).linkToDeath(mServiceManagerDeathCaptor.capture(),
2966                 anyLong());
2967         mInOrder.verify(mServiceManagerMock).registerForNotifications(
2968                 eq(ISupplicant.kInterfaceName), eq(""), mServiceNotificationCaptor.capture());
2969         // act: cause the onRegistration(...) callback to execute
2970         mServiceNotificationCaptor.getValue().onRegistration(ISupplicant.kInterfaceName, "", true);
2971 
2972         assertTrue(mDut.isInitializationComplete());
2973         assertTrue(mDut.setupIface(WLAN0_IFACE_NAME));
2974         mInOrder.verify(mISupplicantMockV11).linkToDeath(mSupplicantDeathCaptor.capture(),
2975                 anyLong());
2976         // verify: addInterface is called
2977         mInOrder.verify(mISupplicantMockV11)
2978                 .addInterface(any(ISupplicant.IfaceInfo.class),
2979                         any(android.hardware.wifi.supplicant.V1_1.ISupplicant
2980                                 .addInterfaceCallback.class));
2981 
2982         mInOrder.verify(mISupplicantStaIfaceMockV14)
2983                 .registerCallback_1_4(
2984                         any(android.hardware.wifi.supplicant.V1_4.ISupplicantStaIfaceCallback
2985                                 .class));
2986     }
2987 
createSupplicantStatus(int code)2988     private SupplicantStatus createSupplicantStatus(int code) {
2989         SupplicantStatus status = new SupplicantStatus();
2990         status.code = code;
2991         return status;
2992     }
2993 
2994     private android.hardware.wifi.supplicant.V1_4.SupplicantStatus
createSupplicantStatusV1_4(int code)2995             createSupplicantStatusV1_4(int code) {
2996         android.hardware.wifi.supplicant.V1_4.SupplicantStatus status =
2997                 new android.hardware.wifi.supplicant.V1_4.SupplicantStatus();
2998         status.code = code;
2999         return status;
3000     }
3001 
3002     /**
3003      * Create an IfaceInfo with given type and name
3004      */
createIfaceInfo(int type, String name)3005     private ISupplicant.IfaceInfo createIfaceInfo(int type, String name) {
3006         ISupplicant.IfaceInfo info = new ISupplicant.IfaceInfo();
3007         info.type = type;
3008         info.name = name;
3009         return info;
3010     }
3011 
3012     private class GetListInterfacesAnswer extends MockAnswerUtil.AnswerWithArguments {
3013         private ArrayList<ISupplicant.IfaceInfo> mInterfaceList;
3014 
GetListInterfacesAnswer(ArrayList<ISupplicant.IfaceInfo> ifaces)3015         GetListInterfacesAnswer(ArrayList<ISupplicant.IfaceInfo> ifaces) {
3016             mInterfaceList = ifaces;
3017         }
3018 
answer(ISupplicant.listInterfacesCallback cb)3019         public void answer(ISupplicant.listInterfacesCallback cb) {
3020             cb.onValues(mStatusSuccess, mInterfaceList);
3021         }
3022     }
3023 
3024     private class GetGetInterfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
3025         boolean mGetNullInterface;
3026 
GetGetInterfaceAnswer(boolean getNullInterface)3027         GetGetInterfaceAnswer(boolean getNullInterface) {
3028             mGetNullInterface = getNullInterface;
3029         }
3030 
answer(ISupplicant.IfaceInfo iface, ISupplicant.getInterfaceCallback cb)3031         public void answer(ISupplicant.IfaceInfo iface, ISupplicant.getInterfaceCallback cb) {
3032             if (mGetNullInterface) {
3033                 cb.onValues(mStatusSuccess, null);
3034             } else {
3035                 cb.onValues(mStatusSuccess, mISupplicantIfaceMock);
3036             }
3037         }
3038     }
3039 
3040     private class GetAddInterfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
3041         boolean mGetNullInterface;
3042 
GetAddInterfaceAnswer(boolean getNullInterface)3043         GetAddInterfaceAnswer(boolean getNullInterface) {
3044             mGetNullInterface = getNullInterface;
3045         }
3046 
answer(ISupplicant.IfaceInfo iface, android.hardware.wifi.supplicant.V1_1.ISupplicant .addInterfaceCallback cb)3047         public void answer(ISupplicant.IfaceInfo iface,
3048                            android.hardware.wifi.supplicant.V1_1.ISupplicant
3049                                    .addInterfaceCallback cb) {
3050             if (mGetNullInterface) {
3051                 cb.onValues(mStatusSuccess, null);
3052             } else {
3053                 cb.onValues(mStatusSuccess, mISupplicantIfaceMock);
3054             }
3055         }
3056     }
3057 
3058     private class GetAddInterfaceAnswerV1_2 extends MockAnswerUtil.AnswerWithArguments {
3059         boolean mGetNullInterface;
3060 
GetAddInterfaceAnswerV1_2(boolean getNullInterface)3061         GetAddInterfaceAnswerV1_2(boolean getNullInterface) {
3062             mGetNullInterface = getNullInterface;
3063         }
3064 
answer(ISupplicant.IfaceInfo iface, android.hardware.wifi.supplicant.V1_2.ISupplicant .addInterfaceCallback cb)3065         public void answer(ISupplicant.IfaceInfo iface,
3066                 android.hardware.wifi.supplicant.V1_2.ISupplicant
3067                         .addInterfaceCallback cb) {
3068             if (mGetNullInterface) {
3069                 cb.onValues(mStatusSuccess, null);
3070             } else {
3071                 cb.onValues(mStatusSuccess, mISupplicantIfaceMock);
3072             }
3073         }
3074     }
3075 
3076     private class GetAddInterfaceAnswerV1_3 extends MockAnswerUtil.AnswerWithArguments {
3077         boolean mGetNullInterface;
3078 
GetAddInterfaceAnswerV1_3(boolean getNullInterface)3079         GetAddInterfaceAnswerV1_3(boolean getNullInterface) {
3080             mGetNullInterface = getNullInterface;
3081         }
3082 
answer(ISupplicant.IfaceInfo iface, android.hardware.wifi.supplicant.V1_3.ISupplicant .addInterfaceCallback cb)3083         public void answer(ISupplicant.IfaceInfo iface,
3084                 android.hardware.wifi.supplicant.V1_3.ISupplicant
3085                         .addInterfaceCallback cb) {
3086             if (mGetNullInterface) {
3087                 cb.onValues(mStatusSuccess, null);
3088             } else {
3089                 cb.onValues(mStatusSuccess, mISupplicantIfaceMock);
3090             }
3091         }
3092     }
3093 
3094     private class GetAddInterfaceAnswerV1_4 extends MockAnswerUtil.AnswerWithArguments {
3095         boolean mGetNullInterface;
3096 
GetAddInterfaceAnswerV1_4(boolean getNullInterface)3097         GetAddInterfaceAnswerV1_4(boolean getNullInterface) {
3098             mGetNullInterface = getNullInterface;
3099         }
3100 
answer(ISupplicant.IfaceInfo iface, android.hardware.wifi.supplicant.V1_4.ISupplicant .addInterfaceCallback cb)3101         public void answer(ISupplicant.IfaceInfo iface,
3102                 android.hardware.wifi.supplicant.V1_4.ISupplicant
3103                         .addInterfaceCallback cb) {
3104             if (mGetNullInterface) {
3105                 cb.onValues(mStatusSuccess, null);
3106             } else {
3107                 cb.onValues(mStatusSuccess, mISupplicantIfaceMock);
3108             }
3109         }
3110     }
3111 
3112     /**
3113      * Setup mocks for connect sequence.
3114      */
setupMocksForConnectSequence(final boolean haveExistingNetwork)3115     private void setupMocksForConnectSequence(final boolean haveExistingNetwork) throws Exception {
3116         final int existingNetworkId = SUPPLICANT_NETWORK_ID;
3117         doAnswer(new MockAnswerUtil.AnswerWithArguments() {
3118             public SupplicantStatus answer() throws RemoteException {
3119                 return mStatusSuccess;
3120             }
3121         }).when(mISupplicantStaIfaceMock).disconnect();
3122         doAnswer(new MockAnswerUtil.AnswerWithArguments() {
3123             public void answer(ISupplicantStaIface.listNetworksCallback cb) throws RemoteException {
3124                 if (haveExistingNetwork) {
3125                     cb.onValues(mStatusSuccess, new ArrayList<>(Arrays.asList(existingNetworkId)));
3126                 } else {
3127                     cb.onValues(mStatusSuccess, new ArrayList<>());
3128                 }
3129             }
3130         }).when(mISupplicantStaIfaceMock)
3131                 .listNetworks(any(ISupplicantStaIface.listNetworksCallback.class));
3132         doAnswer(new MockAnswerUtil.AnswerWithArguments() {
3133             public SupplicantStatus answer(int id) throws RemoteException {
3134                 return mStatusSuccess;
3135             }
3136         }).when(mISupplicantStaIfaceMock).removeNetwork(eq(existingNetworkId));
3137         doAnswer(new MockAnswerUtil.AnswerWithArguments() {
3138             public void answer(ISupplicantStaIface.addNetworkCallback cb) throws RemoteException {
3139                 cb.onValues(mStatusSuccess, mock(ISupplicantStaNetwork.class));
3140                 return;
3141             }
3142         }).when(mISupplicantStaIfaceMock).addNetwork(
3143                 any(ISupplicantStaIface.addNetworkCallback.class));
3144         when(mSupplicantStaNetworkMock.saveWifiConfiguration(any(WifiConfiguration.class)))
3145                 .thenReturn(true);
3146         when(mSupplicantStaNetworkMock.select()).thenReturn(true);
3147     }
3148 
3149     /**
3150      * Helper function to validate the connect sequence.
3151      */
validateConnectSequence( final boolean haveExistingNetwork, int numNetworkAdditions, String ssid)3152     private void validateConnectSequence(
3153             final boolean haveExistingNetwork, int numNetworkAdditions, String ssid)
3154             throws Exception {
3155         if (haveExistingNetwork) {
3156             verify(mISupplicantStaIfaceMock).removeNetwork(anyInt());
3157         }
3158         verify(mISupplicantStaIfaceMock, times(numNetworkAdditions))
3159                 .addNetwork(any(ISupplicantStaIface.addNetworkCallback.class));
3160         ArgumentCaptor<WifiConfiguration> configCaptor =
3161                 ArgumentCaptor.forClass(WifiConfiguration.class);
3162         verify(mSupplicantStaNetworkMock, times(numNetworkAdditions))
3163                 .saveWifiConfiguration(configCaptor.capture());
3164         assertTrue(TextUtils.equals(configCaptor.getValue().SSID, ssid));
3165         verify(mSupplicantStaNetworkMock, times(numNetworkAdditions)).select();
3166         verify(mSsidTranslator).setTranslatedSsidForStaIface(any(), anyString());
3167     }
3168 
3169     /**
3170      * Helper function to execute all the actions to perform connection to the network.
3171      *
3172      * @param newFrameworkNetworkId Framework Network Id of the new network to connect.
3173      * @param haveExistingNetwork Removes the existing network.
3174      * @param ssid Raw SSID to send to supplicant.
3175      * @return the WifiConfiguration object of the new network to connect.
3176      */
executeAndValidateConnectSequence( final int newFrameworkNetworkId, final boolean haveExistingNetwork, String ssid)3177     private WifiConfiguration executeAndValidateConnectSequence(
3178             final int newFrameworkNetworkId, final boolean haveExistingNetwork,
3179             String ssid) throws Exception {
3180         return executeAndValidateConnectSequenceWithKeyMgmt(newFrameworkNetworkId,
3181                 haveExistingNetwork, TRANSLATED_SUPPLICANT_SSID.toString(),
3182                 WifiConfiguration.SECURITY_TYPE_PSK, null);
3183     }
3184 
3185     /**
3186      * Helper function to execute all the actions to perform connection to the network.
3187      *
3188      * @param newFrameworkNetworkId Framework Network Id of the new network to connect.
3189      * @param haveExistingNetwork Removes the existing network.
3190      * @param ssid Raw SSID to send to supplicant.
3191      * @param securityType The security type.
3192      * @param wepKey if configurations are for a WEP network else null.
3193      * @param hasEverConnected indicate that this configuration is ever connected or not.
3194      * @return the WifiConfiguration object of the new network to connect.
3195      */
executeAndValidateConnectSequenceWithKeyMgmt( final int newFrameworkNetworkId, final boolean haveExistingNetwork, String ssid, int securityType, String wepKey, boolean hasEverConnected)3196     private WifiConfiguration executeAndValidateConnectSequenceWithKeyMgmt(
3197             final int newFrameworkNetworkId, final boolean haveExistingNetwork,
3198             String ssid, int securityType, String wepKey, boolean hasEverConnected)
3199             throws Exception {
3200         setupMocksForConnectSequence(haveExistingNetwork);
3201         WifiConfiguration config = new WifiConfiguration();
3202         config.setSecurityParams(securityType);
3203         config.networkId = newFrameworkNetworkId;
3204         config.SSID = ssid;
3205         config.wepKeys[0] = wepKey;
3206         config.wepTxKeyIndex = 0;
3207         WifiConfiguration.NetworkSelectionStatus networkSelectionStatus =
3208                 new WifiConfiguration.NetworkSelectionStatus();
3209         networkSelectionStatus.setCandidateSecurityParams(config.getSecurityParams(securityType));
3210         networkSelectionStatus.setHasEverConnected(hasEverConnected);
3211         config.setNetworkSelectionStatus(networkSelectionStatus);
3212         assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, config));
3213         validateConnectSequence(haveExistingNetwork, 1, ssid);
3214         return config;
3215     }
3216 
3217     /**
3218      * Helper function to execute all the actions to perform connection to the network.
3219      *
3220      * @param newFrameworkNetworkId Framework Network Id of the new network to connect.
3221      * @param haveExistingNetwork Removes the existing network.
3222      * @param ssid Raw SSID to send to supplicant.
3223      * @param securityType The security type.
3224      * @param wepKey if configurations are for a WEP network else null.
3225      * @return the WifiConfiguration object of the new network to connect.
3226      */
executeAndValidateConnectSequenceWithKeyMgmt( final int newFrameworkNetworkId, final boolean haveExistingNetwork, String ssid, int securityType, String wepKey)3227     private WifiConfiguration executeAndValidateConnectSequenceWithKeyMgmt(
3228             final int newFrameworkNetworkId, final boolean haveExistingNetwork,
3229             String ssid, int securityType, String wepKey) throws Exception {
3230         return executeAndValidateConnectSequenceWithKeyMgmt(
3231                 newFrameworkNetworkId, haveExistingNetwork,
3232                 ssid, securityType, wepKey, false);
3233     }
3234 
3235     /**
3236      * Setup mocks for roam sequence.
3237      */
setupMocksForRoamSequence(String roamBssid)3238     private void setupMocksForRoamSequence(String roamBssid) throws Exception {
3239         doAnswer(new MockAnswerUtil.AnswerWithArguments() {
3240             public SupplicantStatus answer() throws RemoteException {
3241                 return mStatusSuccess;
3242             }
3243         }).when(mISupplicantStaIfaceMock).reassociate();
3244         when(mSupplicantStaNetworkMock.setBssid(eq(roamBssid))).thenReturn(true);
3245     }
3246 
3247     /**
3248      * Helper function to execute all the actions to perform roaming to the network.
3249      *
3250      * @param sameNetwork Roam to the same network or not.
3251      * @param linkedNetwork Roam to linked network or not.
3252      */
executeAndValidateRoamSequence(boolean sameNetwork, boolean linkedNetwork)3253     private void executeAndValidateRoamSequence(boolean sameNetwork, boolean linkedNetwork)
3254             throws Exception {
3255         int connectedNetworkId = ROAM_NETWORK_ID;
3256         String roamBssid = BSSID;
3257         int roamNetworkId;
3258         if (sameNetwork) {
3259             roamNetworkId = connectedNetworkId;
3260         } else {
3261             roamNetworkId = connectedNetworkId + 1;
3262         }
3263         executeAndValidateConnectSequence(connectedNetworkId, false,
3264                 TRANSLATED_SUPPLICANT_SSID.toString());
3265         setupMocksForRoamSequence(roamBssid);
3266 
3267         WifiConfiguration roamingConfig = new WifiConfiguration();
3268         roamingConfig.networkId = roamNetworkId;
3269         roamingConfig.getNetworkSelectionStatus().setNetworkSelectionBSSID(roamBssid);
3270         SupplicantStaNetworkHalHidlImpl linkedNetworkHandle =
3271                 mock(SupplicantStaNetworkHalHidlImpl.class);
3272         if (linkedNetwork) {
3273             // Set the StaNetworkMockable to add a new handle for the linked network
3274             int roamRemoteNetworkId = roamNetworkId + 1;
3275             when(linkedNetworkHandle.getNetworkId()).thenReturn(roamRemoteNetworkId);
3276             when(linkedNetworkHandle.saveWifiConfiguration(any())).thenReturn(true);
3277             when(linkedNetworkHandle.select()).thenReturn(true);
3278             mDut.setStaNetworkMockable(linkedNetworkHandle);
3279             final HashMap<String, WifiConfiguration> linkedNetworks = new HashMap<>();
3280             linkedNetworks.put(roamingConfig.getProfileKey(), roamingConfig);
3281             assertTrue(mDut.updateLinkedNetworks(
3282                     WLAN0_IFACE_NAME, connectedNetworkId, linkedNetworks));
3283         }
3284         assertTrue(mDut.roamToNetwork(WLAN0_IFACE_NAME, roamingConfig));
3285 
3286         if (sameNetwork) {
3287             verify(mSupplicantStaNetworkMock).setBssid(eq(roamBssid));
3288             verify(mISupplicantStaIfaceMock).reassociate();
3289         } else if (linkedNetwork) {
3290             verify(mISupplicantStaIfaceMock, never()).removeNetwork(anyInt());
3291             verify(mISupplicantStaIfaceMock, times(2))
3292                     .addNetwork(any(ISupplicantStaIface.addNetworkCallback.class));
3293             verify(mSupplicantStaNetworkMock).saveWifiConfiguration(any(WifiConfiguration.class));
3294             verify(mSupplicantStaNetworkMock).select();
3295             verify(linkedNetworkHandle).saveWifiConfiguration(any(WifiConfiguration.class));
3296             verify(linkedNetworkHandle).select();
3297             verify(mSupplicantStaNetworkMock, never()).setBssid(anyString());
3298             verify(mISupplicantStaIfaceMock, never()).reassociate();
3299         } else {
3300             validateConnectSequence(false, 2, null);
3301             verify(mSupplicantStaNetworkMock, never()).setBssid(anyString());
3302             verify(mISupplicantStaIfaceMock, never()).reassociate();
3303         }
3304     }
3305 
3306     /**
3307      * Helper function to set up Hal cascadingly.
3308      */
setupMocksForHalV1_1()3309     private void setupMocksForHalV1_1() throws Exception {
3310         // V1_0 is set up by default, no need to do it.
3311         when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_1.ISupplicant
3312                 .kInterfaceName), anyString()))
3313                 .thenReturn(IServiceManager.Transport.HWBINDER);
3314     }
3315 
setupMocksForHalV1_2()3316     private void setupMocksForHalV1_2() throws Exception {
3317         setupMocksForHalV1_1();
3318         when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_2.ISupplicant
3319                 .kInterfaceName), anyString()))
3320                 .thenReturn(IServiceManager.Transport.HWBINDER);
3321     }
3322 
setupMocksForHalV1_3()3323     private void setupMocksForHalV1_3() throws Exception {
3324         setupMocksForHalV1_2();
3325         when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_3.ISupplicant
3326                 .kInterfaceName), anyString()))
3327                 .thenReturn(IServiceManager.Transport.HWBINDER);
3328     }
3329 
setupMocksForHalV1_4()3330     private void setupMocksForHalV1_4() throws Exception {
3331         setupMocksForHalV1_3();
3332         when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_4.ISupplicant
3333                 .kInterfaceName), anyString()))
3334                 .thenReturn(IServiceManager.Transport.HWBINDER);
3335     }
3336 
setupMocksForPmkCache(boolean isHalSupported)3337     private void setupMocksForPmkCache(boolean isHalSupported) throws Exception {
3338         ArrayList<Byte> pmkCacheData = NativeUtil.byteArrayToArrayList("deadbeef".getBytes());
3339         setupMocksForPmkCache(pmkCacheData, isHalSupported);
3340     }
3341 
setupMocksForPmkCache(ArrayList<Byte> pmkCacheData, boolean isHalSupported)3342     private void setupMocksForPmkCache(ArrayList<Byte> pmkCacheData, boolean isHalSupported)
3343             throws Exception {
3344         mDut.mPmkCacheManager = mPmkCacheManager;
3345         doAnswer(new MockAnswerUtil.AnswerWithArguments() {
3346             public List<ArrayList<Byte>> answer(int networkId) {
3347                 if (pmkCacheData == null) return null;
3348 
3349                 List<ArrayList<Byte>> pmkDataList = new ArrayList<>();
3350                 pmkDataList.add(pmkCacheData);
3351                 return pmkDataList;
3352             }
3353         }).when(mPmkCacheManager)
3354                 .get(anyInt());
3355 
3356         if (!isHalSupported) return;
3357         /** Callback registration */
3358         doAnswer(new MockAnswerUtil.AnswerWithArguments() {
3359             public SupplicantStatus answer(
3360                     android.hardware.wifi.supplicant.V1_3.ISupplicantStaIfaceCallback cb)
3361                     throws RemoteException {
3362                 mISupplicantStaIfaceCallbackV13 = cb;
3363                 return mStatusSuccess;
3364             }
3365         }).when(mISupplicantStaIfaceMockV13)
3366                 .registerCallback_1_3(
3367                         any(android.hardware.wifi.supplicant.V1_3.ISupplicantStaIfaceCallback
3368                                 .class));
3369 
3370         doAnswer(new MockAnswerUtil.AnswerWithArguments() {
3371             public boolean answer(WifiConfiguration config, Map<String, String> networkExtra)
3372                     throws Exception {
3373                 config.networkId = SUPPLICANT_NETWORK_ID;
3374                 return true;
3375             }
3376         }).when(mSupplicantStaNetworkMock)
3377                 .loadWifiConfiguration(any(WifiConfiguration.class), any(Map.class));
3378 
3379         doAnswer(new MockAnswerUtil.AnswerWithArguments() {
3380             public boolean answer(ArrayList<Byte> serializedData)
3381                     throws Exception {
3382                 mISupplicantStaIfaceCallbackV13.onPmkCacheAdded(
3383                         PMK_CACHE_EXPIRATION_IN_SEC, serializedData);
3384                 return true;
3385             }
3386         }).when(mSupplicantStaNetworkMock)
3387                 .setPmkCache(any(ArrayList.class));
3388     }
3389 
3390     private class GetWpaDriverCapabilitiesAnswer extends MockAnswerUtil.AnswerWithArguments {
3391         private int mWpaDriverCapabilities;
3392 
GetWpaDriverCapabilitiesAnswer(int wpaDriverCapabilities)3393         GetWpaDriverCapabilitiesAnswer(int wpaDriverCapabilities) {
3394             mWpaDriverCapabilities = wpaDriverCapabilities;
3395         }
3396 
answer(android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface .getWpaDriverCapabilitiesCallback cb)3397         public void answer(android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
3398                 .getWpaDriverCapabilitiesCallback cb) {
3399             cb.onValues(mStatusSuccess, mWpaDriverCapabilities);
3400         }
3401     }
3402 
3403     private class GetWpaDriverCapabilities_1_4Answer extends MockAnswerUtil.AnswerWithArguments {
3404         private int mWpaDriverCapabilities;
3405 
GetWpaDriverCapabilities_1_4Answer(int wpaDriverCapabilities)3406         GetWpaDriverCapabilities_1_4Answer(int wpaDriverCapabilities) {
3407             mWpaDriverCapabilities = wpaDriverCapabilities;
3408         }
3409 
answer(android.hardware.wifi.supplicant.V1_4.ISupplicantStaIface .getWpaDriverCapabilities_1_4Callback cb)3410         public void answer(android.hardware.wifi.supplicant.V1_4.ISupplicantStaIface
3411                 .getWpaDriverCapabilities_1_4Callback cb) {
3412             cb.onValues(mStatusSuccessV14, mWpaDriverCapabilities);
3413         }
3414     }
3415 
3416     /**
3417      * Test To get wpa driver capabilities API on old HAL, should
3418      * return 0 (not supported)
3419      */
3420     @Test
tetGetWpaDriverCapabilitiesOldHal()3421     public void tetGetWpaDriverCapabilitiesOldHal() throws Exception {
3422         setupMocksForHalV1_2();
3423 
3424         executeAndValidateInitializationSequenceV1_2();
3425 
3426         assertEquals(0, mDut.getWpaDriverFeatureSet(WLAN0_IFACE_NAME));
3427     }
3428 
3429     /**
3430      * Test Multi Band operation support (MBO).
3431      */
3432     @Test
testGetWpaDriverCapabilitiesMbo()3433     public void testGetWpaDriverCapabilitiesMbo() throws Exception {
3434         setupMocksForHalV1_3();
3435 
3436         executeAndValidateInitializationSequenceV1_3();
3437 
3438         doAnswer(new GetWpaDriverCapabilitiesAnswer(android.hardware.wifi.supplicant.V1_3
3439                 .WpaDriverCapabilitiesMask.MBO))
3440                 .when(mISupplicantStaIfaceMockV13).getWpaDriverCapabilities(any(
3441                 android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
3442                         .getWpaDriverCapabilitiesCallback.class));
3443 
3444         assertEquals(WIFI_FEATURE_MBO, mDut.getWpaDriverFeatureSet(WLAN0_IFACE_NAME));
3445     }
3446 
3447     /**
3448      * Test Optimized Connectivity support (OCE).
3449      */
3450     @Test
testGetWpaDriverCapabilitiesOce()3451     public void testGetWpaDriverCapabilitiesOce() throws Exception {
3452         setupMocksForHalV1_3();
3453 
3454         executeAndValidateInitializationSequenceV1_3();
3455 
3456         doAnswer(new GetWpaDriverCapabilitiesAnswer(android.hardware.wifi.supplicant.V1_3
3457                 .WpaDriverCapabilitiesMask.MBO
3458                 | android.hardware.wifi.supplicant.V1_3
3459                 .WpaDriverCapabilitiesMask.OCE))
3460                 .when(mISupplicantStaIfaceMockV13).getWpaDriverCapabilities(any(
3461                 android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
3462                         .getWpaDriverCapabilitiesCallback.class));
3463 
3464         assertEquals(WIFI_FEATURE_MBO | WIFI_FEATURE_OCE,
3465                 mDut.getWpaDriverFeatureSet(WLAN0_IFACE_NAME));
3466     }
3467 
3468     /**
3469      * Test getWpaDriverCapabilities_1_4
3470      */
3471     @Test
testGetWpaDriverCapabilities_1_4()3472     public void testGetWpaDriverCapabilities_1_4() throws Exception {
3473         setupMocksForHalV1_4();
3474 
3475         executeAndValidateInitializationSequenceV1_4();
3476 
3477         doAnswer(new GetWpaDriverCapabilities_1_4Answer(android.hardware.wifi.supplicant.V1_3
3478                 .WpaDriverCapabilitiesMask.MBO
3479                 | android.hardware.wifi.supplicant.V1_3
3480                 .WpaDriverCapabilitiesMask.OCE))
3481                 .when(mISupplicantStaIfaceMockV14).getWpaDriverCapabilities_1_4(any(
3482                 android.hardware.wifi.supplicant.V1_4.ISupplicantStaIface
3483                         .getWpaDriverCapabilities_1_4Callback.class));
3484 
3485         assertEquals(WIFI_FEATURE_MBO | WIFI_FEATURE_OCE,
3486                 mDut.getWpaDriverFeatureSet(WLAN0_IFACE_NAME));
3487     }
3488 
3489     /**
3490      * Test the handling of BSS transition request callback.
3491      */
3492     @Test
testBssTmHandlingDoneCallback()3493     public void testBssTmHandlingDoneCallback() throws Exception {
3494         setupMocksForHalV1_3();
3495         executeAndValidateInitializationSequenceV1_3();
3496         assertNotNull(mISupplicantStaIfaceCallbackV13);
3497         mISupplicantStaIfaceCallbackV13.onBssTmHandlingDone(new BssTmData());
3498 
3499         ArgumentCaptor<BtmFrameData> btmFrameDataCaptor =
3500                 ArgumentCaptor.forClass(BtmFrameData.class);
3501         verify(mWifiMonitor).broadcastBssTmHandlingDoneEvent(
3502                 eq(WLAN0_IFACE_NAME), btmFrameDataCaptor.capture());
3503     }
3504 
3505     /**
3506      * Tests the configuring of FILS HLP packet in supplicant.
3507      */
3508     @Test
testAddHlpReq()3509     public void testAddHlpReq() throws Exception {
3510         byte[] dstAddr = {0x45, 0x23, 0x12, 0x12, 0x12, 0x45};
3511         byte[] hlpPacket = {0x00, 0x01, 0x02, 0x03, 0x04, 0x12, 0x15, 0x34, 0x55, 0x12,
3512                 0x12, 0x45, 0x23, 0x52, 0x32, 0x16, 0x15, 0x53, 0x62, 0x32, 0x32, 0x10};
3513 
3514         setupMocksForHalV1_3();
3515         when(mISupplicantStaIfaceMockV13.filsHlpAddRequest(any(byte[].class),
3516                 any(ArrayList.class))).thenReturn(mStatusSuccess);
3517 
3518         // Fail before initialization is performed.
3519         assertFalse(mDut.addHlpReq(WLAN0_IFACE_NAME, dstAddr, hlpPacket));
3520         verify(mISupplicantStaIfaceMockV13, never()).filsHlpAddRequest(any(byte[].class),
3521                 any(ArrayList.class));
3522 
3523         executeAndValidateInitializationSequenceV1_3();
3524         assertNotNull(mISupplicantStaIfaceCallbackV13);
3525 
3526         ArrayList<Byte> hlpPayload = NativeUtil.byteArrayToArrayList(hlpPacket);
3527         assertTrue(mDut.addHlpReq(WLAN0_IFACE_NAME, dstAddr, hlpPacket));
3528         verify(mISupplicantStaIfaceMockV13).filsHlpAddRequest(eq(dstAddr), eq(hlpPayload));
3529     }
3530 
3531     /**
3532      * Tests the flushing of FILS HLP packet from supplicant.
3533      */
3534     @Test
testFlushAllHlp()3535     public void testFlushAllHlp() throws Exception {
3536 
3537         setupMocksForHalV1_3();
3538         when(mISupplicantStaIfaceMockV13.filsHlpFlushRequest()).thenReturn(mStatusSuccess);
3539 
3540         // Fail before initialization is performed.
3541         assertFalse(mDut.flushAllHlp(WLAN0_IFACE_NAME));
3542         verify(mISupplicantStaIfaceMockV13, never()).filsHlpFlushRequest();
3543 
3544         executeAndValidateInitializationSequenceV1_3();
3545         assertNotNull(mISupplicantStaIfaceCallbackV13);
3546 
3547         assertTrue(mDut.flushAllHlp(WLAN0_IFACE_NAME));
3548         verify(mISupplicantStaIfaceMockV13).filsHlpFlushRequest();
3549     }
3550 
3551     /**
3552      * Tests the handling of state change V13 notification without
3553      * any configured network.
3554      */
3555     @Test
testonStateChangedV13CallbackWithNoConfiguredNetwork()3556     public void testonStateChangedV13CallbackWithNoConfiguredNetwork() throws Exception {
3557         setupMocksForHalV1_3();
3558         executeAndValidateInitializationSequenceV1_3();
3559         assertNotNull(mISupplicantStaIfaceCallbackV13);
3560 
3561         mISupplicantStaIfaceCallbackV13.onStateChanged_1_3(
3562                 ISupplicantStaIfaceCallback.State.INACTIVE,
3563                 NativeUtil.macAddressToByteArray(BSSID), SUPPLICANT_NETWORK_ID,
3564                 NativeUtil.decodeSsid(SUPPLICANT_SSID), false);
3565 
3566         // Can't compare WifiSsid instances because they lack an equals.
3567         verify(mWifiMonitor).broadcastSupplicantStateChangeEvent(
3568                 eq(WLAN0_IFACE_NAME), eq(WifiConfiguration.INVALID_NETWORK_ID),
3569                 any(WifiSsid.class), eq(BSSID), eq(0), eq(SupplicantState.INACTIVE));
3570     }
3571 
3572     /**
3573      * Tests the handling of state change V13 notification to
3574      * associated after configuring a network.
3575      */
3576     @Test
testStateChangeV13ToAssociatedCallback()3577     public void testStateChangeV13ToAssociatedCallback() throws Exception {
3578         setupMocksForHalV1_3();
3579         executeAndValidateInitializationSequenceV1_3();
3580         int frameworkNetworkId = 6;
3581         executeAndValidateConnectSequence(frameworkNetworkId, false,
3582                 TRANSLATED_SUPPLICANT_SSID.toString());
3583         assertNotNull(mISupplicantStaIfaceCallbackV13);
3584 
3585         mISupplicantStaIfaceCallbackV13.onStateChanged_1_3(
3586                 ISupplicantStaIfaceCallback.State.ASSOCIATED,
3587                 NativeUtil.macAddressToByteArray(BSSID), SUPPLICANT_NETWORK_ID,
3588                 NativeUtil.decodeSsid(SUPPLICANT_SSID), false);
3589 
3590         verify(mWifiMonitor).broadcastSupplicantStateChangeEvent(
3591                 eq(WLAN0_IFACE_NAME), eq(frameworkNetworkId),
3592                 any(WifiSsid.class), eq(BSSID), eq(0), eq(SupplicantState.ASSOCIATED));
3593     }
3594 
3595     /**
3596      * Tests the handling of state change V13 notification to
3597      * completed after configuring a network.
3598      */
3599     @Test
testStateChangeV13ToCompletedCallback()3600     public void testStateChangeV13ToCompletedCallback() throws Exception {
3601         InOrder wifiMonitorInOrder = inOrder(mWifiMonitor);
3602         setupMocksForHalV1_3();
3603         executeAndValidateInitializationSequenceV1_3();
3604         assertNotNull(mISupplicantStaIfaceCallbackV13);
3605         int frameworkNetworkId = 6;
3606         executeAndValidateConnectSequence(frameworkNetworkId, false,
3607                 TRANSLATED_SUPPLICANT_SSID.toString());
3608 
3609         mISupplicantStaIfaceCallbackV13.onStateChanged_1_3(
3610                 ISupplicantStaIfaceCallback.State.COMPLETED,
3611                 NativeUtil.macAddressToByteArray(BSSID), SUPPLICANT_NETWORK_ID,
3612                 NativeUtil.decodeSsid(SUPPLICANT_SSID), false);
3613 
3614         wifiMonitorInOrder.verify(mWifiMonitor).broadcastNetworkConnectionEvent(
3615                 eq(WLAN0_IFACE_NAME), eq(frameworkNetworkId), eq(false),
3616                 eq(TRANSLATED_SUPPLICANT_SSID), eq(BSSID));
3617         wifiMonitorInOrder.verify(mWifiMonitor).broadcastSupplicantStateChangeEvent(
3618                 eq(WLAN0_IFACE_NAME), eq(frameworkNetworkId),
3619                 any(WifiSsid.class), eq(BSSID), eq(0), eq(SupplicantState.COMPLETED));
3620     }
3621 
3622     /**
3623      * Tests the handling of incorrect network passwords, edge case
3624      * when onStateChanged_1_3() is used.
3625      *
3626      * If the network is removed during 4-way handshake, do not call it a password mismatch.
3627      */
3628     @Test
testNetworkRemovedDuring4wayWhenonStateChangedV13IsUsed()3629     public void testNetworkRemovedDuring4wayWhenonStateChangedV13IsUsed() throws Exception {
3630         executeAndValidateInitializationSequence();
3631         assertNotNull(mISupplicantStaIfaceCallback);
3632         setupMocksForHalV1_3();
3633         executeAndValidateInitializationSequenceV1_3();
3634         assertNotNull(mISupplicantStaIfaceCallbackV13);
3635 
3636         int reasonCode = 3;
3637 
3638         mISupplicantStaIfaceCallbackV13.onStateChanged_1_3(
3639                 ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE,
3640                 NativeUtil.macAddressToByteArray(BSSID),
3641                 SUPPLICANT_NETWORK_ID,
3642                 NativeUtil.decodeSsid(SUPPLICANT_SSID), false);
3643         mISupplicantStaIfaceCallback.onNetworkRemoved(SUPPLICANT_NETWORK_ID);
3644         mISupplicantStaIfaceCallback.onDisconnected(
3645                 NativeUtil.macAddressToByteArray(BSSID), true, reasonCode);
3646         verify(mWifiMonitor, times(0)).broadcastAuthenticationFailureEvent(any(), anyInt(),
3647                 anyInt(), any(), any());
3648     }
3649 
3650      /**
3651       * Tests the handling of incorrect network passwords when
3652       * onStateChanged_1_3() is used, edge case.
3653       *
3654       * If the disconnect reason is "IE in 4way differs", do not call it a password mismatch.
3655       */
3656     @Test
testIeDiffersWhenonStateChangedV13IsUsed()3657     public void testIeDiffersWhenonStateChangedV13IsUsed() throws Exception {
3658         executeAndValidateInitializationSequence();
3659         assertNotNull(mISupplicantStaIfaceCallback);
3660         setupMocksForHalV1_3();
3661         executeAndValidateInitializationSequenceV1_3();
3662         assertNotNull(mISupplicantStaIfaceCallbackV13);
3663 
3664         int reasonCode = ISupplicantStaIfaceCallback.ReasonCode.IE_IN_4WAY_DIFFERS;
3665 
3666         mISupplicantStaIfaceCallbackV13.onStateChanged_1_3(
3667                 ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE,
3668                 NativeUtil.macAddressToByteArray(BSSID),
3669                 SUPPLICANT_NETWORK_ID,
3670                 NativeUtil.decodeSsid(SUPPLICANT_SSID), false);
3671         mISupplicantStaIfaceCallback.onDisconnected(
3672                 NativeUtil.macAddressToByteArray(BSSID), true, reasonCode);
3673         verify(mWifiMonitor, times(0)).broadcastAuthenticationFailureEvent(any(), anyInt(),
3674                 anyInt(), any(), any());
3675     }
3676 
3677     /**
3678      * Tests the handling of state change V13 notification to
3679      * completed (with FILS HLP IE sent) after configuring a
3680      * network.
3681      */
3682     @Test
testStateChangeV13WithFilsHlpIESentToCompletedCallback()3683     public void testStateChangeV13WithFilsHlpIESentToCompletedCallback() throws Exception {
3684         InOrder wifiMonitorInOrder = inOrder(mWifiMonitor);
3685         setupMocksForHalV1_3();
3686         executeAndValidateInitializationSequenceV1_3();
3687         assertNotNull(mISupplicantStaIfaceCallbackV13);
3688         int frameworkNetworkId = 6;
3689         executeAndValidateConnectSequence(frameworkNetworkId, false,
3690                 TRANSLATED_SUPPLICANT_SSID.toString());
3691 
3692         mISupplicantStaIfaceCallbackV13.onStateChanged_1_3(
3693                 ISupplicantStaIfaceCallback.State.COMPLETED,
3694                 NativeUtil.macAddressToByteArray(BSSID), SUPPLICANT_NETWORK_ID,
3695                 NativeUtil.decodeSsid(SUPPLICANT_SSID), true);
3696 
3697         wifiMonitorInOrder.verify(mWifiMonitor).broadcastNetworkConnectionEvent(
3698                 eq(WLAN0_IFACE_NAME), eq(frameworkNetworkId), eq(true),
3699                 eq(TRANSLATED_SUPPLICANT_SSID), eq(BSSID));
3700         wifiMonitorInOrder.verify(mWifiMonitor).broadcastSupplicantStateChangeEvent(
3701                 eq(WLAN0_IFACE_NAME), eq(frameworkNetworkId),
3702                 eq(TRANSLATED_SUPPLICANT_SSID), eq(BSSID), eq(0), eq(SupplicantState.COMPLETED));
3703     }
3704 
3705     @Test
testDisableNetworkAfterConnected()3706     public void testDisableNetworkAfterConnected() throws Exception {
3707         when(mSupplicantStaNetworkMock.disable()).thenReturn(true);
3708 
3709         executeAndValidateInitializationSequence();
3710 
3711         // Connect to a network.
3712         executeAndValidateConnectSequence(4, false, TRANSLATED_SUPPLICANT_SSID.toString());
3713 
3714         // Disable it.
3715         assertTrue(mDut.disableCurrentNetwork(WLAN0_IFACE_NAME));
3716         verify(mSupplicantStaNetworkMock).disable();
3717     }
3718 
3719     /**
3720      * Tests the handling of association rejection notification V1_4.
3721      */
3722     @Test
testAssociationRejectionCallback_1_4()3723     public void testAssociationRejectionCallback_1_4() throws Exception {
3724         setupMocksForHalV1_4();
3725         executeAndValidateInitializationSequenceV1_4();
3726         assertNotNull(mISupplicantStaIfaceCallbackV14);
3727         AssociationRejectionData assocRejectData = new AssociationRejectionData();
3728         assocRejectData.ssid = NativeUtil.decodeSsid(SUPPLICANT_SSID);
3729         assocRejectData.bssid = NativeUtil.macAddressToByteArray(BSSID);
3730         assocRejectData.statusCode = 5;
3731         assocRejectData.isOceRssiBasedAssocRejectAttrPresent = true;
3732         assocRejectData.oceRssiBasedAssocRejectData.retryDelayS = 10;
3733         assocRejectData.oceRssiBasedAssocRejectData.deltaRssi = 20;
3734         mISupplicantStaIfaceCallbackV14.onAssociationRejected_1_4(assocRejectData);
3735 
3736         ArgumentCaptor<AssocRejectEventInfo> assocRejectEventInfoCaptor =
3737                 ArgumentCaptor.forClass(AssocRejectEventInfo.class);
3738         verify(mWifiMonitor).broadcastAssociationRejectionEvent(
3739                 eq(WLAN0_IFACE_NAME), assocRejectEventInfoCaptor.capture());
3740         AssocRejectEventInfo assocRejectEventInfo =
3741                 (AssocRejectEventInfo) assocRejectEventInfoCaptor.getValue();
3742         assertNotNull(assocRejectEventInfo);
3743         assertEquals(TRANSLATED_SUPPLICANT_SSID.toString(), assocRejectEventInfo.ssid);
3744         assertEquals(BSSID, assocRejectEventInfo.bssid);
3745         assertEquals(SupplicantStaIfaceCallbackHidlImpl.halToFrameworkStatusCode(
3746                 assocRejectData.statusCode), assocRejectEventInfo.statusCode);
3747         assertFalse(assocRejectEventInfo.timedOut);
3748         assertNotNull(assocRejectEventInfo.oceRssiBasedAssocRejectInfo);
3749         assertEquals(assocRejectData.oceRssiBasedAssocRejectData.retryDelayS,
3750                 assocRejectEventInfo.oceRssiBasedAssocRejectInfo.mRetryDelayS);
3751         assertEquals(assocRejectData.oceRssiBasedAssocRejectData.deltaRssi,
3752                 assocRejectEventInfo.oceRssiBasedAssocRejectInfo.mDeltaRssi);
3753         assertNull(assocRejectEventInfo.mboAssocDisallowedInfo);
3754     }
3755 
3756     /**
3757      * Tests the handling of network not found notification.
3758      */
3759     @Test
testNetworkNotFoundCallback()3760     public void testNetworkNotFoundCallback() throws Exception {
3761         setupMocksForHalV1_4();
3762         executeAndValidateInitializationSequenceV1_4();
3763         assertNotNull(mISupplicantStaIfaceCallbackV14);
3764         mISupplicantStaIfaceCallbackV14.onNetworkNotFound(NativeUtil.decodeSsid(SUPPLICANT_SSID));
3765 
3766         verify(mWifiMonitor).broadcastNetworkNotFoundEvent(
3767                 eq(WLAN0_IFACE_NAME), eq(TRANSLATED_SUPPLICANT_SSID.toString()));
3768     }
3769 
3770     /**
3771      * Tests the handling of network not found notification.
3772      */
3773     @Test
testNetworkNotFoundCallbackTriggersConnectToFallbackSsid()3774     public void testNetworkNotFoundCallbackTriggersConnectToFallbackSsid() throws Exception {
3775         setupMocksForHalV1_4();
3776         executeAndValidateInitializationSequenceV1_4();
3777         assertNotNull(mISupplicantStaIfaceCallbackV14);
3778         // Setup mocks to return two possible original SSIDs. We will pick
3779         // TRANSLATED_SUPPLICANT_SSID as the first SSID to try.
3780         when(mSsidTranslator.getAllPossibleOriginalSsids(TRANSLATED_SUPPLICANT_SSID)).thenAnswer(
3781                 (Answer<List<WifiSsid>>) invocation -> {
3782                     List<WifiSsid> ssids = new ArrayList<>();
3783                     ssids.add(TRANSLATED_SUPPLICANT_SSID);
3784                     ssids.add(WifiSsid.fromString(SUPPLICANT_SSID));
3785                     return ssids;
3786                 });
3787         executeAndValidateConnectSequence(SUPPLICANT_NETWORK_ID, false,
3788                 TRANSLATED_SUPPLICANT_SSID.toString());
3789         mISupplicantStaIfaceCallbackV14.onNetworkNotFound(NativeUtil.decodeSsid(SUPPLICANT_SSID));
3790 
3791         // Validate that we initiated another connect sequence to the fallback SUPPLICANT_SSID.
3792         verify(mWifiMonitor, never()).broadcastNetworkNotFoundEvent(
3793                 eq(WLAN0_IFACE_NAME), eq(TRANSLATED_SUPPLICANT_SSID.toString()));
3794         validateConnectSequence(false, 2, SUPPLICANT_SSID);
3795 
3796         // Fallback SSID was not found, broadcast the network not found event now.
3797         mISupplicantStaIfaceCallbackV14.onNetworkNotFound(NativeUtil.decodeSsid(SUPPLICANT_SSID));
3798         verify(mWifiMonitor).broadcastNetworkNotFoundEvent(
3799                 eq(WLAN0_IFACE_NAME), eq(TRANSLATED_SUPPLICANT_SSID.toString()));
3800     }
3801 
3802     /**
3803      * Tests the behavior of {@link SupplicantStaIfaceHal#getCurrentNetworkSecurityParams(String)}
3804      * @throws Exception
3805      */
3806     @Test
testGetCurrentNetworkSecurityParams()3807     public void testGetCurrentNetworkSecurityParams() throws Exception {
3808         executeAndValidateInitializationSequence();
3809 
3810         // Null current network should return null security params
3811         assertNull(mDut.getCurrentNetworkSecurityParams(WLAN0_IFACE_NAME));
3812 
3813         // Connecting to network with PSK candidate security params should return PSK params.
3814         executeAndValidateConnectSequenceWithKeyMgmt(0, false,
3815                 TRANSLATED_SUPPLICANT_SSID.toString(), WifiConfiguration.SECURITY_TYPE_PSK,
3816                 "97CA326539");
3817         assertTrue(mDut.getCurrentNetworkSecurityParams(WLAN0_IFACE_NAME)
3818                 .isSecurityType(WifiConfiguration.SECURITY_TYPE_PSK));
3819     }
3820 
3821     /**
3822      * Tests that the very first connection attempt failure due to Authentication timeout in PSK
3823      * network is notified as wrong password error.
3824      */
3825     @Test
testPskNetworkAuthenticationTimeOutDueToWrongPasswordInFirstConnectAttempt()3826     public void testPskNetworkAuthenticationTimeOutDueToWrongPasswordInFirstConnectAttempt()
3827             throws Exception {
3828         executeAndValidateInitializationSequence();
3829         assertNotNull(mISupplicantStaIfaceCallback);
3830         executeAndValidateConnectSequenceWithKeyMgmt(
3831                 SUPPLICANT_NETWORK_ID, false, TRANSLATED_SUPPLICANT_SSID.toString(),
3832                 WifiConfiguration.SECURITY_TYPE_PSK, null, false);
3833         mISupplicantStaIfaceCallback.onStateChanged(
3834                 ISupplicantStaIfaceCallback.State.ASSOCIATING,
3835                 NativeUtil.macAddressToByteArray(BSSID), SUPPLICANT_NETWORK_ID,
3836                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
3837         mISupplicantStaIfaceCallback.onStateChanged(
3838                 ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE,
3839                 NativeUtil.macAddressToByteArray(BSSID), SUPPLICANT_NETWORK_ID,
3840                 NativeUtil.decodeSsid(SUPPLICANT_SSID));
3841         mISupplicantStaIfaceCallback.onAuthenticationTimeout(
3842                 NativeUtil.macAddressToByteArray(BSSID));
3843         verify(mWifiMonitor).broadcastAuthenticationFailureEvent(
3844                 eq(WLAN0_IFACE_NAME), eq(WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD), eq(-1),
3845                 eq(TRANSLATED_SUPPLICANT_SSID.toString()), eq(MacAddress.fromString(BSSID)));
3846     }
3847 }
3848