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