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