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 
17 package com.android.server.wifi;
18 
19 import static org.junit.Assert.assertArrayEquals;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertNotEquals;
23 import static org.junit.Assert.assertNotNull;
24 import static org.junit.Assert.assertNull;
25 import static org.junit.Assert.assertTrue;
26 import static org.junit.Assume.assumeTrue;
27 import static org.mockito.ArgumentMatchers.argThat;
28 import static org.mockito.Mockito.any;
29 import static org.mockito.Mockito.anyBoolean;
30 import static org.mockito.Mockito.anyByte;
31 import static org.mockito.Mockito.anyInt;
32 import static org.mockito.Mockito.anyLong;
33 import static org.mockito.Mockito.anyObject;
34 import static org.mockito.Mockito.anyShort;
35 import static org.mockito.Mockito.doAnswer;
36 import static org.mockito.Mockito.doNothing;
37 import static org.mockito.Mockito.doThrow;
38 import static org.mockito.Mockito.eq;
39 import static org.mockito.Mockito.inOrder;
40 import static org.mockito.Mockito.mock;
41 import static org.mockito.Mockito.never;
42 import static org.mockito.Mockito.reset;
43 import static org.mockito.Mockito.spy;
44 import static org.mockito.Mockito.times;
45 import static org.mockito.Mockito.verify;
46 import static org.mockito.Mockito.verifyNoMoreInteractions;
47 import static org.mockito.Mockito.when;
48 
49 import android.app.test.MockAnswerUtil.AnswerWithArguments;
50 import android.content.Context;
51 import android.content.pm.PackageManager;
52 import android.content.res.Resources;
53 import android.hardware.wifi.V1_0.IWifiApIface;
54 import android.hardware.wifi.V1_0.IWifiChip;
55 import android.hardware.wifi.V1_0.IWifiChipEventCallback;
56 import android.hardware.wifi.V1_0.IWifiIface;
57 import android.hardware.wifi.V1_0.IWifiStaIface;
58 import android.hardware.wifi.V1_0.IWifiStaIfaceEventCallback;
59 import android.hardware.wifi.V1_0.IfaceType;
60 import android.hardware.wifi.V1_0.StaApfPacketFilterCapabilities;
61 import android.hardware.wifi.V1_0.StaBackgroundScanCapabilities;
62 import android.hardware.wifi.V1_0.StaBackgroundScanParameters;
63 import android.hardware.wifi.V1_0.StaLinkLayerIfacePacketStats;
64 import android.hardware.wifi.V1_0.StaLinkLayerIfaceStats;
65 import android.hardware.wifi.V1_0.StaLinkLayerRadioStats;
66 import android.hardware.wifi.V1_0.StaLinkLayerStats;
67 import android.hardware.wifi.V1_0.StaRoamingCapabilities;
68 import android.hardware.wifi.V1_0.StaRoamingConfig;
69 import android.hardware.wifi.V1_0.StaRoamingState;
70 import android.hardware.wifi.V1_0.StaScanData;
71 import android.hardware.wifi.V1_0.StaScanDataFlagMask;
72 import android.hardware.wifi.V1_0.StaScanResult;
73 import android.hardware.wifi.V1_0.WifiDebugHostWakeReasonStats;
74 import android.hardware.wifi.V1_0.WifiDebugPacketFateFrameType;
75 import android.hardware.wifi.V1_0.WifiDebugRingBufferFlags;
76 import android.hardware.wifi.V1_0.WifiDebugRingBufferStatus;
77 import android.hardware.wifi.V1_0.WifiDebugRingBufferVerboseLevel;
78 import android.hardware.wifi.V1_0.WifiDebugRxPacketFate;
79 import android.hardware.wifi.V1_0.WifiDebugRxPacketFateReport;
80 import android.hardware.wifi.V1_0.WifiDebugTxPacketFate;
81 import android.hardware.wifi.V1_0.WifiDebugTxPacketFateReport;
82 import android.hardware.wifi.V1_0.WifiInformationElement;
83 import android.hardware.wifi.V1_0.WifiStatus;
84 import android.hardware.wifi.V1_0.WifiStatusCode;
85 import android.hardware.wifi.V1_2.IWifiChipEventCallback.IfaceInfo;
86 import android.hardware.wifi.V1_2.IWifiChipEventCallback.RadioModeInfo;
87 import android.hardware.wifi.V1_3.WifiChannelStats;
88 import android.hardware.wifi.V1_5.IWifiChip.MultiStaUseCase;
89 import android.hardware.wifi.V1_5.StaLinkLayerIfaceContentionTimeStats;
90 import android.hardware.wifi.V1_5.StaPeerInfo;
91 import android.hardware.wifi.V1_5.StaRateStat;
92 import android.hardware.wifi.V1_5.WifiUsableChannel;
93 import android.net.InetAddresses;
94 import android.net.KeepalivePacketData;
95 import android.net.MacAddress;
96 import android.net.NattKeepalivePacketData;
97 import android.net.apf.ApfCapabilities;
98 import android.net.wifi.CoexUnsafeChannel;
99 import android.net.wifi.ScanResult;
100 import android.net.wifi.SoftApConfiguration;
101 import android.net.wifi.WifiAvailableChannel;
102 import android.net.wifi.WifiManager;
103 import android.net.wifi.WifiScanner;
104 import android.net.wifi.WifiSsid;
105 import android.os.Handler;
106 import android.os.RemoteException;
107 import android.os.WorkSource;
108 import android.os.test.TestLooper;
109 import android.system.OsConstants;
110 import android.util.Pair;
111 
112 import androidx.test.filters.SmallTest;
113 
114 import com.android.modules.utils.build.SdkLevel;
115 import com.android.server.wifi.HalDeviceManager.InterfaceDestroyedListener;
116 import com.android.server.wifi.WifiLinkLayerStats.ChannelStats;
117 import com.android.server.wifi.WifiLinkLayerStats.RadioStat;
118 import com.android.server.wifi.WifiNative.RoamingCapabilities;
119 import com.android.server.wifi.WifiNative.RxFateReport;
120 import com.android.server.wifi.WifiNative.TxFateReport;
121 import com.android.server.wifi.util.NativeUtil;
122 import com.android.wifi.resources.R;
123 
124 import org.junit.Before;
125 import org.junit.Test;
126 import org.mockito.ArgumentCaptor;
127 import org.mockito.InOrder;
128 import org.mockito.Mock;
129 import org.mockito.MockitoAnnotations;
130 import org.mockito.stubbing.Answer;
131 
132 import java.net.InetAddress;
133 import java.util.ArrayList;
134 import java.util.Arrays;
135 import java.util.Collections;
136 import java.util.HashSet;
137 import java.util.List;
138 import java.util.Random;
139 import java.util.Set;
140 
141 /**
142  * Unit tests for {@link com.android.server.wifi.WifiVendorHal}.
143  */
144 @SmallTest
145 public class WifiVendorHalTest extends WifiBaseTest {
146 
147     private static final String TEST_IFACE_NAME = "wlan0";
148     private static final String TEST_IFACE_NAME_1 = "wlan1";
149     private static final MacAddress TEST_MAC_ADDRESS = MacAddress.fromString("ee:33:a2:94:10:92");
150     private static final int[] TEST_FREQUENCIES =
151             {2412, 2417, 2422, 2427, 2432, 2437};
152     private static final WorkSource TEST_WORKSOURCE = new WorkSource();
153 
154     private WifiVendorHal mWifiVendorHal;
155     private WifiStatus mWifiStatusSuccess;
156     private WifiStatus mWifiStatusFailure;
157     private WifiStatus mWifiStatusBusy;
158     private WifiLog mWifiLog;
159     private TestLooper mLooper;
160     private Handler mHandler;
161     @Mock
162     private Resources mResources;
163     @Mock
164     private Context mContext;
165     @Mock
166     private PackageManager mPackageManager;
167     @Mock
168     private HalDeviceManager mHalDeviceManager;
169     @Mock
170     private WifiVendorHal.HalDeviceManagerStatusListener mHalDeviceManagerStatusCallbacks;
171     @Mock
172     private IWifiApIface mIWifiApIface;
173     @Mock
174     private android.hardware.wifi.V1_4.IWifiApIface mIWifiApIfaceV14;
175     @Mock
176     private android.hardware.wifi.V1_5.IWifiApIface mIWifiApIfaceV15;
177     @Mock
178     private IWifiChip mIWifiChip;
179     @Mock
180     private android.hardware.wifi.V1_1.IWifiChip mIWifiChipV11;
181     @Mock
182     private android.hardware.wifi.V1_2.IWifiChip mIWifiChipV12;
183     @Mock
184     private android.hardware.wifi.V1_3.IWifiChip mIWifiChipV13;
185     @Mock
186     private android.hardware.wifi.V1_4.IWifiChip mIWifiChipV14;
187     @Mock
188     private android.hardware.wifi.V1_5.IWifiChip mIWifiChipV15;
189     @Mock
190     private IWifiStaIface mIWifiStaIface;
191     @Mock
192     private android.hardware.wifi.V1_2.IWifiStaIface mIWifiStaIfaceV12;
193     @Mock
194     private android.hardware.wifi.V1_3.IWifiStaIface mIWifiStaIfaceV13;
195     @Mock
196     private android.hardware.wifi.V1_5.IWifiStaIface mIWifiStaIfaceV15;
197     private IWifiStaIfaceEventCallback mIWifiStaIfaceEventCallback;
198     private IWifiChipEventCallback mIWifiChipEventCallback;
199     private android.hardware.wifi.V1_2.IWifiChipEventCallback mIWifiChipEventCallbackV12;
200     private android.hardware.wifi.V1_4.IWifiChipEventCallback mIWifiChipEventCallbackV14;
201     @Mock
202     private WifiNative.VendorHalDeathEventHandler mVendorHalDeathHandler;
203     @Mock
204     private WifiNative.VendorHalRadioModeChangeEventHandler mVendorHalRadioModeChangeHandler;
205     @Mock
206     private WifiGlobals mWifiGlobals;
207 
208     /**
209      * Spy used to return the V1_1 IWifiChip mock object to simulate the 1.1 HAL running on the
210      * device.
211      */
212     private class WifiVendorHalSpyV1_1 extends WifiVendorHal {
WifiVendorHalSpyV1_1(Context context, HalDeviceManager halDeviceManager, Handler handler, WifiGlobals wifiGlobals)213         WifiVendorHalSpyV1_1(Context context, HalDeviceManager halDeviceManager, Handler handler,
214                 WifiGlobals wifiGlobals) {
215             super(context, halDeviceManager, handler, wifiGlobals);
216         }
217 
218         @Override
getWifiChipForV1_1Mockable()219         protected android.hardware.wifi.V1_1.IWifiChip getWifiChipForV1_1Mockable() {
220             return mIWifiChipV11;
221         }
222 
223         @Override
getWifiChipForV1_2Mockable()224         protected android.hardware.wifi.V1_2.IWifiChip getWifiChipForV1_2Mockable() {
225             return null;
226         }
227 
228         @Override
getWifiChipForV1_3Mockable()229         protected android.hardware.wifi.V1_3.IWifiChip getWifiChipForV1_3Mockable() {
230             return null;
231         }
232 
233         @Override
getWifiChipForV1_4Mockable()234         protected android.hardware.wifi.V1_4.IWifiChip getWifiChipForV1_4Mockable() {
235             return null;
236         }
237 
238         @Override
getWifiStaIfaceForV1_2Mockable( String ifaceName)239         protected android.hardware.wifi.V1_2.IWifiStaIface getWifiStaIfaceForV1_2Mockable(
240                 String ifaceName) {
241             return null;
242         }
243 
244         @Override
getWifiStaIfaceForV1_3Mockable( String ifaceName)245         protected android.hardware.wifi.V1_3.IWifiStaIface getWifiStaIfaceForV1_3Mockable(
246                 String ifaceName) {
247             return null;
248         }
249 
250         @Override
getWifiStaIfaceForV1_5Mockable( String ifaceName)251         protected android.hardware.wifi.V1_5.IWifiStaIface getWifiStaIfaceForV1_5Mockable(
252                 String ifaceName) {
253             return null;
254         }
255     }
256 
257     /**
258      * Spy used to return the V1_2 IWifiChip and IWifiStaIface mock objects to simulate
259      * the 1.2 HAL running on the device.
260      */
261     private class WifiVendorHalSpyV1_2 extends WifiVendorHalSpyV1_1 {
WifiVendorHalSpyV1_2(Context context, HalDeviceManager halDeviceManager, Handler handler, WifiGlobals wifiGlobals)262         WifiVendorHalSpyV1_2(Context context, HalDeviceManager halDeviceManager, Handler handler,
263                 WifiGlobals wifiGlobals) {
264             super(context, halDeviceManager, handler, wifiGlobals);
265         }
266 
267         @Override
getWifiChipForV1_2Mockable()268         protected android.hardware.wifi.V1_2.IWifiChip getWifiChipForV1_2Mockable() {
269             return mIWifiChipV12;
270         }
271 
272         @Override
getWifiStaIfaceForV1_2Mockable( String ifaceName)273         protected android.hardware.wifi.V1_2.IWifiStaIface getWifiStaIfaceForV1_2Mockable(
274                 String ifaceName) {
275             return mIWifiStaIfaceV12;
276         }
277     }
278 
279     /**
280      * Spy used to return the V1_3 IWifiChip and V1_3 IWifiStaIface mock objects to simulate
281      * the 1.3 HAL running on the device.
282      */
283     private class WifiVendorHalSpyV1_3 extends WifiVendorHalSpyV1_2 {
WifiVendorHalSpyV1_3(Context context, HalDeviceManager halDeviceManager, Handler handler, WifiGlobals wifiGlobals)284         WifiVendorHalSpyV1_3(Context context, HalDeviceManager halDeviceManager, Handler handler,
285                 WifiGlobals wifiGlobals) {
286             super(context, halDeviceManager, handler, wifiGlobals);
287         }
288 
289         @Override
getWifiChipForV1_3Mockable()290         protected android.hardware.wifi.V1_3.IWifiChip getWifiChipForV1_3Mockable() {
291             return mIWifiChipV13;
292         }
293 
294         @Override
getWifiStaIfaceForV1_3Mockable( String ifaceName)295         protected android.hardware.wifi.V1_3.IWifiStaIface getWifiStaIfaceForV1_3Mockable(
296                 String ifaceName) {
297             return mIWifiStaIfaceV13;
298         }
299     }
300 
301     /**
302      * Spy used to return the V1_4 IWifiChip and V1_4 IWifiStaIface mock objects to simulate
303      * the 1.4 HAL running on the device.
304      */
305     private class WifiVendorHalSpyV1_4 extends WifiVendorHalSpyV1_3 {
WifiVendorHalSpyV1_4(Context context, HalDeviceManager halDeviceManager, Handler handler, WifiGlobals wifiGlobals)306         WifiVendorHalSpyV1_4(Context context, HalDeviceManager halDeviceManager, Handler handler,
307                 WifiGlobals wifiGlobals) {
308             super(context, halDeviceManager, handler, wifiGlobals);
309         }
310 
311         @Override
getWifiChipForV1_4Mockable()312         protected android.hardware.wifi.V1_4.IWifiChip getWifiChipForV1_4Mockable() {
313             return mIWifiChipV14;
314         }
315     }
316 
317     /**
318      * Spy used to return the V1_5 IWifiChip and V1_5 IWifiStaIface mock objects to simulate
319      * the 1.5 HAL running on the device.
320      */
321     private class WifiVendorHalSpyV1_5 extends WifiVendorHalSpyV1_4 {
WifiVendorHalSpyV1_5(Context context, HalDeviceManager halDeviceManager, Handler handler, WifiGlobals wifiGlobals)322         WifiVendorHalSpyV1_5(Context context, HalDeviceManager halDeviceManager, Handler handler,
323                 WifiGlobals wifiGlobals) {
324             super(context, halDeviceManager, handler, wifiGlobals);
325         }
326 
327         @Override
getWifiChipForV1_5Mockable()328         protected android.hardware.wifi.V1_5.IWifiChip getWifiChipForV1_5Mockable() {
329             return mIWifiChipV15;
330         }
331 
332         @Override
getWifiStaIfaceForV1_5Mockable( String ifaceName)333         protected android.hardware.wifi.V1_5.IWifiStaIface getWifiStaIfaceForV1_5Mockable(
334                 String ifaceName) {
335             return mIWifiStaIfaceV15;
336         }
337     }
338 
339     /**
340      * Identity function to supply a type to its argument, which is a lambda
341      */
answerWifiStatus(Answer<WifiStatus> statusLambda)342     static Answer<WifiStatus> answerWifiStatus(Answer<WifiStatus> statusLambda) {
343         return (statusLambda);
344     }
345 
346     /**
347      * Sets up for unit test
348      */
349     @Before
setUp()350     public void setUp() throws Exception {
351         MockitoAnnotations.initMocks(this);
352         mWifiLog = new FakeWifiLog();
353         mLooper = new TestLooper();
354         mHandler = new Handler(mLooper.getLooper());
355         mWifiStatusSuccess = new WifiStatus();
356         mWifiStatusSuccess.code = WifiStatusCode.SUCCESS;
357         mWifiStatusFailure = new WifiStatus();
358         mWifiStatusFailure.code = WifiStatusCode.ERROR_UNKNOWN;
359         mWifiStatusFailure.description = "I don't even know what a Mock Turtle is.";
360         mWifiStatusBusy = new WifiStatus();
361         mWifiStatusBusy.code = WifiStatusCode.ERROR_BUSY;
362         mWifiStatusBusy.description = "Don't bother me, kid";
363         when(mIWifiStaIface.enableLinkLayerStatsCollection(false)).thenReturn(mWifiStatusSuccess);
364 
365         // Setup the HalDeviceManager mock's start/stop behaviour. This can be overridden in
366         // individual tests, if needed.
367         doAnswer(new AnswerWithArguments() {
368             public boolean answer() {
369                 when(mHalDeviceManager.isReady()).thenReturn(true);
370                 when(mHalDeviceManager.isStarted()).thenReturn(true);
371                 mHalDeviceManagerStatusCallbacks.onStatusChanged();
372                 mLooper.dispatchAll();
373                 return true;
374             }
375         }).when(mHalDeviceManager).start();
376 
377         doAnswer(new AnswerWithArguments() {
378             public void answer() {
379                 when(mHalDeviceManager.isReady()).thenReturn(true);
380                 when(mHalDeviceManager.isStarted()).thenReturn(false);
381                 mHalDeviceManagerStatusCallbacks.onStatusChanged();
382                 mLooper.dispatchAll();
383             }
384         }).when(mHalDeviceManager).stop();
385         when(mHalDeviceManager.createStaIface(any(), eq(null), any()))
386                 .thenReturn(mIWifiStaIface);
387         when(mHalDeviceManager.createApIface(anyLong(), any(), eq(null), any(), anyBoolean()))
388                 .thenReturn(mIWifiApIface);
389         when(mHalDeviceManager.removeIface(any())).thenReturn(true);
390         when(mHalDeviceManager.getChip(any(IWifiIface.class)))
391                 .thenReturn(mIWifiChip);
392         when(mHalDeviceManager.isSupported()).thenReturn(true);
393         when(mIWifiChip.registerEventCallback(any(IWifiChipEventCallback.class)))
394                 .thenReturn(mWifiStatusSuccess);
395         mIWifiStaIfaceEventCallback = null;
396         when(mIWifiStaIface.registerEventCallback(any(IWifiStaIfaceEventCallback.class)))
397                 .thenAnswer(answerWifiStatus((invocation) -> {
398                     Object[] args = invocation.getArguments();
399                     mIWifiStaIfaceEventCallback = (IWifiStaIfaceEventCallback) args[0];
400                     return (mWifiStatusSuccess);
401                 }));
402         when(mIWifiChip.registerEventCallback(any(IWifiChipEventCallback.class)))
403                 .thenAnswer(answerWifiStatus((invocation) -> {
404                     Object[] args = invocation.getArguments();
405                     mIWifiChipEventCallback = (IWifiChipEventCallback) args[0];
406                     return (mWifiStatusSuccess);
407                 }));
408         when(mIWifiChipV12.registerEventCallback_1_2(
409                 any(android.hardware.wifi.V1_2.IWifiChipEventCallback.class)))
410                 .thenAnswer(answerWifiStatus((invocation) -> {
411                     Object[] args = invocation.getArguments();
412                     mIWifiChipEventCallbackV12 =
413                             (android.hardware.wifi.V1_2.IWifiChipEventCallback) args[0];
414                     return (mWifiStatusSuccess);
415                 }));
416 
417         when(mIWifiChipV14.registerEventCallback_1_4(
418                 any(android.hardware.wifi.V1_4.IWifiChipEventCallback.class)))
419                 .thenAnswer(answerWifiStatus((invocation) -> {
420                     Object[] args = invocation.getArguments();
421                     mIWifiChipEventCallbackV14 =
422                             (android.hardware.wifi.V1_4.IWifiChipEventCallback) args[0];
423                     return (mWifiStatusSuccess);
424                 }));
425 
426         doAnswer(new AnswerWithArguments() {
427             public void answer(IWifiIface.getNameCallback cb)
428                     throws RemoteException {
429                 cb.onValues(mWifiStatusSuccess, TEST_IFACE_NAME);
430             }
431         }).when(mIWifiStaIface).getName(any(IWifiIface.getNameCallback.class));
432         doAnswer(new AnswerWithArguments() {
433             public void answer(IWifiIface.getNameCallback cb)
434                     throws RemoteException {
435                 cb.onValues(mWifiStatusSuccess, TEST_IFACE_NAME);
436             }
437         }).when(mIWifiApIface).getName(any(IWifiIface.getNameCallback.class));
438 
439         when(mContext.getResources()).thenReturn(mResources);
440         when(mResources.getBoolean(R.bool.config_wifiLinkLayerAllRadiosStatsAggregationEnabled))
441                 .thenReturn(false);
442         // Create the vendor HAL object under test.
443         mWifiVendorHal = new WifiVendorHal(mContext, mHalDeviceManager, mHandler, mWifiGlobals);
444 
445         // Initialize the vendor HAL to capture the registered callback.
446         mWifiVendorHal.initialize(mVendorHalDeathHandler);
447         ArgumentCaptor<WifiVendorHal.HalDeviceManagerStatusListener> hdmCallbackCaptor =
448                 ArgumentCaptor.forClass(WifiVendorHal.HalDeviceManagerStatusListener.class);
449         verify(mHalDeviceManager).registerStatusListener(
450                 hdmCallbackCaptor.capture(), any(Handler.class));
451         mHalDeviceManagerStatusCallbacks = hdmCallbackCaptor.getValue();
452 
453     }
454 
455     /**
456      * Tests the successful starting of HAL in STA mode using
457      * {@link WifiVendorHal#startVendorHalSta()}.
458      */
459     @Test
testStartHalSuccessInStaMode()460     public void testStartHalSuccessInStaMode() throws  Exception {
461         assertTrue(mWifiVendorHal.startVendorHalSta());
462         assertTrue(mWifiVendorHal.isHalStarted());
463 
464         verify(mHalDeviceManager).start();
465         verify(mHalDeviceManager).createStaIface(any(), eq(null), any());
466         verify(mHalDeviceManager).getChip(eq(mIWifiStaIface));
467         verify(mHalDeviceManager).isReady();
468         verify(mHalDeviceManager).isStarted();
469         verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class));
470         verify(mIWifiChip).registerEventCallback(any(IWifiChipEventCallback.class));
471 
472         verify(mHalDeviceManager, never()).createApIface(
473                 anyLong(), any(), eq(null), any(), anyBoolean());
474     }
475 
476     /**
477      * Tests the successful starting of HAL in AP mode using
478      * {@link WifiVendorHal#startVendorHalAp()}.
479      */
480     @Test
testStartHalSuccessInApMode()481     public void testStartHalSuccessInApMode() throws Exception {
482         assertTrue(mWifiVendorHal.startVendorHalAp());
483         assertTrue(mWifiVendorHal.isHalStarted());
484 
485         verify(mHalDeviceManager).start();
486         verify(mHalDeviceManager).createApIface(
487                 anyLong(), any(), eq(null), any(), anyBoolean());
488         verify(mHalDeviceManager).getChip(eq(mIWifiApIface));
489         verify(mHalDeviceManager).isReady();
490         verify(mHalDeviceManager).isStarted();
491 
492         verify(mHalDeviceManager, never()).createStaIface(any(), eq(null), any());
493     }
494 
495     /**
496      * Tests the failure to start HAL in STA mode using
497      * {@link WifiVendorHal#startVendorHalSta()}.
498      */
499     @Test
testStartHalFailureInStaMode()500     public void testStartHalFailureInStaMode() throws Exception {
501         // No callbacks are invoked in this case since the start itself failed. So, override
502         // default AnswerWithArguments that we setup.
503         doAnswer(new AnswerWithArguments() {
504             public boolean answer() throws Exception {
505                 return false;
506             }
507         }).when(mHalDeviceManager).start();
508         assertFalse(mWifiVendorHal.startVendorHalSta());
509         assertFalse(mWifiVendorHal.isHalStarted());
510 
511         verify(mHalDeviceManager).start();
512 
513         verify(mHalDeviceManager, never()).createStaIface(any(), eq(null), any());
514         verify(mHalDeviceManager, never()).createApIface(
515                 anyLong(), any(), eq(null), any(), anyBoolean());
516         verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
517         verify(mIWifiStaIface, never())
518                 .registerEventCallback(any(IWifiStaIfaceEventCallback.class));
519     }
520 
521     /**
522      * Tests the failure to start HAL in STA mode using
523      * {@link WifiVendorHal#startVendorHalSta()}.
524      */
525     @Test
testStartHalFailureInIfaceCreationInStaMode()526     public void testStartHalFailureInIfaceCreationInStaMode() throws Exception {
527         when(mHalDeviceManager.createStaIface(any(), eq(null), any())).thenReturn(null);
528         assertFalse(mWifiVendorHal.startVendorHalSta());
529         assertFalse(mWifiVendorHal.isHalStarted());
530 
531         verify(mHalDeviceManager).start();
532         verify(mHalDeviceManager).createStaIface(any(), eq(null), any());
533         verify(mHalDeviceManager).stop();
534 
535         verify(mHalDeviceManager, never()).createApIface(
536                 anyLong(), any(), eq(null), any(), anyBoolean());
537         verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
538         verify(mIWifiStaIface, never())
539                 .registerEventCallback(any(IWifiStaIfaceEventCallback.class));
540     }
541 
542     /**
543      * Tests the failure to start HAL in STA mode using
544      * {@link WifiVendorHal#startVendorHalSta()}.
545      */
546     @Test
testStartHalFailureInChipGetInStaMode()547     public void testStartHalFailureInChipGetInStaMode() throws Exception {
548         when(mHalDeviceManager.getChip(any(IWifiIface.class))).thenReturn(null);
549         assertFalse(mWifiVendorHal.startVendorHalSta());
550         assertFalse(mWifiVendorHal.isHalStarted());
551 
552         verify(mHalDeviceManager).start();
553         verify(mHalDeviceManager).createStaIface(any(), eq(null), any());
554         verify(mHalDeviceManager).getChip(any(IWifiIface.class));
555         verify(mHalDeviceManager).stop();
556         verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class));
557 
558         verify(mHalDeviceManager, never()).createApIface(
559                 anyLong(), any(), eq(null), any(), anyBoolean());
560     }
561 
562     /**
563      * Tests the failure to start HAL in STA mode using
564      * {@link WifiVendorHal#startVendorHalSta()}.
565      */
566     @Test
testStartHalFailureInStaIfaceCallbackRegistration()567     public void testStartHalFailureInStaIfaceCallbackRegistration() throws Exception {
568         when(mIWifiStaIface.registerEventCallback(any(IWifiStaIfaceEventCallback.class)))
569                 .thenReturn(mWifiStatusFailure);
570         assertFalse(mWifiVendorHal.startVendorHalSta());
571         assertFalse(mWifiVendorHal.isHalStarted());
572 
573         verify(mHalDeviceManager).start();
574         verify(mHalDeviceManager).createStaIface(any(), eq(null), any());
575         verify(mHalDeviceManager).stop();
576         verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class));
577 
578         verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
579         verify(mHalDeviceManager, never()).createApIface(
580                 anyLong(), any(), eq(null), any(), anyBoolean());
581     }
582 
583     /**
584      * Tests the failure to start HAL in STA mode using
585      * {@link WifiVendorHal#startVendorHalSta()}.
586      */
587     @Test
testStartHalFailureInChipCallbackRegistration()588     public void testStartHalFailureInChipCallbackRegistration() throws Exception {
589         when(mIWifiChip.registerEventCallback(any(IWifiChipEventCallback.class)))
590                 .thenReturn(mWifiStatusFailure);
591         assertFalse(mWifiVendorHal.startVendorHalSta());
592         assertFalse(mWifiVendorHal.isHalStarted());
593 
594         verify(mHalDeviceManager).start();
595         verify(mHalDeviceManager).createStaIface(any(), eq(null), any());
596         verify(mHalDeviceManager).getChip(any(IWifiIface.class));
597         verify(mHalDeviceManager).stop();
598         verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class));
599         verify(mIWifiChip).registerEventCallback(any(IWifiChipEventCallback.class));
600 
601         verify(mHalDeviceManager, never()).createApIface(
602                 anyLong(), any(), eq(null), any(), anyBoolean());
603     }
604 
605     /**
606      * Tests the failure to start HAL in AP mode using
607      * {@link WifiVendorHal#startVendorHalAp()}.
608      */
609     @Test
testStartHalFailureInApMode()610     public void testStartHalFailureInApMode() throws Exception {
611         when(mHalDeviceManager.createApIface(anyLong(), any(), eq(null), any(), anyBoolean()))
612                 .thenReturn(null);
613         assertFalse(mWifiVendorHal.startVendorHalAp());
614         assertFalse(mWifiVendorHal.isHalStarted());
615 
616         verify(mHalDeviceManager).start();
617         verify(mHalDeviceManager).createApIface(anyLong(), any(), eq(null), any(), anyBoolean());
618         verify(mHalDeviceManager).stop();
619 
620         verify(mHalDeviceManager, never()).createStaIface(any(), eq(null), any());
621         verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
622     }
623 
624     /**
625      * Tests the stopping of HAL in STA mode using
626      * {@link WifiVendorHal#stopVendorHal()}.
627      */
628     @Test
testStopHalInStaMode()629     public void testStopHalInStaMode() {
630         assertTrue(mWifiVendorHal.startVendorHalSta());
631         assertTrue(mWifiVendorHal.isHalStarted());
632 
633         mWifiVendorHal.stopVendorHal();
634         assertFalse(mWifiVendorHal.isHalStarted());
635 
636         verify(mHalDeviceManager).start();
637         verify(mHalDeviceManager).stop();
638         verify(mHalDeviceManager).createStaIface(any(), eq(null), any());
639         verify(mHalDeviceManager).getChip(eq(mIWifiStaIface));
640         verify(mHalDeviceManager, times(2)).isReady();
641         verify(mHalDeviceManager, times(2)).isStarted();
642 
643         verify(mHalDeviceManager, never()).createApIface(
644                 anyLong(), any(), eq(null), any(), anyBoolean());
645     }
646 
647     /**
648      * Tests the stopping of HAL in AP mode using
649      * {@link WifiVendorHal#stopVendorHal()}.
650      */
651     @Test
testStopHalInApMode()652     public void testStopHalInApMode() {
653         assertTrue(mWifiVendorHal.startVendorHalAp());
654         assertTrue(mWifiVendorHal.isHalStarted());
655 
656         mWifiVendorHal.stopVendorHal();
657         assertFalse(mWifiVendorHal.isHalStarted());
658 
659         verify(mHalDeviceManager).start();
660         verify(mHalDeviceManager).stop();
661         verify(mHalDeviceManager).createApIface(
662                 anyLong(), any(), eq(null), any(), anyBoolean());
663         verify(mHalDeviceManager).getChip(eq(mIWifiApIface));
664         verify(mHalDeviceManager, times(2)).isReady();
665         verify(mHalDeviceManager, times(2)).isStarted();
666 
667         verify(mHalDeviceManager, never()).createStaIface(any(), eq(null), any());
668     }
669 
670     /**
671      * Tests the handling of interface destroyed callback from HalDeviceManager.
672      */
673     @Test
testStaInterfaceDestroyedHandling()674     public void testStaInterfaceDestroyedHandling() throws  Exception {
675         ArgumentCaptor<InterfaceDestroyedListener> internalListenerCaptor =
676                 ArgumentCaptor.forClass(InterfaceDestroyedListener.class);
677         InterfaceDestroyedListener externalLister = mock(InterfaceDestroyedListener.class);
678 
679         assertTrue(mWifiVendorHal.startVendorHal());
680         assertNotNull(mWifiVendorHal.createStaIface(externalLister, TEST_WORKSOURCE));
681         assertTrue(mWifiVendorHal.isHalStarted());
682 
683         verify(mHalDeviceManager).start();
684         verify(mHalDeviceManager).createStaIface(internalListenerCaptor.capture(),
685                 eq(null), eq(TEST_WORKSOURCE));
686         verify(mHalDeviceManager).getChip(eq(mIWifiStaIface));
687         verify(mHalDeviceManager).isReady();
688         verify(mHalDeviceManager).isStarted();
689         verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class));
690         verify(mIWifiChip).registerEventCallback(any(IWifiChipEventCallback.class));
691 
692         // Now trigger the interface destroyed callback from HalDeviceManager and ensure the
693         // external listener is invoked and iface removed from internal database.
694         internalListenerCaptor.getValue().onDestroyed(TEST_IFACE_NAME);
695         verify(externalLister).onDestroyed(TEST_IFACE_NAME);
696 
697         // This should fail now, since the interface was already destroyed.
698         assertFalse(mWifiVendorHal.removeStaIface(TEST_IFACE_NAME));
699         verify(mHalDeviceManager, never()).removeIface(any());
700     }
701 
702     /**
703      * Tests the handling of interface destroyed callback from HalDeviceManager.
704      */
705     @Test
testApInterfaceDestroyedHandling()706     public void testApInterfaceDestroyedHandling() throws  Exception {
707         ArgumentCaptor<InterfaceDestroyedListener> internalListenerCaptor =
708                 ArgumentCaptor.forClass(InterfaceDestroyedListener.class);
709         InterfaceDestroyedListener externalLister = mock(InterfaceDestroyedListener.class);
710 
711         assertTrue(mWifiVendorHal.startVendorHal());
712         assertNotNull(mWifiVendorHal.createApIface(
713                 externalLister, TEST_WORKSOURCE, SoftApConfiguration.BAND_2GHZ, false));
714         assertTrue(mWifiVendorHal.isHalStarted());
715 
716         verify(mHalDeviceManager).start();
717         verify(mHalDeviceManager).createApIface(anyLong(),
718                 internalListenerCaptor.capture(), eq(null), eq(TEST_WORKSOURCE), eq(false));
719         verify(mHalDeviceManager).getChip(eq(mIWifiApIface));
720         verify(mHalDeviceManager).isReady();
721         verify(mHalDeviceManager).isStarted();
722         verify(mIWifiChip).registerEventCallback(any(IWifiChipEventCallback.class));
723 
724         // Now trigger the interface destroyed callback from HalDeviceManager and ensure the
725         // external listener is invoked and iface removed from internal database.
726         internalListenerCaptor.getValue().onDestroyed(TEST_IFACE_NAME);
727         verify(externalLister).onDestroyed(TEST_IFACE_NAME);
728 
729         // This should fail now, since the interface was already destroyed.
730         assertFalse(mWifiVendorHal.removeApIface(TEST_IFACE_NAME));
731         verify(mHalDeviceManager, never()).removeIface(any());
732     }
733 
734     /**
735      * Test that enter logs when verbose logging is enabled
736      */
737     @Test
testEnterLogging()738     public void testEnterLogging() {
739         mWifiVendorHal.mLog = spy(mWifiLog);
740         mWifiVendorHal.enableVerboseLogging(true);
741         mWifiVendorHal.installPacketFilter(TEST_IFACE_NAME, new byte[0]);
742         verify(mWifiVendorHal.mLog).trace(eq("filter length %"), eq(1));
743     }
744 
745     /**
746      * Test that enter does not log when verbose logging is not enabled
747      */
748     @Test
testEnterSilenceWhenNotEnabled()749     public void testEnterSilenceWhenNotEnabled() {
750         mWifiVendorHal.mLog = spy(mWifiLog);
751         mWifiVendorHal.installPacketFilter(TEST_IFACE_NAME, new byte[0]);
752         mWifiVendorHal.enableVerboseLogging(true);
753         mWifiVendorHal.enableVerboseLogging(false);
754         mWifiVendorHal.installPacketFilter(TEST_IFACE_NAME, new byte[0]);
755         verify(mWifiVendorHal.mLog, never()).trace(eq("filter length %"), anyInt());
756     }
757 
758     /**
759      * Test that boolResult logs a false result
760      */
761     @Test
testBoolResultFalse()762     public void testBoolResultFalse() {
763         mWifiLog = spy(mWifiLog);
764         mWifiVendorHal.mLog = mWifiLog;
765         mWifiVendorHal.mVerboseLog = mWifiLog;
766         assertFalse(mWifiVendorHal.getBgScanCapabilities(
767                 TEST_IFACE_NAME, new WifiNative.ScanCapabilities()));
768         verify(mWifiLog).err("% returns %");
769     }
770 
771     /**
772      * Test that getBgScanCapabilities is hooked up to the HAL correctly
773      *
774      * A call before the vendor HAL is started should return a non-null result with version 0
775      *
776      * A call after the HAL is started should return the mocked values.
777      */
778     @Test
testGetBgScanCapabilities()779     public void testGetBgScanCapabilities() throws Exception {
780         StaBackgroundScanCapabilities capabilities = new StaBackgroundScanCapabilities();
781         capabilities.maxCacheSize = 12;
782         capabilities.maxBuckets = 34;
783         capabilities.maxApCachePerScan = 56;
784         capabilities.maxReportingThreshold = 78;
785 
786         doAnswer(new AnswerWithArguments() {
787             public void answer(IWifiStaIface.getBackgroundScanCapabilitiesCallback cb)
788                     throws RemoteException {
789                 cb.onValues(mWifiStatusSuccess, capabilities);
790             }
791         }).when(mIWifiStaIface).getBackgroundScanCapabilities(any(
792                 IWifiStaIface.getBackgroundScanCapabilitiesCallback.class));
793 
794         WifiNative.ScanCapabilities result = new WifiNative.ScanCapabilities();
795 
796         // should fail - not started
797         assertFalse(mWifiVendorHal.getBgScanCapabilities(TEST_IFACE_NAME, result));
798         // Start the vendor hal
799         assertTrue(mWifiVendorHal.startVendorHalSta());
800         // should succeed
801         assertTrue(mWifiVendorHal.getBgScanCapabilities(TEST_IFACE_NAME, result));
802 
803         assertEquals(12, result.max_scan_cache_size);
804         assertEquals(34, result.max_scan_buckets);
805         assertEquals(56, result.max_ap_cache_per_scan);
806         assertEquals(78, result.max_scan_reporting_threshold);
807     }
808 
809     /**
810      * Test translation to WifiManager.WIFI_FEATURE_*
811      *
812      * Just do a spot-check with a few feature bits here; since the code is table-
813      * driven we don't have to work hard to exercise all of it.
814      */
815     @Test
testStaIfaceFeatureMaskTranslation()816     public void testStaIfaceFeatureMaskTranslation() {
817         int caps = (
818                 IWifiStaIface.StaIfaceCapabilityMask.BACKGROUND_SCAN
819                 | IWifiStaIface.StaIfaceCapabilityMask.LINK_LAYER_STATS
820             );
821         long expected = (
822                 WifiManager.WIFI_FEATURE_SCANNER
823                 | WifiManager.WIFI_FEATURE_LINK_LAYER_STATS);
824         assertEquals(expected, mWifiVendorHal.wifiFeatureMaskFromStaCapabilities(caps));
825     }
826 
827     /**
828      * Test translation to WifiManager.WIFI_FEATURE_*
829      *
830      * Just do a spot-check with a few feature bits here; since the code is table-
831      * driven we don't have to work hard to exercise all of it.
832      */
833     @Test
testChipFeatureMaskTranslation()834     public void testChipFeatureMaskTranslation() {
835         int caps = (
836                 android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.SET_TX_POWER_LIMIT
837                         | android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.D2D_RTT
838                         | android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.D2AP_RTT
839         );
840         long expected = (
841                 WifiManager.WIFI_FEATURE_TX_POWER_LIMIT
842                         | WifiManager.WIFI_FEATURE_D2D_RTT
843                         | WifiManager.WIFI_FEATURE_D2AP_RTT
844         );
845         assertEquals(expected, mWifiVendorHal.wifiFeatureMaskFromChipCapabilities(caps));
846     }
847 
848     /**
849      * Test translation to WifiManager.WIFI_FEATURE_* for V1.3
850      *
851      * Test the added features in V1.3
852      */
853     @Test
testChipFeatureMaskTranslation_1_3()854     public void testChipFeatureMaskTranslation_1_3() {
855         int caps = (
856                 android.hardware.wifi.V1_3.IWifiChip.ChipCapabilityMask.SET_LATENCY_MODE
857                         | android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.D2D_RTT
858         );
859         long expected = (
860                 WifiManager.WIFI_FEATURE_LOW_LATENCY
861                         | WifiManager.WIFI_FEATURE_D2D_RTT
862         );
863         assertEquals(expected, mWifiVendorHal.wifiFeatureMaskFromChipCapabilities_1_3(caps));
864     }
865 
testGetSupportedFeaturesCommon( int staIfaceHidlCaps, int chipHidlCaps, long expectedFeatureSet)866     private void testGetSupportedFeaturesCommon(
867             int staIfaceHidlCaps, int chipHidlCaps, long expectedFeatureSet) throws Exception {
868         assertTrue(mWifiVendorHal.startVendorHalSta());
869 
870         Set<Integer> halDeviceManagerSupportedIfaces = new HashSet<Integer>() {{
871                 add(IfaceType.STA);
872                 add(IfaceType.P2P);
873             }};
874 
875         doAnswer(new AnswerWithArguments() {
876             public void answer(IWifiStaIface.getCapabilitiesCallback cb) throws RemoteException {
877                 cb.onValues(mWifiStatusSuccess, staIfaceHidlCaps);
878             }
879         }).when(mIWifiStaIface).getCapabilities(any(IWifiStaIface.getCapabilitiesCallback.class));
880 
881         when(mHalDeviceManager.getSupportedIfaceTypes())
882                 .thenReturn(halDeviceManagerSupportedIfaces);
883 
884         assertEquals(expectedFeatureSet, mWifiVendorHal.getSupportedFeatureSet(TEST_IFACE_NAME));
885     }
886     /**
887      * Test get supported features. Tests whether we coalesce information from different sources
888      * (IWifiStaIface, IWifiChip and HalDeviceManager) into the bitmask of supported features
889      * correctly.
890      */
891     @Test
testGetSupportedFeatures()892     public void testGetSupportedFeatures() throws Exception {
893         int staIfaceHidlCaps = (
894                 IWifiStaIface.StaIfaceCapabilityMask.BACKGROUND_SCAN
895                         | IWifiStaIface.StaIfaceCapabilityMask.LINK_LAYER_STATS
896         );
897         int chipHidlCaps =
898                 android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.SET_TX_POWER_LIMIT;
899         when(mWifiGlobals.isWpa3SaeH2eSupported()).thenReturn(true);
900         long expectedFeatureSet = (
901                 WifiManager.WIFI_FEATURE_SCANNER
902                         | WifiManager.WIFI_FEATURE_LINK_LAYER_STATS
903                         | WifiManager.WIFI_FEATURE_TX_POWER_LIMIT
904                         | WifiManager.WIFI_FEATURE_INFRA
905                         | WifiManager.WIFI_FEATURE_P2P
906                         | WifiManager.WIFI_FEATURE_SAE_H2E
907         );
908 
909         doAnswer(new AnswerWithArguments() {
910             public void answer(IWifiChip.getCapabilitiesCallback cb) throws RemoteException {
911                 cb.onValues(mWifiStatusSuccess, chipHidlCaps);
912             }
913         }).when(mIWifiChip).getCapabilities(any(IWifiChip.getCapabilitiesCallback.class));
914 
915         mWifiVendorHal = new WifiVendorHalSpyV1_1(mContext, mHalDeviceManager, mHandler,
916                 mWifiGlobals);
917         testGetSupportedFeaturesCommon(staIfaceHidlCaps, chipHidlCaps, expectedFeatureSet);
918     }
919 
920     /**
921      * Test get supported features. Tests whether we coalesce information from different sources
922      * (IWifiStaIface, IWifiChip and HalDeviceManager) into the bitmask of supported features
923      * correctly.
924      */
925     @Test
testGetSupportedFeaturesForHalV1_3()926     public void testGetSupportedFeaturesForHalV1_3() throws Exception {
927         assertTrue(mWifiVendorHal.startVendorHalSta());
928 
929         int staIfaceHidlCaps = (
930                 IWifiStaIface.StaIfaceCapabilityMask.BACKGROUND_SCAN
931                         | IWifiStaIface.StaIfaceCapabilityMask.LINK_LAYER_STATS
932         );
933         int chipHidlCaps =
934                 android.hardware.wifi.V1_3.IWifiChip.ChipCapabilityMask.SET_LATENCY_MODE
935                         | android.hardware.wifi.V1_3.IWifiChip.ChipCapabilityMask.P2P_RAND_MAC;
936         long expectedFeatureSet = (
937                 WifiManager.WIFI_FEATURE_SCANNER
938                         | WifiManager.WIFI_FEATURE_LINK_LAYER_STATS
939                         | WifiManager.WIFI_FEATURE_LOW_LATENCY
940                         | WifiManager.WIFI_FEATURE_P2P_RAND_MAC
941                         | WifiManager.WIFI_FEATURE_INFRA
942                         | WifiManager.WIFI_FEATURE_P2P
943         );
944 
945         doAnswer(new AnswerWithArguments() {
946             public void answer(
947                     android.hardware.wifi.V1_3.IWifiChip.getCapabilities_1_3Callback cb)
948                     throws RemoteException {
949                 cb.onValues(mWifiStatusSuccess, chipHidlCaps);
950             }
951         }).when(mIWifiChipV13).getCapabilities_1_3(
952                 any(android.hardware.wifi.V1_3.IWifiChip.getCapabilities_1_3Callback.class));
953 
954         mWifiVendorHal = new WifiVendorHalSpyV1_3(mContext, mHalDeviceManager, mHandler,
955                 mWifiGlobals);
956         testGetSupportedFeaturesCommon(staIfaceHidlCaps, chipHidlCaps, expectedFeatureSet);
957     }
958 
959     /**
960      * Test get supported features. Tests whether we coalesce information from different sources
961      * (IWifiStaIface, IWifiChip and HalDeviceManager) into the bitmask of supported features
962      * correctly.
963      */
964     @Test
testGetSupportedFeaturesForHalV1_5()965     public void testGetSupportedFeaturesForHalV1_5() throws Exception {
966         assertTrue(mWifiVendorHal.startVendorHalSta());
967 
968         int staIfaceHidlCaps = (
969                 IWifiStaIface.StaIfaceCapabilityMask.BACKGROUND_SCAN
970                         | IWifiStaIface.StaIfaceCapabilityMask.LINK_LAYER_STATS
971         );
972         int chipHidlCaps = android.hardware.wifi.V1_5.IWifiChip.ChipCapabilityMask.WIGIG;
973         long expectedFeatureSet = (
974                 WifiManager.WIFI_FEATURE_SCANNER
975                         | WifiManager.WIFI_FEATURE_LINK_LAYER_STATS
976                         | WifiManager.WIFI_FEATURE_INFRA_60G
977                         | WifiManager.WIFI_FEATURE_INFRA
978                         | WifiManager.WIFI_FEATURE_P2P
979         );
980 
981         doAnswer(new AnswerWithArguments() {
982             public void answer(
983                     android.hardware.wifi.V1_5.IWifiChip.getCapabilities_1_5Callback cb)
984                     throws RemoteException {
985                 cb.onValues(mWifiStatusSuccess, chipHidlCaps);
986             }
987         }).when(mIWifiChipV15).getCapabilities_1_5(
988                 any(android.hardware.wifi.V1_5.IWifiChip.getCapabilities_1_5Callback.class));
989 
990         mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler,
991                 mWifiGlobals);
992         testGetSupportedFeaturesCommon(staIfaceHidlCaps, chipHidlCaps, expectedFeatureSet);
993     }
994 
995     /**
996      * Test get supported features. Tests whether we coalesce information from package manager
997      * if vendor hal is not supported.
998      */
999     @Test
testGetSupportedFeaturesFromPackageManager()1000     public void testGetSupportedFeaturesFromPackageManager() throws Exception {
1001         doAnswer(new AnswerWithArguments() {
1002             public boolean answer() throws Exception {
1003                 return false;
1004             }
1005         }).when(mHalDeviceManager).start();
1006         when(mHalDeviceManager.isSupported()).thenReturn(false);
1007         assertFalse(mWifiVendorHal.startVendorHalSta());
1008 
1009         when(mContext.getPackageManager()).thenReturn(mPackageManager);
1010         when(mPackageManager.hasSystemFeature(eq(PackageManager.FEATURE_WIFI)))
1011                 .thenReturn(true);
1012         when(mPackageManager.hasSystemFeature(eq(PackageManager.FEATURE_WIFI_DIRECT)))
1013                 .thenReturn(true);
1014         when(mPackageManager.hasSystemFeature(eq(PackageManager.FEATURE_WIFI_AWARE)))
1015                 .thenReturn(true);
1016 
1017         long expectedFeatureSet = (
1018                 WifiManager.WIFI_FEATURE_INFRA
1019                         | WifiManager.WIFI_FEATURE_P2P
1020                         | WifiManager.WIFI_FEATURE_AWARE
1021         );
1022 
1023         mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler,
1024                 mWifiGlobals);
1025         assertEquals(expectedFeatureSet, mWifiVendorHal.getSupportedFeatureSet(TEST_IFACE_NAME));
1026     }
1027 
1028     /**
1029      * Test |getFactoryMacAddress| gets called when the hal version is V1_3
1030      * @throws Exception
1031      */
1032     @Test
testGetStaFactoryMacWithHalV1_3()1033     public void testGetStaFactoryMacWithHalV1_3() throws Exception {
1034         doAnswer(new AnswerWithArguments() {
1035             public void answer(
1036                     android.hardware.wifi.V1_3.IWifiStaIface.getFactoryMacAddressCallback cb)
1037                     throws RemoteException {
1038                 cb.onValues(mWifiStatusSuccess, MacAddress.BROADCAST_ADDRESS.toByteArray());
1039             }
1040         }).when(mIWifiStaIfaceV13).getFactoryMacAddress(any(
1041                 android.hardware.wifi.V1_3.IWifiStaIface.getFactoryMacAddressCallback.class));
1042         mWifiVendorHal = new WifiVendorHalSpyV1_3(mContext, mHalDeviceManager, mHandler,
1043                 mWifiGlobals);
1044         assertEquals(MacAddress.BROADCAST_ADDRESS.toString(),
1045                 mWifiVendorHal.getStaFactoryMacAddress(TEST_IFACE_NAME).toString());
1046         verify(mIWifiStaIfaceV13).getFactoryMacAddress(any());
1047     }
1048 
1049     /**
1050      * Test enablement of link layer stats after startup
1051      *
1052      * Request link layer stats before HAL start
1053      * - should not make it to the HAL layer
1054      * Start the HAL in STA mode
1055      * Request link layer stats twice more
1056      * - enable request should make it to the HAL layer
1057      * - HAL layer should have been called to make the requests (i.e., two calls total)
1058      */
1059     @Test
testLinkLayerStatsEnableAfterStartup()1060     public void testLinkLayerStatsEnableAfterStartup() throws Exception {
1061         doNothing().when(mIWifiStaIface).getLinkLayerStats(any());
1062 
1063         assertNull(mWifiVendorHal.getWifiLinkLayerStats(TEST_IFACE_NAME));
1064         assertTrue(mWifiVendorHal.startVendorHalSta());
1065         assertTrue(mWifiVendorHal.isHalStarted());
1066 
1067         verify(mHalDeviceManager).start();
1068         mWifiVendorHal.getWifiLinkLayerStats(TEST_IFACE_NAME);
1069         mWifiVendorHal.getWifiLinkLayerStats(TEST_IFACE_NAME);
1070         verify(mIWifiStaIface).enableLinkLayerStatsCollection(false); // mLinkLayerStatsDebug
1071         verify(mIWifiStaIface, times(2)).getLinkLayerStats(any());
1072     }
1073 
1074     /**
1075      * Test getLinkLayerStats_1_3 gets called when the hal version is V1_3.
1076      */
1077     @Test
testLinkLayerStatsCorrectVersionWithHalV1_3()1078     public void testLinkLayerStatsCorrectVersionWithHalV1_3() throws Exception {
1079         mWifiVendorHal = new WifiVendorHalSpyV1_3(mContext, mHalDeviceManager, mHandler,
1080                 mWifiGlobals);
1081         mWifiVendorHal.getWifiLinkLayerStats(TEST_IFACE_NAME);
1082         verify(mIWifiStaIfaceV13).getLinkLayerStats_1_3(any());
1083     }
1084 
1085     /**
1086      * Test getLinkLayerStats_1_5 gets called when the hal version is V1_5.
1087      */
1088     @Test
testLinkLayerStatsCorrectVersionWithHalV1_5()1089     public void testLinkLayerStatsCorrectVersionWithHalV1_5() throws Exception {
1090         mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler,
1091                 mWifiGlobals);
1092         mWifiVendorHal.getWifiLinkLayerStats(TEST_IFACE_NAME);
1093         verify(mIWifiStaIfaceV15).getLinkLayerStats_1_5(any());
1094     }
1095 
1096     /**
1097      * Test that link layer stats are not enabled and harmless in AP mode
1098      *
1099      * Start the HAL in AP mode
1100      * - stats should not be enabled
1101      * Request link layer stats
1102      * - HAL layer should have been called to make the request
1103      */
1104     @Test
testLinkLayerStatsNotEnabledAndHarmlessInApMode()1105     public void testLinkLayerStatsNotEnabledAndHarmlessInApMode() throws Exception {
1106         doNothing().when(mIWifiStaIface).getLinkLayerStats(any());
1107 
1108         assertTrue(mWifiVendorHal.startVendorHalAp());
1109         assertTrue(mWifiVendorHal.isHalStarted());
1110         assertNull(mWifiVendorHal.getWifiLinkLayerStats(TEST_IFACE_NAME));
1111 
1112         verify(mHalDeviceManager).start();
1113 
1114         verify(mIWifiStaIface, never()).enableLinkLayerStatsCollection(false);
1115         verify(mIWifiStaIface, never()).getLinkLayerStats(any());
1116     }
1117 
1118     /**
1119      * Test that the link layer stats fields are populated correctly.
1120      *
1121      * This is done by filling Hal LinkLayerStats (V1_0) with random values, converting it to
1122      * WifiLinkLayerStats and then asserting the values in the original structure are equal to the
1123      * values in the converted structure.
1124      */
1125     @Test
testLinkLayerStatsAssignment()1126     public void testLinkLayerStatsAssignment() throws Exception {
1127         Random r = new Random(1775968256);
1128         StaLinkLayerStats stats = new StaLinkLayerStats();
1129         randomizePacketStats(r, stats.iface.wmeBePktStats);
1130         randomizePacketStats(r, stats.iface.wmeBkPktStats);
1131         randomizePacketStats(r, stats.iface.wmeViPktStats);
1132         randomizePacketStats(r, stats.iface.wmeVoPktStats);
1133         randomizeRadioStats(r, stats.radios);
1134         stats.timeStampInMs = r.nextLong() & 0xFFFFFFFFFFL;
1135 
1136         WifiLinkLayerStats converted = WifiVendorHal.frameworkFromHalLinkLayerStats(stats);
1137 
1138         verifyIFaceStats(stats.iface, converted);
1139         verifyRadioStats(stats.radios, converted);
1140         assertEquals(stats.timeStampInMs, converted.timeStampInMs);
1141         assertEquals(WifiLinkLayerStats.V1_0, converted.version);
1142     }
1143 
1144     /**
1145      * Test that the link layer stats V1_3 fields are populated correctly.
1146      *
1147      * This is done by filling Hal LinkLayerStats (V1_3) with random values, converting it to
1148      * WifiLinkLayerStats and then asserting the values in the original structure are equal to the
1149      * values in the converted structure.
1150      */
1151     @Test
testLinkLayerStatsAssignment_1_3()1152     public void testLinkLayerStatsAssignment_1_3() throws Exception {
1153         Random r = new Random(1775968256);
1154         android.hardware.wifi.V1_3.StaLinkLayerStats stats =
1155                 new android.hardware.wifi.V1_3.StaLinkLayerStats();
1156         randomizePacketStats(r, stats.iface.wmeBePktStats);
1157         randomizePacketStats(r, stats.iface.wmeBkPktStats);
1158         randomizePacketStats(r, stats.iface.wmeViPktStats);
1159         randomizePacketStats(r, stats.iface.wmeVoPktStats);
1160         android.hardware.wifi.V1_3.StaLinkLayerRadioStats rstat =
1161                 new android.hardware.wifi.V1_3.StaLinkLayerRadioStats();
1162         randomizeRadioStats_1_3(r, rstat);
1163         stats.radios.add(rstat);
1164         stats.timeStampInMs = r.nextLong() & 0xFFFFFFFFFFL;
1165 
1166         WifiLinkLayerStats converted = WifiVendorHal.frameworkFromHalLinkLayerStats_1_3(stats);
1167 
1168         verifyIFaceStats(stats.iface, converted);
1169         verifyRadioStats_1_3(stats.radios.get(0), converted);
1170         assertEquals(stats.timeStampInMs, converted.timeStampInMs);
1171         assertEquals(WifiLinkLayerStats.V1_3, converted.version);
1172         assertEquals(1, converted.numRadios);
1173     }
1174 
1175     /**
1176      * Test that the link layer stats V1_5 fields are populated correctly.
1177      *
1178      * This is done by filling Hal LinkLayerStats (V1_5) with random values, converting it to
1179      * WifiLinkLayerStats and then asserting the values in the original structure are equal to the
1180      * values in the converted structure.
1181      */
1182     @Test
testLinkLayerStatsAssignment_1_5()1183     public void testLinkLayerStatsAssignment_1_5() throws Exception {
1184         Random r = new Random(1775968256);
1185         android.hardware.wifi.V1_5.StaLinkLayerStats stats =
1186                 new android.hardware.wifi.V1_5.StaLinkLayerStats();
1187         randomizePacketStats(r, stats.iface.V1_0.wmeBePktStats);
1188         randomizePacketStats(r, stats.iface.V1_0.wmeBkPktStats);
1189         randomizePacketStats(r, stats.iface.V1_0.wmeViPktStats);
1190         randomizePacketStats(r, stats.iface.V1_0.wmeVoPktStats);
1191         android.hardware.wifi.V1_5.StaLinkLayerRadioStats rstat =
1192                 new android.hardware.wifi.V1_5.StaLinkLayerRadioStats();
1193         randomizeRadioStats_1_5(r, rstat);
1194         stats.radios.add(rstat);
1195         stats.timeStampInMs = r.nextLong() & 0xFFFFFFFFFFL;
1196         randomizeContentionTimeStats(r, stats.iface.wmeBeContentionTimeStats);
1197         randomizeContentionTimeStats(r, stats.iface.wmeBkContentionTimeStats);
1198         randomizeContentionTimeStats(r, stats.iface.wmeViContentionTimeStats);
1199         randomizeContentionTimeStats(r, stats.iface.wmeVoContentionTimeStats);
1200         randomizePeerInfoStats(r, stats.iface.peers);
1201 
1202         WifiLinkLayerStats converted = WifiVendorHal.frameworkFromHalLinkLayerStats_1_5(stats);
1203 
1204         verifyIFaceStats(stats.iface.V1_0, converted);
1205         verifyIFaceStats_1_5(stats.iface, converted);
1206         verifyPerRadioStats(stats.radios, converted);
1207         verifyRadioStats_1_5(stats.radios.get(0), converted);
1208         assertEquals(stats.timeStampInMs, converted.timeStampInMs);
1209         assertEquals(WifiLinkLayerStats.V1_5, converted.version);
1210         assertEquals(1, converted.numRadios);
1211     }
1212 
1213     /**
1214      * Test that the link layer stats V1_3 fields are aggregated correctly for two radios.
1215      *
1216      * This is done by filling multiple Hal LinkLayerStats (V1_3) with random values,
1217      * converting it to WifiLinkLayerStats and then asserting the sum of values from HAL structure
1218      * are equal to the values in the converted structure.
1219      */
1220     @Test
testTwoRadioStatsAggregation_1_3()1221     public void testTwoRadioStatsAggregation_1_3() throws Exception {
1222         when(mResources.getBoolean(R.bool.config_wifiLinkLayerAllRadiosStatsAggregationEnabled))
1223                 .thenReturn(true);
1224         Random r = new Random(245786856);
1225         android.hardware.wifi.V1_3.StaLinkLayerStats stats =
1226                 new android.hardware.wifi.V1_3.StaLinkLayerStats();
1227         // Fill stats in two radios
1228         for (int i = 0; i < 2; i++) {
1229             android.hardware.wifi.V1_3.StaLinkLayerRadioStats rstat =
1230                     new android.hardware.wifi.V1_3.StaLinkLayerRadioStats();
1231             randomizeRadioStats_1_3(r, rstat);
1232             stats.radios.add(rstat);
1233         }
1234 
1235         WifiLinkLayerStats converted = WifiVendorHal.frameworkFromHalLinkLayerStats_1_3(stats);
1236         verifyTwoRadioStatsAggregation_1_3(stats.radios, converted);
1237         assertEquals(2, converted.numRadios);
1238     }
1239 
1240     /**
1241      * Test that the link layer stats V1_3 fields are not aggregated on setting
1242      * config_wifiLinkLayerAllRadiosStatsAggregationEnabled to false(Default value).
1243      *
1244      * This is done by filling multiple Hal LinkLayerStats (V1_3) with random values,
1245      * converting it to WifiLinkLayerStats and then asserting the values from radio 0
1246      * are equal to the values in the converted structure.
1247      */
1248     @Test
testRadioStatsAggregationDisabled_1_3()1249     public void testRadioStatsAggregationDisabled_1_3() throws Exception {
1250         Random r = new Random(245786856);
1251         android.hardware.wifi.V1_3.StaLinkLayerStats stats =
1252                 new android.hardware.wifi.V1_3.StaLinkLayerStats();
1253         // Fill stats in two radios
1254         for (int i = 0; i < 2; i++) {
1255             android.hardware.wifi.V1_3.StaLinkLayerRadioStats rstat =
1256                     new android.hardware.wifi.V1_3.StaLinkLayerRadioStats();
1257             randomizeRadioStats_1_3(r, rstat);
1258             stats.radios.add(rstat);
1259         }
1260 
1261         WifiLinkLayerStats converted = WifiVendorHal.frameworkFromHalLinkLayerStats_1_3(stats);
1262         verifyRadioStats_1_3(stats.radios.get(0), converted);
1263         assertEquals(1, converted.numRadios);
1264     }
1265 
1266     /**
1267      * Test that the link layer stats V1_5 fields are aggregated correctly for two radios.
1268      *
1269      * This is done by filling multiple Hal LinkLayerStats (V1_5) with random values,
1270      * converting it to WifiLinkLayerStats and then asserting the sum of values from HAL structure
1271      * are equal to the values in the converted structure.
1272      */
1273     @Test
testTwoRadioStatsAggregation_1_5()1274     public void testTwoRadioStatsAggregation_1_5() throws Exception {
1275         when(mResources.getBoolean(R.bool.config_wifiLinkLayerAllRadiosStatsAggregationEnabled))
1276                 .thenReturn(true);
1277         Random r = new Random(245786856);
1278         android.hardware.wifi.V1_5.StaLinkLayerStats stats =
1279                 new android.hardware.wifi.V1_5.StaLinkLayerStats();
1280         // Fill stats in two radios
1281         for (int i = 0; i < 2; i++) {
1282             android.hardware.wifi.V1_5.StaLinkLayerRadioStats rstat =
1283                     new android.hardware.wifi.V1_5.StaLinkLayerRadioStats();
1284             randomizeRadioStats_1_5(r, rstat);
1285             stats.radios.add(rstat);
1286         }
1287 
1288         WifiLinkLayerStats converted = WifiVendorHal.frameworkFromHalLinkLayerStats_1_5(stats);
1289         verifyPerRadioStats(stats.radios, converted);
1290         verifyTwoRadioStatsAggregation_1_5(stats.radios, converted);
1291         assertEquals(2, converted.numRadios);
1292     }
1293 
1294     /**
1295      * Test that the link layer stats V1_5 fields are not aggregated on setting
1296      * config_wifiLinkLayerAllRadiosStatsAggregationEnabled to false(Default value).
1297      *
1298      * This is done by filling multiple Hal LinkLayerStats (V1_5) with random values,
1299      * converting it to WifiLinkLayerStats and then asserting the values from radio 0
1300      * are equal to the values in the converted structure.
1301      */
1302     @Test
testRadioStatsAggregationDisabled_1_5()1303     public void testRadioStatsAggregationDisabled_1_5() throws Exception {
1304         Random r = new Random(245786856);
1305         android.hardware.wifi.V1_5.StaLinkLayerStats stats =
1306                 new android.hardware.wifi.V1_5.StaLinkLayerStats();
1307         // Fill stats in two radios
1308         for (int i = 0; i < 2; i++) {
1309             android.hardware.wifi.V1_5.StaLinkLayerRadioStats rstat =
1310                     new android.hardware.wifi.V1_5.StaLinkLayerRadioStats();
1311             randomizeRadioStats_1_5(r, rstat);
1312             stats.radios.add(rstat);
1313         }
1314 
1315         WifiLinkLayerStats converted = WifiVendorHal.frameworkFromHalLinkLayerStats_1_5(stats);
1316         verifyPerRadioStats(stats.radios, converted);
1317         verifyRadioStats_1_5(stats.radios.get(0), converted);
1318         assertEquals(1, converted.numRadios);
1319     }
1320 
verifyIFaceStats(StaLinkLayerIfaceStats iface, WifiLinkLayerStats wifiLinkLayerStats)1321     private void verifyIFaceStats(StaLinkLayerIfaceStats iface,
1322             WifiLinkLayerStats wifiLinkLayerStats) {
1323         assertEquals(iface.beaconRx, wifiLinkLayerStats.beacon_rx);
1324         assertEquals(iface.avgRssiMgmt, wifiLinkLayerStats.rssi_mgmt);
1325 
1326         assertEquals(iface.wmeBePktStats.rxMpdu, wifiLinkLayerStats.rxmpdu_be);
1327         assertEquals(iface.wmeBePktStats.txMpdu, wifiLinkLayerStats.txmpdu_be);
1328         assertEquals(iface.wmeBePktStats.lostMpdu, wifiLinkLayerStats.lostmpdu_be);
1329         assertEquals(iface.wmeBePktStats.retries, wifiLinkLayerStats.retries_be);
1330 
1331         assertEquals(iface.wmeBkPktStats.rxMpdu, wifiLinkLayerStats.rxmpdu_bk);
1332         assertEquals(iface.wmeBkPktStats.txMpdu, wifiLinkLayerStats.txmpdu_bk);
1333         assertEquals(iface.wmeBkPktStats.lostMpdu, wifiLinkLayerStats.lostmpdu_bk);
1334         assertEquals(iface.wmeBkPktStats.retries, wifiLinkLayerStats.retries_bk);
1335 
1336         assertEquals(iface.wmeViPktStats.rxMpdu, wifiLinkLayerStats.rxmpdu_vi);
1337         assertEquals(iface.wmeViPktStats.txMpdu, wifiLinkLayerStats.txmpdu_vi);
1338         assertEquals(iface.wmeViPktStats.lostMpdu, wifiLinkLayerStats.lostmpdu_vi);
1339         assertEquals(iface.wmeViPktStats.retries, wifiLinkLayerStats.retries_vi);
1340 
1341         assertEquals(iface.wmeVoPktStats.rxMpdu, wifiLinkLayerStats.rxmpdu_vo);
1342         assertEquals(iface.wmeVoPktStats.txMpdu, wifiLinkLayerStats.txmpdu_vo);
1343         assertEquals(iface.wmeVoPktStats.lostMpdu, wifiLinkLayerStats.lostmpdu_vo);
1344         assertEquals(iface.wmeVoPktStats.retries, wifiLinkLayerStats.retries_vo);
1345     }
1346 
verifyIFaceStats_1_5(android.hardware.wifi.V1_5.StaLinkLayerIfaceStats iface, WifiLinkLayerStats wifiLinkLayerStats)1347     private void verifyIFaceStats_1_5(android.hardware.wifi.V1_5.StaLinkLayerIfaceStats iface,
1348             WifiLinkLayerStats wifiLinkLayerStats) {
1349         assertEquals(iface.wmeBeContentionTimeStats.contentionTimeMinInUsec,
1350                 wifiLinkLayerStats.contentionTimeMinBeInUsec);
1351         assertEquals(iface.wmeBeContentionTimeStats.contentionTimeMaxInUsec,
1352                 wifiLinkLayerStats.contentionTimeMaxBeInUsec);
1353         assertEquals(iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec,
1354                 wifiLinkLayerStats.contentionTimeAvgBeInUsec);
1355         assertEquals(iface.wmeBeContentionTimeStats.contentionNumSamples,
1356                 wifiLinkLayerStats.contentionNumSamplesBe);
1357 
1358         assertEquals(iface.wmeBkContentionTimeStats.contentionTimeMinInUsec,
1359                 wifiLinkLayerStats.contentionTimeMinBkInUsec);
1360         assertEquals(iface.wmeBkContentionTimeStats.contentionTimeMaxInUsec,
1361                 wifiLinkLayerStats.contentionTimeMaxBkInUsec);
1362         assertEquals(iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec,
1363                 wifiLinkLayerStats.contentionTimeAvgBkInUsec);
1364         assertEquals(iface.wmeBkContentionTimeStats.contentionNumSamples,
1365                 wifiLinkLayerStats.contentionNumSamplesBk);
1366 
1367         assertEquals(iface.wmeViContentionTimeStats.contentionTimeMinInUsec,
1368                 wifiLinkLayerStats.contentionTimeMinViInUsec);
1369         assertEquals(iface.wmeViContentionTimeStats.contentionTimeMaxInUsec,
1370                 wifiLinkLayerStats.contentionTimeMaxViInUsec);
1371         assertEquals(iface.wmeViContentionTimeStats.contentionTimeAvgInUsec,
1372                 wifiLinkLayerStats.contentionTimeAvgViInUsec);
1373         assertEquals(iface.wmeViContentionTimeStats.contentionNumSamples,
1374                 wifiLinkLayerStats.contentionNumSamplesVi);
1375 
1376         assertEquals(iface.wmeVoContentionTimeStats.contentionTimeMinInUsec,
1377                 wifiLinkLayerStats.contentionTimeMinVoInUsec);
1378         assertEquals(iface.wmeVoContentionTimeStats.contentionTimeMaxInUsec,
1379                 wifiLinkLayerStats.contentionTimeMaxVoInUsec);
1380         assertEquals(iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec,
1381                 wifiLinkLayerStats.contentionTimeAvgVoInUsec);
1382         assertEquals(iface.wmeVoContentionTimeStats.contentionNumSamples,
1383                 wifiLinkLayerStats.contentionNumSamplesVo);
1384 
1385         for (int i = 0; i < iface.peers.size(); i++) {
1386             assertEquals(iface.peers.get(i).staCount, wifiLinkLayerStats.peerInfo[i].staCount);
1387             assertEquals(iface.peers.get(i).chanUtil, wifiLinkLayerStats.peerInfo[i].chanUtil);
1388             for (int j = 0; j < iface.peers.get(i).rateStats.size(); j++) {
1389                 assertEquals(iface.peers.get(i).rateStats.get(j).rateInfo.preamble,
1390                         wifiLinkLayerStats.peerInfo[i].rateStats[j].preamble);
1391                 assertEquals(iface.peers.get(i).rateStats.get(j).rateInfo.nss,
1392                         wifiLinkLayerStats.peerInfo[i].rateStats[j].nss);
1393                 assertEquals(iface.peers.get(i).rateStats.get(j).rateInfo.bw,
1394                         wifiLinkLayerStats.peerInfo[i].rateStats[j].bw);
1395                 assertEquals(iface.peers.get(i).rateStats.get(j).rateInfo.rateMcsIdx,
1396                         wifiLinkLayerStats.peerInfo[i].rateStats[j].rateMcsIdx);
1397                 assertEquals(iface.peers.get(i).rateStats.get(j).rateInfo.bitRateInKbps,
1398                         wifiLinkLayerStats.peerInfo[i].rateStats[j].bitRateInKbps);
1399                 assertEquals(iface.peers.get(i).rateStats.get(j).txMpdu,
1400                         wifiLinkLayerStats.peerInfo[i].rateStats[j].txMpdu);
1401                 assertEquals(iface.peers.get(i).rateStats.get(j).rxMpdu,
1402                         wifiLinkLayerStats.peerInfo[i].rateStats[j].rxMpdu);
1403                 assertEquals(iface.peers.get(i).rateStats.get(j).mpduLost,
1404                         wifiLinkLayerStats.peerInfo[i].rateStats[j].mpduLost);
1405                 assertEquals(iface.peers.get(i).rateStats.get(j).retries,
1406                         wifiLinkLayerStats.peerInfo[i].rateStats[j].retries);
1407             }
1408         }
1409     }
1410 
verifyRadioStats(List<StaLinkLayerRadioStats> radios, WifiLinkLayerStats wifiLinkLayerStats)1411     private void verifyRadioStats(List<StaLinkLayerRadioStats> radios,
1412             WifiLinkLayerStats wifiLinkLayerStats) {
1413         StaLinkLayerRadioStats radio = radios.get(0);
1414         assertEquals(radio.onTimeInMs, wifiLinkLayerStats.on_time);
1415         assertEquals(radio.txTimeInMs, wifiLinkLayerStats.tx_time);
1416         assertEquals(radio.rxTimeInMs, wifiLinkLayerStats.rx_time);
1417         assertEquals(radio.onTimeInMsForScan, wifiLinkLayerStats.on_time_scan);
1418         assertEquals(radio.txTimeInMsPerLevel.size(),
1419                 wifiLinkLayerStats.tx_time_per_level.length);
1420         for (int i = 0; i < radio.txTimeInMsPerLevel.size(); i++) {
1421             assertEquals((int) radio.txTimeInMsPerLevel.get(i),
1422                     wifiLinkLayerStats.tx_time_per_level[i]);
1423         }
1424     }
1425 
verifyRadioStats_1_3( android.hardware.wifi.V1_3.StaLinkLayerRadioStats radio, WifiLinkLayerStats wifiLinkLayerStats)1426     private void verifyRadioStats_1_3(
1427             android.hardware.wifi.V1_3.StaLinkLayerRadioStats radio,
1428             WifiLinkLayerStats wifiLinkLayerStats) {
1429         assertEquals(radio.V1_0.onTimeInMs, wifiLinkLayerStats.on_time);
1430         assertEquals(radio.V1_0.txTimeInMs, wifiLinkLayerStats.tx_time);
1431         assertEquals(radio.V1_0.rxTimeInMs, wifiLinkLayerStats.rx_time);
1432         assertEquals(radio.V1_0.onTimeInMsForScan, wifiLinkLayerStats.on_time_scan);
1433         assertEquals(radio.V1_0.txTimeInMsPerLevel.size(),
1434                 wifiLinkLayerStats.tx_time_per_level.length);
1435         for (int i = 0; i < radio.V1_0.txTimeInMsPerLevel.size(); i++) {
1436             assertEquals((int) radio.V1_0.txTimeInMsPerLevel.get(i),
1437                     wifiLinkLayerStats.tx_time_per_level[i]);
1438         }
1439         assertEquals(radio.onTimeInMsForNanScan, wifiLinkLayerStats.on_time_nan_scan);
1440         assertEquals(radio.onTimeInMsForBgScan, wifiLinkLayerStats.on_time_background_scan);
1441         assertEquals(radio.onTimeInMsForRoamScan, wifiLinkLayerStats.on_time_roam_scan);
1442         assertEquals(radio.onTimeInMsForPnoScan, wifiLinkLayerStats.on_time_pno_scan);
1443         assertEquals(radio.onTimeInMsForHs20Scan, wifiLinkLayerStats.on_time_hs20_scan);
1444         assertEquals(radio.channelStats.size(),
1445                 wifiLinkLayerStats.channelStatsMap.size());
1446         for (int j = 0; j < radio.channelStats.size(); j++) {
1447             WifiChannelStats channelStats = radio.channelStats.get(j);
1448             ChannelStats retrievedChannelStats =
1449                     wifiLinkLayerStats.channelStatsMap.get(channelStats.channel.centerFreq);
1450             assertNotNull(retrievedChannelStats);
1451             assertEquals(channelStats.channel.centerFreq, retrievedChannelStats.frequency);
1452             assertEquals(channelStats.onTimeInMs, retrievedChannelStats.radioOnTimeMs);
1453             assertEquals(channelStats.ccaBusyTimeInMs, retrievedChannelStats.ccaBusyTimeMs);
1454         }
1455     }
1456 
verifyPerRadioStats(List<android.hardware.wifi.V1_5.StaLinkLayerRadioStats> radios, WifiLinkLayerStats wifiLinkLayerStats)1457     private void verifyPerRadioStats(List<android.hardware.wifi.V1_5.StaLinkLayerRadioStats> radios,
1458             WifiLinkLayerStats wifiLinkLayerStats) {
1459         assertEquals(radios.size(),
1460                 wifiLinkLayerStats.radioStats.length);
1461         for (int i = 0; i < radios.size(); i++) {
1462             android.hardware.wifi.V1_5.StaLinkLayerRadioStats radio = radios.get(i);
1463             RadioStat radioStat = wifiLinkLayerStats.radioStats[i];
1464             assertEquals(radio.radioId, radioStat.radio_id);
1465             assertEquals(radio.V1_3.V1_0.onTimeInMs, radioStat.on_time);
1466             assertEquals(radio.V1_3.V1_0.txTimeInMs, radioStat.tx_time);
1467             assertEquals(radio.V1_3.V1_0.rxTimeInMs, radioStat.rx_time);
1468             assertEquals(radio.V1_3.V1_0.onTimeInMsForScan, radioStat.on_time_scan);
1469             assertEquals(radio.V1_3.onTimeInMsForNanScan, radioStat.on_time_nan_scan);
1470             assertEquals(radio.V1_3.onTimeInMsForBgScan, radioStat.on_time_background_scan);
1471             assertEquals(radio.V1_3.onTimeInMsForRoamScan, radioStat.on_time_roam_scan);
1472             assertEquals(radio.V1_3.onTimeInMsForPnoScan, radioStat.on_time_pno_scan);
1473             assertEquals(radio.V1_3.onTimeInMsForHs20Scan, radioStat.on_time_hs20_scan);
1474 
1475             assertEquals(radio.V1_3.channelStats.size(),
1476                     radioStat.channelStatsMap.size());
1477             for (int j = 0; j < radio.V1_3.channelStats.size(); j++) {
1478                 WifiChannelStats channelStats = radio.V1_3.channelStats.get(j);
1479                 ChannelStats retrievedChannelStats =
1480                         radioStat.channelStatsMap.get(channelStats.channel.centerFreq);
1481                 assertNotNull(retrievedChannelStats);
1482                 assertEquals(channelStats.channel.centerFreq, retrievedChannelStats.frequency);
1483                 assertEquals(channelStats.onTimeInMs, retrievedChannelStats.radioOnTimeMs);
1484                 assertEquals(channelStats.ccaBusyTimeInMs, retrievedChannelStats.ccaBusyTimeMs);
1485             }
1486         }
1487 
1488     }
1489 
verifyRadioStats_1_5( android.hardware.wifi.V1_5.StaLinkLayerRadioStats radio, WifiLinkLayerStats wifiLinkLayerStats)1490     private void verifyRadioStats_1_5(
1491             android.hardware.wifi.V1_5.StaLinkLayerRadioStats radio,
1492             WifiLinkLayerStats wifiLinkLayerStats) {
1493         verifyRadioStats_1_3(radio.V1_3, wifiLinkLayerStats);
1494     }
1495 
verifyTwoRadioStatsAggregation( android.hardware.wifi.V1_3.StaLinkLayerRadioStats radio0, android.hardware.wifi.V1_3.StaLinkLayerRadioStats radio1, WifiLinkLayerStats wifiLinkLayerStats)1496     private void verifyTwoRadioStatsAggregation(
1497             android.hardware.wifi.V1_3.StaLinkLayerRadioStats radio0,
1498             android.hardware.wifi.V1_3.StaLinkLayerRadioStats radio1,
1499             WifiLinkLayerStats wifiLinkLayerStats) {
1500         assertEquals(radio0.V1_0.onTimeInMs + radio1.V1_0.onTimeInMs,
1501                 wifiLinkLayerStats.on_time);
1502         assertEquals(radio0.V1_0.txTimeInMs + radio1.V1_0.txTimeInMs,
1503                 wifiLinkLayerStats.tx_time);
1504         assertEquals(radio0.V1_0.rxTimeInMs + radio1.V1_0.rxTimeInMs,
1505                 wifiLinkLayerStats.rx_time);
1506         assertEquals(radio0.V1_0.onTimeInMsForScan + radio1.V1_0.onTimeInMsForScan,
1507                 wifiLinkLayerStats.on_time_scan);
1508         assertEquals(radio0.V1_0.txTimeInMsPerLevel.size(),
1509                 radio1.V1_0.txTimeInMsPerLevel.size());
1510         assertEquals(radio0.V1_0.txTimeInMsPerLevel.size(),
1511                 wifiLinkLayerStats.tx_time_per_level.length);
1512         for (int i = 0; i < radio0.V1_0.txTimeInMsPerLevel.size(); i++) {
1513             assertEquals((int) radio0.V1_0.txTimeInMsPerLevel.get(i)
1514                     + (int) radio1.V1_0.txTimeInMsPerLevel.get(i),
1515                     wifiLinkLayerStats.tx_time_per_level[i]);
1516         }
1517         assertEquals(radio0.onTimeInMsForNanScan + radio1.onTimeInMsForNanScan,
1518                 wifiLinkLayerStats.on_time_nan_scan);
1519         assertEquals(radio0.onTimeInMsForBgScan + radio1.onTimeInMsForBgScan,
1520                 wifiLinkLayerStats.on_time_background_scan);
1521         assertEquals(radio0.onTimeInMsForRoamScan + radio1.onTimeInMsForRoamScan,
1522                 wifiLinkLayerStats.on_time_roam_scan);
1523         assertEquals(radio0.onTimeInMsForPnoScan + radio1.onTimeInMsForPnoScan,
1524                 wifiLinkLayerStats.on_time_pno_scan);
1525         assertEquals(radio0.onTimeInMsForHs20Scan + radio1.onTimeInMsForHs20Scan,
1526                 wifiLinkLayerStats.on_time_hs20_scan);
1527         assertEquals(radio0.channelStats.size(), radio1.channelStats.size());
1528         assertEquals(radio0.channelStats.size(),
1529                 wifiLinkLayerStats.channelStatsMap.size());
1530         for (int j = 0; j < radio0.channelStats.size(); j++) {
1531             WifiChannelStats radio0ChannelStats = radio0.channelStats.get(j);
1532             WifiChannelStats radio1ChannelStats = radio1.channelStats.get(j);
1533             ChannelStats retrievedChannelStats =
1534                     wifiLinkLayerStats.channelStatsMap.get(radio0ChannelStats.channel.centerFreq);
1535             assertNotNull(retrievedChannelStats);
1536             assertEquals(radio0ChannelStats.channel.centerFreq, retrievedChannelStats.frequency);
1537             assertEquals(radio1ChannelStats.channel.centerFreq, retrievedChannelStats.frequency);
1538             assertEquals(radio0ChannelStats.onTimeInMs + radio1ChannelStats.onTimeInMs,
1539                     retrievedChannelStats.radioOnTimeMs);
1540             assertEquals(radio0ChannelStats.ccaBusyTimeInMs
1541                     + radio1ChannelStats.ccaBusyTimeInMs, retrievedChannelStats.ccaBusyTimeMs);
1542         }
1543     }
1544 
verifyTwoRadioStatsAggregation_1_3( List<android.hardware.wifi.V1_3.StaLinkLayerRadioStats> radios, WifiLinkLayerStats wifiLinkLayerStats)1545     private void verifyTwoRadioStatsAggregation_1_3(
1546             List<android.hardware.wifi.V1_3.StaLinkLayerRadioStats> radios,
1547             WifiLinkLayerStats wifiLinkLayerStats) {
1548         assertEquals(2, radios.size());
1549         android.hardware.wifi.V1_3.StaLinkLayerRadioStats radio0 = radios.get(0);
1550         android.hardware.wifi.V1_3.StaLinkLayerRadioStats radio1 = radios.get(1);
1551         verifyTwoRadioStatsAggregation(radio0, radio1, wifiLinkLayerStats);
1552     }
1553 
verifyTwoRadioStatsAggregation_1_5( List<android.hardware.wifi.V1_5.StaLinkLayerRadioStats> radios, WifiLinkLayerStats wifiLinkLayerStats)1554     private void verifyTwoRadioStatsAggregation_1_5(
1555             List<android.hardware.wifi.V1_5.StaLinkLayerRadioStats> radios,
1556             WifiLinkLayerStats wifiLinkLayerStats) {
1557         assertEquals(2, radios.size());
1558         android.hardware.wifi.V1_5.StaLinkLayerRadioStats radio0 = radios.get(0);
1559         android.hardware.wifi.V1_5.StaLinkLayerRadioStats radio1 = radios.get(1);
1560         verifyTwoRadioStatsAggregation(radio0.V1_3, radio1.V1_3, wifiLinkLayerStats);
1561     }
1562 
1563     /**
1564      * Populate packet stats with non-negative random values
1565      */
randomizePacketStats(Random r, StaLinkLayerIfacePacketStats pstats)1566     private static void randomizePacketStats(Random r, StaLinkLayerIfacePacketStats pstats) {
1567         pstats.rxMpdu = r.nextLong() & 0xFFFFFFFFFFL; // more than 32 bits
1568         pstats.txMpdu = r.nextLong() & 0xFFFFFFFFFFL;
1569         pstats.lostMpdu = r.nextLong() & 0xFFFFFFFFFFL;
1570         pstats.retries = r.nextLong() & 0xFFFFFFFFFFL;
1571     }
1572 
1573     /**
1574      * Populate contention time stats with non-negative random values
1575      */
randomizeContentionTimeStats(Random r, StaLinkLayerIfaceContentionTimeStats cstats)1576     private static void randomizeContentionTimeStats(Random r,
1577             StaLinkLayerIfaceContentionTimeStats cstats) {
1578         cstats.contentionTimeMinInUsec = r.nextInt() & 0x7FFFFFFF;
1579         cstats.contentionTimeMaxInUsec = r.nextInt() & 0x7FFFFFFF;
1580         cstats.contentionTimeAvgInUsec = r.nextInt() & 0x7FFFFFFF;
1581         cstats.contentionNumSamples = r.nextInt() & 0x7FFFFFFF;
1582     }
1583 
1584     /**
1585      * Populate peer info stats with non-negative random values
1586      */
randomizePeerInfoStats(Random r, ArrayList<StaPeerInfo> pstats)1587     private static void randomizePeerInfoStats(Random r, ArrayList<StaPeerInfo> pstats) {
1588         StaPeerInfo pstat = new StaPeerInfo();
1589         pstat.staCount = 2;
1590         pstat.chanUtil = 90;
1591         pstat.rateStats = new ArrayList<StaRateStat>();
1592         StaRateStat rateStat = new StaRateStat();
1593         rateStat.rateInfo.preamble = r.nextInt() & 0x7FFFFFFF;
1594         rateStat.rateInfo.nss = r.nextInt() & 0x7FFFFFFF;
1595         rateStat.rateInfo.bw = r.nextInt() & 0x7FFFFFFF;
1596         rateStat.rateInfo.rateMcsIdx = 9;
1597         rateStat.rateInfo.bitRateInKbps = 101;
1598         rateStat.txMpdu = r.nextInt() & 0x7FFFFFFF;
1599         rateStat.rxMpdu = r.nextInt() & 0x7FFFFFFF;
1600         rateStat.mpduLost = r.nextInt() & 0x7FFFFFFF;
1601         rateStat.retries = r.nextInt() & 0x7FFFFFFF;
1602         pstat.rateStats.add(rateStat);
1603         pstats.add(pstat);
1604     }
1605 
1606     /**
1607      * Populate radio stats with non-negative random values
1608      */
randomizeRadioStats(Random r, ArrayList<StaLinkLayerRadioStats> rstats)1609     private static void randomizeRadioStats(Random r, ArrayList<StaLinkLayerRadioStats> rstats) {
1610         StaLinkLayerRadioStats rstat = new StaLinkLayerRadioStats();
1611         rstat.onTimeInMs = r.nextInt() & 0xFFFFFF;
1612         rstat.txTimeInMs = r.nextInt() & 0xFFFFFF;
1613         for (int i = 0; i < 4; i++) {
1614             Integer v = r.nextInt() & 0xFFFFFF;
1615             rstat.txTimeInMsPerLevel.add(v);
1616         }
1617         rstat.rxTimeInMs = r.nextInt() & 0xFFFFFF;
1618         rstat.onTimeInMsForScan = r.nextInt() & 0xFFFFFF;
1619         rstats.add(rstat);
1620     }
1621 
1622     /**
1623      * Populate radio stats V1_3 with non-negative random values
1624      */
randomizeRadioStats_1_3(Random r, android.hardware.wifi.V1_3.StaLinkLayerRadioStats rstat)1625     private static void randomizeRadioStats_1_3(Random r,
1626             android.hardware.wifi.V1_3.StaLinkLayerRadioStats rstat) {
1627         rstat.V1_0.onTimeInMs = r.nextInt() & 0xFFFFFF;
1628         rstat.V1_0.txTimeInMs = r.nextInt() & 0xFFFFFF;
1629         for (int j = 0; j < 4; j++) {
1630             Integer v = r.nextInt() & 0xFFFFFF;
1631             rstat.V1_0.txTimeInMsPerLevel.add(v);
1632         }
1633         rstat.V1_0.rxTimeInMs = r.nextInt() & 0xFFFFFF;
1634         rstat.V1_0.onTimeInMsForScan = r.nextInt() & 0xFFFFFF;
1635         rstat.onTimeInMsForNanScan = r.nextInt() & 0xFFFFFF;
1636         rstat.onTimeInMsForBgScan = r.nextInt() & 0xFFFFFF;
1637         rstat.onTimeInMsForRoamScan = r.nextInt() & 0xFFFFFF;
1638         rstat.onTimeInMsForPnoScan = r.nextInt() & 0xFFFFFF;
1639         rstat.onTimeInMsForHs20Scan = r.nextInt() & 0xFFFFFF;
1640         for (int k = 0; k < TEST_FREQUENCIES.length; k++) {
1641             WifiChannelStats channelStats = new WifiChannelStats();
1642             channelStats.channel.centerFreq = TEST_FREQUENCIES[k];
1643             channelStats.onTimeInMs = r.nextInt() & 0xFFFFFF;
1644             channelStats.ccaBusyTimeInMs = r.nextInt() & 0xFFFFFF;
1645             rstat.channelStats.add(channelStats);
1646         }
1647     }
1648 
1649     /**
1650      * Populate radio stats V1_5 with non-negative random values
1651      */
randomizeRadioStats_1_5(Random r, android.hardware.wifi.V1_5.StaLinkLayerRadioStats rstat)1652     private static void randomizeRadioStats_1_5(Random r,
1653             android.hardware.wifi.V1_5.StaLinkLayerRadioStats rstat) {
1654         rstat.radioId = r.nextInt() & 0xFFFFFF;
1655         randomizeRadioStats_1_3(r, rstat.V1_3);
1656     }
1657 
1658     /**
1659      * Test that getFirmwareVersion() and getDriverVersion() work
1660      *
1661      * Calls before the STA is started are expected to return null.
1662      */
1663     @Test
testVersionGetters()1664     public void testVersionGetters() throws Exception {
1665         String firmwareVersion = "fuzzy";
1666         String driverVersion = "dizzy";
1667         IWifiChip.ChipDebugInfo chipDebugInfo = new IWifiChip.ChipDebugInfo();
1668         chipDebugInfo.firmwareDescription = firmwareVersion;
1669         chipDebugInfo.driverDescription = driverVersion;
1670 
1671         doAnswer(new AnswerWithArguments() {
1672             public void answer(IWifiChip.requestChipDebugInfoCallback cb) throws RemoteException {
1673                 cb.onValues(mWifiStatusSuccess, chipDebugInfo);
1674             }
1675         }).when(mIWifiChip).requestChipDebugInfo(any(IWifiChip.requestChipDebugInfoCallback.class));
1676 
1677         assertNull(mWifiVendorHal.getFirmwareVersion());
1678         assertNull(mWifiVendorHal.getDriverVersion());
1679 
1680         assertTrue(mWifiVendorHal.startVendorHalSta());
1681 
1682         assertEquals(firmwareVersion, mWifiVendorHal.getFirmwareVersion());
1683         assertEquals(driverVersion, mWifiVendorHal.getDriverVersion());
1684     }
1685 
1686     /**
1687      * For checkRoundTripIntTranslation lambdas
1688      */
1689     interface IntForInt {
translate(int value)1690         int translate(int value);
1691     }
1692 
1693     /**
1694      * Checks that translation from x to y and back again is the identity function
1695      *
1696      * @param xFromY reverse translator
1697      * @param yFromX forward translator
1698      * @param xLimit non-inclusive upper bound on x (lower bound is zero)
1699      */
checkRoundTripIntTranslation( IntForInt xFromY, IntForInt yFromX, int xFirst, int xLimit)1700     private void checkRoundTripIntTranslation(
1701             IntForInt xFromY, IntForInt yFromX, int xFirst, int xLimit) throws Exception {
1702         int ex = 0;
1703         for (int i = xFirst; i < xLimit; i++) {
1704             assertEquals(i, xFromY.translate(yFromX.translate(i)));
1705         }
1706         try {
1707             yFromX.translate(xLimit);
1708             assertTrue("expected an exception here", false);
1709         } catch (IllegalArgumentException e) {
1710             ex++;
1711         }
1712         try {
1713             xFromY.translate(yFromX.translate(xLimit - 1) + 1);
1714             assertTrue("expected an exception here", false);
1715         } catch (IllegalArgumentException e) {
1716             ex++;
1717         }
1718         assertEquals(2, ex);
1719     }
1720 
1721     @Test
testStartSendingOffloadedPacket()1722     public void testStartSendingOffloadedPacket() throws Exception {
1723         byte[] srcMac = NativeUtil.macAddressToByteArray("4007b2088c81");
1724         byte[] dstMac = NativeUtil.macAddressToByteArray("4007b8675309");
1725         InetAddress src = InetAddresses.parseNumericAddress("192.168.13.13");
1726         InetAddress dst = InetAddresses.parseNumericAddress("93.184.216.34");
1727         int slot = 13;
1728         int millis = 16000;
1729 
1730         KeepalivePacketData kap =
1731                 NattKeepalivePacketData.nattKeepalivePacket(src, 63000, dst, 4500);
1732 
1733         when(mIWifiStaIface.startSendingKeepAlivePackets(
1734                 anyInt(), any(), anyShort(), any(), any(), anyInt()
1735         )).thenReturn(mWifiStatusSuccess);
1736 
1737         assertTrue(mWifiVendorHal.startVendorHalSta());
1738         assertTrue(0 == mWifiVendorHal.startSendingOffloadedPacket(
1739                 TEST_IFACE_NAME, slot, srcMac, dstMac, kap.getPacket(),
1740                 OsConstants.ETH_P_IPV6, millis));
1741 
1742         verify(mIWifiStaIface).startSendingKeepAlivePackets(
1743                 eq(slot), any(), anyShort(), any(), any(), eq(millis));
1744     }
1745 
1746     @Test
testStopSendingOffloadedPacket()1747     public void testStopSendingOffloadedPacket() throws Exception {
1748         int slot = 13;
1749 
1750         when(mIWifiStaIface.stopSendingKeepAlivePackets(anyInt())).thenReturn(mWifiStatusSuccess);
1751 
1752         assertTrue(mWifiVendorHal.startVendorHalSta());
1753         assertTrue(0 == mWifiVendorHal.stopSendingOffloadedPacket(
1754                 TEST_IFACE_NAME, slot));
1755 
1756         verify(mIWifiStaIface).stopSendingKeepAlivePackets(eq(slot));
1757     }
1758 
1759     /**
1760      * Test the setup, invocation, and removal of a RSSI event handler
1761      *
1762      */
1763     @Test
testRssiMonitoring()1764     public void testRssiMonitoring() throws Exception {
1765         when(mIWifiStaIface.startRssiMonitoring(anyInt(), anyInt(), anyInt()))
1766                 .thenReturn(mWifiStatusSuccess);
1767         when(mIWifiStaIface.stopRssiMonitoring(anyInt()))
1768                 .thenReturn(mWifiStatusSuccess);
1769 
1770         ArrayList<Byte> breach = new ArrayList<>(10);
1771         byte hi = -21;
1772         byte med = -42;
1773         byte lo = -84;
1774         Byte lower = -88;
1775         WifiNative.WifiRssiEventHandler handler;
1776         handler = ((cur) -> {
1777             breach.add(cur);
1778         });
1779         // not started
1780         assertEquals(-1, mWifiVendorHal.startRssiMonitoring(TEST_IFACE_NAME, hi, lo, handler));
1781         // not started
1782         assertEquals(-1, mWifiVendorHal.stopRssiMonitoring(TEST_IFACE_NAME));
1783         assertTrue(mWifiVendorHal.startVendorHalSta());
1784         assertEquals(0, mWifiVendorHal.startRssiMonitoring(TEST_IFACE_NAME, hi, lo, handler));
1785         int theCmdId = mWifiVendorHal.sRssiMonCmdId;
1786         breach.clear();
1787         mIWifiStaIfaceEventCallback.onRssiThresholdBreached(theCmdId, new byte[6], lower);
1788         assertEquals(breach.get(0), lower);
1789         assertEquals(0, mWifiVendorHal.stopRssiMonitoring(TEST_IFACE_NAME));
1790         assertEquals(0, mWifiVendorHal.startRssiMonitoring(TEST_IFACE_NAME, hi, lo, handler));
1791         // replacing works
1792         assertEquals(0, mWifiVendorHal.startRssiMonitoring(TEST_IFACE_NAME, med, lo, handler));
1793         // null handler fails
1794         assertEquals(-1, mWifiVendorHal.startRssiMonitoring(
1795                 TEST_IFACE_NAME, hi, lo, null));
1796         assertEquals(0, mWifiVendorHal.startRssiMonitoring(TEST_IFACE_NAME, hi, lo, handler));
1797         // empty range
1798         assertEquals(-1, mWifiVendorHal.startRssiMonitoring(TEST_IFACE_NAME, lo, hi, handler));
1799     }
1800 
1801     /**
1802      * Test that getApfCapabilities is hooked up to the HAL correctly
1803      *
1804      * A call before the vendor HAL is started should return a non-null result with version 0
1805      *
1806      * A call after the HAL is started should return the mocked values.
1807      */
1808     @Test
testApfCapabilities()1809     public void testApfCapabilities() throws Exception {
1810         int myVersion = 33;
1811         int myMaxSize = 1234;
1812 
1813         StaApfPacketFilterCapabilities capabilities = new StaApfPacketFilterCapabilities();
1814         capabilities.version = myVersion;
1815         capabilities.maxLength = myMaxSize;
1816 
1817         doAnswer(new AnswerWithArguments() {
1818             public void answer(IWifiStaIface.getApfPacketFilterCapabilitiesCallback cb)
1819                     throws RemoteException {
1820                 cb.onValues(mWifiStatusSuccess, capabilities);
1821             }
1822         }).when(mIWifiStaIface).getApfPacketFilterCapabilities(any(
1823                 IWifiStaIface.getApfPacketFilterCapabilitiesCallback.class));
1824 
1825 
1826         assertEquals(0, mWifiVendorHal.getApfCapabilities(TEST_IFACE_NAME)
1827                 .apfVersionSupported);
1828 
1829         assertTrue(mWifiVendorHal.startVendorHalSta());
1830 
1831         ApfCapabilities actual = mWifiVendorHal.getApfCapabilities(TEST_IFACE_NAME);
1832 
1833         assertEquals(myVersion, actual.apfVersionSupported);
1834         assertEquals(myMaxSize, actual.maximumApfProgramSize);
1835         assertEquals(android.system.OsConstants.ARPHRD_ETHER, actual.apfPacketFormat);
1836         assertNotEquals(0, actual.apfPacketFormat);
1837     }
1838 
1839     /**
1840      * Test that an APF program can be installed.
1841      */
1842     @Test
testInstallApf()1843     public void testInstallApf() throws Exception {
1844         byte[] filter = new byte[] {19, 53, 10};
1845 
1846         ArrayList<Byte> expected = new ArrayList<>(3);
1847         for (byte b : filter) expected.add(b);
1848 
1849         when(mIWifiStaIface.installApfPacketFilter(anyInt(), any(ArrayList.class)))
1850                 .thenReturn(mWifiStatusSuccess);
1851 
1852         assertTrue(mWifiVendorHal.startVendorHalSta());
1853         assertTrue(mWifiVendorHal.installPacketFilter(TEST_IFACE_NAME, filter));
1854 
1855         verify(mIWifiStaIface).installApfPacketFilter(eq(0), eq(expected));
1856     }
1857 
1858     /**
1859      * Test that an APF program and data buffer can be read back.
1860      */
1861     @Test
testReadApf()1862     public void testReadApf() throws Exception {
1863         // Expose the 1.2 IWifiStaIface.
1864         mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
1865                 mWifiGlobals);
1866 
1867         byte[] program = new byte[] {65, 66, 67};
1868         ArrayList<Byte> expected = new ArrayList<>(3);
1869         for (byte b : program) expected.add(b);
1870 
1871         doAnswer(new AnswerWithArguments() {
1872             public void answer(
1873                     android.hardware.wifi.V1_2.IWifiStaIface.readApfPacketFilterDataCallback cb)
1874                     throws RemoteException {
1875                 cb.onValues(mWifiStatusSuccess, expected);
1876             }
1877         }).when(mIWifiStaIfaceV12).readApfPacketFilterData(any(
1878                 android.hardware.wifi.V1_2.IWifiStaIface.readApfPacketFilterDataCallback.class));
1879 
1880         assertTrue(mWifiVendorHal.startVendorHalSta());
1881         assertArrayEquals(program, mWifiVendorHal.readPacketFilter(TEST_IFACE_NAME));
1882     }
1883 
1884     /**
1885      * Test that the country code is set in AP mode (when it should be).
1886      */
1887     @Test
testSetApCountryCode()1888     public void testSetApCountryCode() throws Exception {
1889         byte[] expected = new byte[]{(byte) 'C', (byte) 'A'};
1890 
1891         when(mIWifiApIface.setCountryCode(any()))
1892                 .thenReturn(mWifiStatusSuccess);
1893 
1894         assertTrue(mWifiVendorHal.startVendorHalAp());
1895 
1896         assertFalse(mWifiVendorHal.setApCountryCode(TEST_IFACE_NAME, null));
1897         assertFalse(mWifiVendorHal.setApCountryCode(TEST_IFACE_NAME, ""));
1898         assertFalse(mWifiVendorHal.setApCountryCode(TEST_IFACE_NAME, "A"));
1899         // Only one expected to succeed
1900         assertTrue(mWifiVendorHal.setApCountryCode(TEST_IFACE_NAME, "CA"));
1901         assertFalse(mWifiVendorHal.setApCountryCode(TEST_IFACE_NAME, "ZZZ"));
1902 
1903         verify(mIWifiApIface).setCountryCode(eq(expected));
1904     }
1905 
1906     /**
1907      * Test that RemoteException is caught and logged.
1908      */
1909     @Test
testRemoteExceptionIsHandled()1910     public void testRemoteExceptionIsHandled() throws Exception {
1911         mWifiLog = spy(mWifiLog);
1912         mWifiVendorHal.mVerboseLog = mWifiLog;
1913         when(mIWifiApIface.setCountryCode(any()))
1914                 .thenThrow(new RemoteException("oops"));
1915         assertTrue(mWifiVendorHal.startVendorHalAp());
1916         assertFalse(mWifiVendorHal.setApCountryCode(TEST_IFACE_NAME, "CA"));
1917         assertTrue(mWifiVendorHal.isHalStarted());
1918         verify(mWifiLog).err("% RemoteException in HIDL call %");
1919     }
1920 
1921     /**
1922      * Test that startLoggingToDebugRingBuffer is plumbed to chip
1923      *
1924      * A call before the vendor hal is started should just return false.
1925      * After starting in STA mode, the call should succeed, and pass ther right things down.
1926      */
1927     @Test
testStartLoggingRingBuffer()1928     public void testStartLoggingRingBuffer() throws Exception {
1929         when(mIWifiChip.startLoggingToDebugRingBuffer(
1930                 any(String.class), anyInt(), anyInt(), anyInt()
1931         )).thenReturn(mWifiStatusSuccess);
1932 
1933         assertFalse(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 0, 0, "One"));
1934         assertTrue(mWifiVendorHal.startVendorHalSta());
1935         assertTrue(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 11, 3000, "One"));
1936 
1937         verify(mIWifiChip).startLoggingToDebugRingBuffer("One", 1, 11, 3000);
1938     }
1939 
1940     /**
1941      * Same test as testStartLoggingRingBuffer, but in AP mode rather than STA.
1942      */
1943     @Test
testStartLoggingRingBufferOnAp()1944     public void testStartLoggingRingBufferOnAp() throws Exception {
1945         when(mIWifiChip.startLoggingToDebugRingBuffer(
1946                 any(String.class), anyInt(), anyInt(), anyInt()
1947         )).thenReturn(mWifiStatusSuccess);
1948 
1949         assertFalse(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 0, 0, "One"));
1950         assertTrue(mWifiVendorHal.startVendorHalAp());
1951         assertTrue(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 11, 3000, "One"));
1952 
1953         verify(mIWifiChip).startLoggingToDebugRingBuffer("One", 1, 11, 3000);
1954     }
1955 
1956     /**
1957      * Test that getRingBufferStatus gets and translates its stuff correctly
1958      */
1959     @Test
testRingBufferStatus()1960     public void testRingBufferStatus() throws Exception {
1961         WifiDebugRingBufferStatus one = new WifiDebugRingBufferStatus();
1962         one.ringName = "One";
1963         one.flags = WifiDebugRingBufferFlags.HAS_BINARY_ENTRIES;
1964         one.ringId = 5607371;
1965         one.sizeInBytes = 54321;
1966         one.freeSizeInBytes = 42;
1967         one.verboseLevel = WifiDebugRingBufferVerboseLevel.VERBOSE;
1968         String oneExpect = "name: One flag: 1 ringBufferId: 5607371 ringBufferByteSize: 54321"
1969                 + " verboseLevel: 2 writtenBytes: 0 readBytes: 0 writtenRecords: 0";
1970 
1971         WifiDebugRingBufferStatus two = new WifiDebugRingBufferStatus();
1972         two.ringName = "Two";
1973         two.flags = WifiDebugRingBufferFlags.HAS_ASCII_ENTRIES
1974                 | WifiDebugRingBufferFlags.HAS_PER_PACKET_ENTRIES;
1975         two.ringId = 4512470;
1976         two.sizeInBytes = 300;
1977         two.freeSizeInBytes = 42;
1978         two.verboseLevel = WifiDebugRingBufferVerboseLevel.DEFAULT;
1979 
1980         ArrayList<WifiDebugRingBufferStatus> halBufferStatus = new ArrayList<>(2);
1981         halBufferStatus.add(one);
1982         halBufferStatus.add(two);
1983 
1984         WifiNative.RingBufferStatus[] actual;
1985 
1986         doAnswer(new AnswerWithArguments() {
1987             public void answer(IWifiChip.getDebugRingBuffersStatusCallback cb)
1988                     throws RemoteException {
1989                 cb.onValues(mWifiStatusSuccess, halBufferStatus);
1990             }
1991         }).when(mIWifiChip).getDebugRingBuffersStatus(any(
1992                 IWifiChip.getDebugRingBuffersStatusCallback.class));
1993 
1994         assertTrue(mWifiVendorHal.startVendorHalSta());
1995         actual = mWifiVendorHal.getRingBufferStatus();
1996 
1997         assertEquals(halBufferStatus.size(), actual.length);
1998         assertEquals(oneExpect, actual[0].toString());
1999         assertEquals(two.ringId, actual[1].ringBufferId);
2000     }
2001 
2002     /**
2003      * Test that getRingBufferData calls forceDumpToDebugRingBuffer
2004      *
2005      * Try once before hal start, and twice after (one success, one failure).
2006      */
2007     @Test
testForceRingBufferDump()2008     public void testForceRingBufferDump() throws Exception {
2009         when(mIWifiChip.forceDumpToDebugRingBuffer(eq("Gunk"))).thenReturn(mWifiStatusSuccess);
2010         when(mIWifiChip.forceDumpToDebugRingBuffer(eq("Glop"))).thenReturn(mWifiStatusFailure);
2011 
2012         assertFalse(mWifiVendorHal.getRingBufferData("Gunk")); // hal not started
2013 
2014         assertTrue(mWifiVendorHal.startVendorHalSta());
2015 
2016         assertTrue(mWifiVendorHal.getRingBufferData("Gunk")); // mocked call succeeds
2017         assertFalse(mWifiVendorHal.getRingBufferData("Glop")); // mocked call fails
2018 
2019         verify(mIWifiChip).forceDumpToDebugRingBuffer("Gunk");
2020         verify(mIWifiChip).forceDumpToDebugRingBuffer("Glop");
2021     }
2022 
2023     /**
2024      * Test flush ring buffer to files.
2025      *
2026      * Try once before hal start, and once after.
2027      */
2028     @Test
testFlushRingBufferToFile()2029     public void testFlushRingBufferToFile() throws Exception {
2030         mWifiVendorHal = new WifiVendorHalSpyV1_3(mContext, mHalDeviceManager, mHandler,
2031                 mWifiGlobals);
2032         when(mIWifiChipV13.flushRingBufferToFile()).thenReturn(mWifiStatusSuccess);
2033 
2034         assertFalse(mWifiVendorHal.flushRingBufferData());
2035 
2036         assertTrue(mWifiVendorHal.startVendorHalSta());
2037         assertTrue(mWifiVendorHal.flushRingBufferData());
2038         verify(mIWifiChipV13).flushRingBufferToFile();
2039     }
2040 
2041     /**
2042      * Tests the start of packet fate monitoring.
2043      *
2044      * Try once before hal start, and once after (one success, one failure).
2045      */
2046     @Test
testStartPktFateMonitoring()2047     public void testStartPktFateMonitoring() throws Exception {
2048         when(mIWifiStaIface.startDebugPacketFateMonitoring()).thenReturn(mWifiStatusSuccess);
2049 
2050         assertFalse(mWifiVendorHal.startPktFateMonitoring(TEST_IFACE_NAME));
2051         verify(mIWifiStaIface, never()).startDebugPacketFateMonitoring();
2052 
2053         assertTrue(mWifiVendorHal.startVendorHalSta());
2054         assertTrue(mWifiVendorHal.startPktFateMonitoring(TEST_IFACE_NAME));
2055         verify(mIWifiStaIface).startDebugPacketFateMonitoring();
2056     }
2057 
2058     /**
2059      * Tests the retrieval of tx packet fates.
2060      *
2061      * Try once before hal start, and once after.
2062      */
2063     @Test
testGetTxPktFates()2064     public void testGetTxPktFates() throws Exception {
2065         byte[] frameContentBytes = new byte[30];
2066         new Random().nextBytes(frameContentBytes);
2067         WifiDebugTxPacketFateReport fateReport = new WifiDebugTxPacketFateReport();
2068         fateReport.fate = WifiDebugTxPacketFate.DRV_QUEUED;
2069         fateReport.frameInfo.driverTimestampUsec = new Random().nextLong();
2070         fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.ETHERNET_II;
2071         fateReport.frameInfo.frameContent.addAll(
2072                 NativeUtil.byteArrayToArrayList(frameContentBytes));
2073 
2074         doAnswer(new AnswerWithArguments() {
2075             public void answer(IWifiStaIface.getDebugTxPacketFatesCallback cb) {
2076                 cb.onValues(mWifiStatusSuccess, new ArrayList<>(Arrays.asList(fateReport)));
2077             }
2078         }).when(mIWifiStaIface)
2079                 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
2080 
2081         assertEquals(0, mWifiVendorHal.getTxPktFates(TEST_IFACE_NAME).size());
2082         verify(mIWifiStaIface, never())
2083                 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
2084 
2085         assertTrue(mWifiVendorHal.startVendorHalSta());
2086 
2087         List<TxFateReport> retrievedFates = mWifiVendorHal.getTxPktFates(TEST_IFACE_NAME);
2088         assertEquals(1, retrievedFates.size());
2089         TxFateReport retrievedFate = retrievedFates.get(0);
2090         verify(mIWifiStaIface)
2091                 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
2092         assertEquals(WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED, retrievedFate.mFate);
2093         assertEquals(fateReport.frameInfo.driverTimestampUsec, retrievedFate.mDriverTimestampUSec);
2094         assertEquals(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, retrievedFate.mFrameType);
2095         assertArrayEquals(frameContentBytes, retrievedFate.mFrameBytes);
2096     }
2097 
2098     /**
2099      * Tests the retrieval of tx packet fates when the number of fates retrieved exceeds the
2100      * maximum number of packet fates fetched ({@link WifiLoggerHal#MAX_FATE_LOG_LEN}).
2101      *
2102      * Try once before hal start, and once after.
2103      */
2104     @Test
testGetTxPktFatesExceedsInputArrayLength()2105     public void testGetTxPktFatesExceedsInputArrayLength() throws Exception {
2106         byte[] frameContentBytes = new byte[30];
2107         new Random().nextBytes(frameContentBytes);
2108         WifiDebugTxPacketFateReport fateReport = new WifiDebugTxPacketFateReport();
2109         fateReport.fate = WifiDebugTxPacketFate.FW_DROP_OTHER;
2110         fateReport.frameInfo.driverTimestampUsec = new Random().nextLong();
2111         fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.MGMT_80211;
2112         fateReport.frameInfo.frameContent.addAll(
2113                 NativeUtil.byteArrayToArrayList(frameContentBytes));
2114 
2115         doAnswer(new AnswerWithArguments() {
2116             public void answer(IWifiStaIface.getDebugTxPacketFatesCallback cb) {
2117                 cb.onValues(mWifiStatusSuccess, new ArrayList<>(
2118                         // create twice as many as the max size
2119                         Collections.nCopies(WifiLoggerHal.MAX_FATE_LOG_LEN * 2, fateReport)));
2120             }
2121         }).when(mIWifiStaIface)
2122                 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
2123 
2124         assertEquals(0, mWifiVendorHal.getTxPktFates(TEST_IFACE_NAME).size());
2125         verify(mIWifiStaIface, never())
2126                 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
2127 
2128         assertTrue(mWifiVendorHal.startVendorHalSta());
2129 
2130         List<TxFateReport> retrievedFates = mWifiVendorHal.getTxPktFates(TEST_IFACE_NAME);
2131         // assert that at most WifiLoggerHal.MAX_FATE_LOG_LEN is retrieved
2132         assertEquals(WifiLoggerHal.MAX_FATE_LOG_LEN, retrievedFates.size());
2133         TxFateReport retrievedFate = retrievedFates.get(0);
2134         verify(mIWifiStaIface)
2135                 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
2136         assertEquals(WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER, retrievedFate.mFate);
2137         assertEquals(fateReport.frameInfo.driverTimestampUsec, retrievedFate.mDriverTimestampUSec);
2138         assertEquals(WifiLoggerHal.FRAME_TYPE_80211_MGMT, retrievedFate.mFrameType);
2139         assertArrayEquals(frameContentBytes, retrievedFate.mFrameBytes);
2140     }
2141 
2142     /**
2143      * Tests the retrieval of rx packet fates.
2144      *
2145      * Try once before hal start, and once after.
2146      */
2147     @Test
testGetRxPktFates()2148     public void testGetRxPktFates() throws Exception {
2149         byte[] frameContentBytes = new byte[30];
2150         new Random().nextBytes(frameContentBytes);
2151         WifiDebugRxPacketFateReport fateReport = new WifiDebugRxPacketFateReport();
2152         fateReport.fate = WifiDebugRxPacketFate.SUCCESS;
2153         fateReport.frameInfo.driverTimestampUsec = new Random().nextLong();
2154         fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.ETHERNET_II;
2155         fateReport.frameInfo.frameContent.addAll(
2156                 NativeUtil.byteArrayToArrayList(frameContentBytes));
2157 
2158         doAnswer(new AnswerWithArguments() {
2159             public void answer(IWifiStaIface.getDebugRxPacketFatesCallback cb) {
2160                 cb.onValues(mWifiStatusSuccess, new ArrayList<>(Arrays.asList(fateReport)));
2161             }
2162         }).when(mIWifiStaIface)
2163                 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
2164 
2165         assertEquals(0, mWifiVendorHal.getRxPktFates(TEST_IFACE_NAME).size());
2166         verify(mIWifiStaIface, never())
2167                 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
2168 
2169         assertTrue(mWifiVendorHal.startVendorHalSta());
2170 
2171         List<RxFateReport> retrievedFates = mWifiVendorHal.getRxPktFates(TEST_IFACE_NAME);
2172         assertEquals(1, retrievedFates.size());
2173         RxFateReport retrievedFate = retrievedFates.get(0);
2174         verify(mIWifiStaIface)
2175                 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
2176         assertEquals(WifiLoggerHal.RX_PKT_FATE_SUCCESS, retrievedFate.mFate);
2177         assertEquals(fateReport.frameInfo.driverTimestampUsec, retrievedFate.mDriverTimestampUSec);
2178         assertEquals(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, retrievedFate.mFrameType);
2179         assertArrayEquals(frameContentBytes, retrievedFate.mFrameBytes);
2180     }
2181 
2182     /**
2183      * Tests the retrieval of rx packet fates when the number of fates retrieved exceeds the
2184      * input array.
2185      *
2186      * Try once before hal start, and once after.
2187      */
2188     @Test
testGetRxPktFatesExceedsInputArrayLength()2189     public void testGetRxPktFatesExceedsInputArrayLength() throws Exception {
2190         byte[] frameContentBytes = new byte[30];
2191         new Random().nextBytes(frameContentBytes);
2192         WifiDebugRxPacketFateReport fateReport = new WifiDebugRxPacketFateReport();
2193         fateReport.fate = WifiDebugRxPacketFate.FW_DROP_FILTER;
2194         fateReport.frameInfo.driverTimestampUsec = new Random().nextLong();
2195         fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.MGMT_80211;
2196         fateReport.frameInfo.frameContent.addAll(
2197                 NativeUtil.byteArrayToArrayList(frameContentBytes));
2198 
2199         doAnswer(new AnswerWithArguments() {
2200             public void answer(IWifiStaIface.getDebugRxPacketFatesCallback cb) {
2201                 cb.onValues(mWifiStatusSuccess, new ArrayList<>(
2202                         // create twice as many as the max size
2203                         Collections.nCopies(WifiLoggerHal.MAX_FATE_LOG_LEN * 2, fateReport)));
2204             }
2205         }).when(mIWifiStaIface)
2206                 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
2207 
2208         assertEquals(0, mWifiVendorHal.getRxPktFates(TEST_IFACE_NAME).size());
2209         verify(mIWifiStaIface, never())
2210                 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
2211 
2212         assertTrue(mWifiVendorHal.startVendorHalSta());
2213 
2214         List<RxFateReport> retrievedFates = mWifiVendorHal.getRxPktFates(TEST_IFACE_NAME);
2215         assertEquals(WifiLoggerHal.MAX_FATE_LOG_LEN, retrievedFates.size());
2216         verify(mIWifiStaIface)
2217                 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
2218         RxFateReport retrievedFate = retrievedFates.get(0);
2219         assertEquals(WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER, retrievedFate.mFate);
2220         assertEquals(fateReport.frameInfo.driverTimestampUsec, retrievedFate.mDriverTimestampUSec);
2221         assertEquals(WifiLoggerHal.FRAME_TYPE_80211_MGMT, retrievedFate.mFrameType);
2222         assertArrayEquals(frameContentBytes, retrievedFate.mFrameBytes);
2223     }
2224 
2225     /**
2226      * Tests the nd offload enable/disable.
2227      */
2228     @Test
testEnableDisableNdOffload()2229     public void testEnableDisableNdOffload() throws Exception {
2230         when(mIWifiStaIface.enableNdOffload(anyBoolean())).thenReturn(mWifiStatusSuccess);
2231 
2232         assertFalse(mWifiVendorHal.configureNeighborDiscoveryOffload(TEST_IFACE_NAME, true));
2233         verify(mIWifiStaIface, never()).enableNdOffload(anyBoolean());
2234 
2235         assertTrue(mWifiVendorHal.startVendorHalSta());
2236 
2237         assertTrue(mWifiVendorHal.configureNeighborDiscoveryOffload(TEST_IFACE_NAME, true));
2238         verify(mIWifiStaIface).enableNdOffload(eq(true));
2239         assertTrue(mWifiVendorHal.configureNeighborDiscoveryOffload(TEST_IFACE_NAME, false));
2240         verify(mIWifiStaIface).enableNdOffload(eq(false));
2241     }
2242 
2243     /**
2244      * Tests the nd offload enable failure.
2245      */
2246     @Test
testEnableNdOffloadFailure()2247     public void testEnableNdOffloadFailure() throws Exception {
2248         when(mIWifiStaIface.enableNdOffload(eq(true))).thenReturn(mWifiStatusFailure);
2249 
2250         assertTrue(mWifiVendorHal.startVendorHalSta());
2251 
2252         assertFalse(mWifiVendorHal.configureNeighborDiscoveryOffload(TEST_IFACE_NAME, true));
2253         verify(mIWifiStaIface).enableNdOffload(eq(true));
2254     }
2255 
2256     /**
2257      * Helper class for mocking getRoamingCapabilities callback
2258      */
2259     private class GetRoamingCapabilitiesAnswer extends AnswerWithArguments {
2260         private final WifiStatus mStatus;
2261         private final StaRoamingCapabilities mCaps;
2262 
GetRoamingCapabilitiesAnswer(WifiStatus status, StaRoamingCapabilities caps)2263         GetRoamingCapabilitiesAnswer(WifiStatus status, StaRoamingCapabilities caps) {
2264             mStatus = status;
2265             mCaps = caps;
2266         }
2267 
answer(IWifiStaIface.getRoamingCapabilitiesCallback cb)2268         public void answer(IWifiStaIface.getRoamingCapabilitiesCallback cb) {
2269             cb.onValues(mStatus, mCaps);
2270         }
2271     }
2272 
2273     /**
2274      * Tests retrieval of firmware roaming capabilities
2275      */
2276     @Test
testFirmwareRoamingCapabilityRetrieval()2277     public void testFirmwareRoamingCapabilityRetrieval() throws Exception {
2278         assertTrue(mWifiVendorHal.startVendorHalSta());
2279         for (int i = 0; i < 4; i++) {
2280             int blocklistSize = i + 10;
2281             int allowlistSize = i * 3;
2282             StaRoamingCapabilities caps = new StaRoamingCapabilities();
2283             caps.maxBlacklistSize = blocklistSize;
2284             caps.maxWhitelistSize = allowlistSize;
2285             doAnswer(new GetRoamingCapabilitiesAnswer(mWifiStatusSuccess, caps))
2286                     .when(mIWifiStaIface).getRoamingCapabilities(
2287                             any(IWifiStaIface.getRoamingCapabilitiesCallback.class));
2288             RoamingCapabilities roamCap = mWifiVendorHal.getRoamingCapabilities(TEST_IFACE_NAME);
2289             assertNotNull(roamCap);
2290             assertEquals(blocklistSize, roamCap.maxBlocklistSize);
2291             assertEquals(allowlistSize, roamCap.maxAllowlistSize);
2292         }
2293     }
2294 
2295     /**
2296      * Tests unsuccessful retrieval of firmware roaming capabilities
2297      */
2298     @Test
testUnsuccessfulFirmwareRoamingCapabilityRetrieval()2299     public void testUnsuccessfulFirmwareRoamingCapabilityRetrieval() throws Exception {
2300         assertTrue(mWifiVendorHal.startVendorHalSta());
2301         StaRoamingCapabilities caps = new StaRoamingCapabilities();
2302         caps.maxBlacklistSize = 43;
2303         caps.maxWhitelistSize = 18;
2304 
2305         // hal returns a failure status
2306         doAnswer(new GetRoamingCapabilitiesAnswer(mWifiStatusFailure, null))
2307                 .when(mIWifiStaIface).getRoamingCapabilities(
2308                         any(IWifiStaIface.getRoamingCapabilitiesCallback.class));
2309         assertNull(mWifiVendorHal.getRoamingCapabilities(TEST_IFACE_NAME));
2310 
2311         // hal returns failure status, but supplies caps anyway
2312         doAnswer(new GetRoamingCapabilitiesAnswer(mWifiStatusFailure, caps))
2313                 .when(mIWifiStaIface).getRoamingCapabilities(
2314                 any(IWifiStaIface.getRoamingCapabilitiesCallback.class));
2315         assertNull(mWifiVendorHal.getRoamingCapabilities(TEST_IFACE_NAME));
2316 
2317         // lost connection
2318         doThrow(new RemoteException())
2319                 .when(mIWifiStaIface).getRoamingCapabilities(
2320                         any(IWifiStaIface.getRoamingCapabilitiesCallback.class));
2321         assertNull(mWifiVendorHal.getRoamingCapabilities(TEST_IFACE_NAME));
2322     }
2323 
2324     /**
2325      * Tests enableFirmwareRoaming successful enable
2326      */
2327     @Test
testEnableFirmwareRoamingSuccess()2328     public void testEnableFirmwareRoamingSuccess() throws Exception {
2329         assertTrue(mWifiVendorHal.startVendorHalSta());
2330         when(mIWifiStaIface.setRoamingState(eq(StaRoamingState.ENABLED)))
2331                 .thenReturn(mWifiStatusSuccess);
2332         assertEquals(WifiNative.SET_FIRMWARE_ROAMING_SUCCESS,
2333                 mWifiVendorHal.enableFirmwareRoaming(TEST_IFACE_NAME,
2334                                                      WifiNative.ENABLE_FIRMWARE_ROAMING));
2335     }
2336 
2337     /**
2338      * Tests enableFirmwareRoaming successful disable
2339      */
2340     @Test
testDisbleFirmwareRoamingSuccess()2341     public void testDisbleFirmwareRoamingSuccess() throws Exception {
2342         assertTrue(mWifiVendorHal.startVendorHalSta());
2343         when(mIWifiStaIface.setRoamingState(eq(StaRoamingState.DISABLED)))
2344                 .thenReturn(mWifiStatusSuccess);
2345         assertEquals(WifiNative.SET_FIRMWARE_ROAMING_SUCCESS,
2346                 mWifiVendorHal.enableFirmwareRoaming(TEST_IFACE_NAME,
2347                                                      WifiNative.DISABLE_FIRMWARE_ROAMING));
2348     }
2349 
2350     /**
2351      * Tests enableFirmwareRoaming failure case - invalid argument
2352      */
2353     @Test
testEnableFirmwareRoamingFailureInvalidArgument()2354     public void testEnableFirmwareRoamingFailureInvalidArgument() throws Exception {
2355         final int badState = WifiNative.DISABLE_FIRMWARE_ROAMING
2356                 + WifiNative.ENABLE_FIRMWARE_ROAMING + 1;
2357         assertTrue(mWifiVendorHal.startVendorHalSta());
2358         assertEquals(WifiNative.SET_FIRMWARE_ROAMING_FAILURE,
2359                 mWifiVendorHal.enableFirmwareRoaming(TEST_IFACE_NAME, badState));
2360         verify(mIWifiStaIface, never()).setRoamingState(anyByte());
2361     }
2362 
2363     /**
2364      * Tests enableFirmwareRoaming failure case - busy
2365      */
2366     @Test
testEnableFirmwareRoamingFailureBusy()2367     public void testEnableFirmwareRoamingFailureBusy() throws Exception {
2368         assertTrue(mWifiVendorHal.startVendorHalSta());
2369         when(mIWifiStaIface.setRoamingState(anyByte()))
2370                 .thenReturn(mWifiStatusBusy);
2371         assertEquals(WifiNative.SET_FIRMWARE_ROAMING_BUSY,
2372                 mWifiVendorHal.enableFirmwareRoaming(TEST_IFACE_NAME,
2373                                                      WifiNative.ENABLE_FIRMWARE_ROAMING));
2374     }
2375 
2376     /**
2377      * Tests enableFirmwareRoaming generic failure case
2378      */
2379     @Test
testEnableFirmwareRoamingFailure()2380     public void testEnableFirmwareRoamingFailure() throws Exception {
2381         assertTrue(mWifiVendorHal.startVendorHalSta());
2382         when(mIWifiStaIface.setRoamingState(anyByte()))
2383                 .thenReturn(mWifiStatusFailure);
2384         assertEquals(WifiNative.SET_FIRMWARE_ROAMING_FAILURE,
2385                 mWifiVendorHal.enableFirmwareRoaming(TEST_IFACE_NAME,
2386                                                      WifiNative.ENABLE_FIRMWARE_ROAMING));
2387     }
2388 
2389     /**
2390      * Tests enableFirmwareRoaming remote exception failure case
2391      */
2392     @Test
testEnableFirmwareRoamingException()2393     public void testEnableFirmwareRoamingException() throws Exception {
2394         assertTrue(mWifiVendorHal.startVendorHalSta());
2395         doThrow(new RemoteException()).when(mIWifiStaIface).setRoamingState(anyByte());
2396         assertEquals(WifiNative.SET_FIRMWARE_ROAMING_FAILURE,
2397                 mWifiVendorHal.enableFirmwareRoaming(TEST_IFACE_NAME,
2398                                                      WifiNative.ENABLE_FIRMWARE_ROAMING));
2399     }
2400 
2401     /**
2402      * Tests configureRoaming success
2403      */
2404     @Test
testConfigureRoamingSuccess()2405     public void testConfigureRoamingSuccess() throws Exception {
2406         assertTrue(mWifiVendorHal.startVendorHalSta());
2407         WifiNative.RoamingConfig roamingConfig = new WifiNative.RoamingConfig();
2408         roamingConfig.blocklistBssids = new ArrayList();
2409         roamingConfig.blocklistBssids.add("12:34:56:78:ca:fe");
2410         roamingConfig.allowlistSsids = new ArrayList();
2411         roamingConfig.allowlistSsids.add("\"xyzzy\"");
2412         roamingConfig.allowlistSsids.add("\"\u0F00 \u05D0\"");
2413         when(mIWifiStaIface.configureRoaming(any())).thenReturn(mWifiStatusSuccess);
2414         assertTrue(mWifiVendorHal.configureRoaming(TEST_IFACE_NAME, roamingConfig));
2415         verify(mIWifiStaIface).configureRoaming(any());
2416     }
2417 
2418     /**
2419      * Tests configureRoaming zero padding success
2420      */
2421     @Test
testConfigureRoamingZeroPaddingSuccess()2422     public void testConfigureRoamingZeroPaddingSuccess() throws Exception {
2423         assertTrue(mWifiVendorHal.startVendorHalSta());
2424         WifiNative.RoamingConfig roamingConfig = new WifiNative.RoamingConfig();
2425         roamingConfig.allowlistSsids = new ArrayList();
2426         roamingConfig.allowlistSsids.add("\"xyzzy\"");
2427         when(mIWifiStaIface.configureRoaming(any())).thenReturn(mWifiStatusSuccess);
2428         assertTrue(mWifiVendorHal.configureRoaming(TEST_IFACE_NAME, roamingConfig));
2429         ArgumentCaptor<StaRoamingConfig> staRoamingConfigCaptor = ArgumentCaptor.forClass(
2430                 StaRoamingConfig.class);
2431         verify(mIWifiStaIface).configureRoaming(staRoamingConfigCaptor.capture());
2432         byte[] allowlistSsidsPadded = new byte[32];
2433         allowlistSsidsPadded[0] = (byte) 0x78;
2434         allowlistSsidsPadded[1] = (byte) 0x79;
2435         allowlistSsidsPadded[2] = (byte) 0x7a;
2436         allowlistSsidsPadded[3] = (byte) 0x7a;
2437         allowlistSsidsPadded[4] = (byte) 0x79;
2438         assertArrayEquals(staRoamingConfigCaptor.getValue().ssidWhitelist.get(0),
2439                 allowlistSsidsPadded);
2440         allowlistSsidsPadded[5] = (byte) 0x79;
2441         assertFalse(Arrays.equals(staRoamingConfigCaptor.getValue().ssidWhitelist.get(0),
2442                 allowlistSsidsPadded));
2443     }
2444 
2445     /**
2446      * Tests configureRoaming success with null lists
2447      */
2448     @Test
testConfigureRoamingResetSuccess()2449     public void testConfigureRoamingResetSuccess() throws Exception {
2450         assertTrue(mWifiVendorHal.startVendorHalSta());
2451         WifiNative.RoamingConfig roamingConfig = new WifiNative.RoamingConfig();
2452         when(mIWifiStaIface.configureRoaming(any())).thenReturn(mWifiStatusSuccess);
2453         assertTrue(mWifiVendorHal.configureRoaming(TEST_IFACE_NAME, roamingConfig));
2454         verify(mIWifiStaIface).configureRoaming(any());
2455     }
2456 
2457     /**
2458      * Tests configureRoaming failure when hal returns failure
2459      */
2460     @Test
testConfigureRoamingFailure()2461     public void testConfigureRoamingFailure() throws Exception {
2462         assertTrue(mWifiVendorHal.startVendorHalSta());
2463         WifiNative.RoamingConfig roamingConfig = new WifiNative.RoamingConfig();
2464         when(mIWifiStaIface.configureRoaming(any())).thenReturn(mWifiStatusFailure);
2465         assertFalse(mWifiVendorHal.configureRoaming(TEST_IFACE_NAME, roamingConfig));
2466         verify(mIWifiStaIface).configureRoaming(any());
2467     }
2468 
2469     /**
2470      * Tests configureRoaming failure due to remote exception
2471      */
2472     @Test
testConfigureRoamingRemoteException()2473     public void testConfigureRoamingRemoteException() throws Exception {
2474         assertTrue(mWifiVendorHal.startVendorHalSta());
2475         WifiNative.RoamingConfig roamingConfig = new WifiNative.RoamingConfig();
2476         doThrow(new RemoteException()).when(mIWifiStaIface).configureRoaming(any());
2477         assertFalse(mWifiVendorHal.configureRoaming(TEST_IFACE_NAME, roamingConfig));
2478         verify(mIWifiStaIface).configureRoaming(any());
2479     }
2480 
2481     /**
2482      * Tests configureRoaming failure due to invalid bssid
2483      */
2484     @Test
testConfigureRoamingBadBssid()2485     public void testConfigureRoamingBadBssid() throws Exception {
2486         assertTrue(mWifiVendorHal.startVendorHalSta());
2487         WifiNative.RoamingConfig roamingConfig = new WifiNative.RoamingConfig();
2488         roamingConfig.blocklistBssids = new ArrayList();
2489         roamingConfig.blocklistBssids.add("12:34:56:78:zz:zz");
2490         when(mIWifiStaIface.configureRoaming(any())).thenReturn(mWifiStatusSuccess);
2491         assertFalse(mWifiVendorHal.configureRoaming(TEST_IFACE_NAME, roamingConfig));
2492         verify(mIWifiStaIface, never()).configureRoaming(any());
2493     }
2494 
2495     /**
2496      * Tests configureRoaming failure due to invalid ssid
2497      */
2498     @Test
testConfigureRoamingBadSsid()2499     public void testConfigureRoamingBadSsid() throws Exception {
2500         assertTrue(mWifiVendorHal.startVendorHalSta());
2501         WifiNative.RoamingConfig roamingConfig = new WifiNative.RoamingConfig();
2502         roamingConfig.allowlistSsids = new ArrayList();
2503         // Add an SSID that is too long (> 32 bytes) due to the multi-byte utf-8 characters
2504         roamingConfig.allowlistSsids.add("\"123456789012345678901234567890\u0F00\u05D0\"");
2505         when(mIWifiStaIface.configureRoaming(any())).thenReturn(mWifiStatusSuccess);
2506         assertFalse(mWifiVendorHal.configureRoaming(TEST_IFACE_NAME, roamingConfig));
2507         verify(mIWifiStaIface, never()).configureRoaming(any());
2508     }
2509 
2510     /**
2511      * Tests the retrieval of wlan wake reason stats.
2512      */
2513     @Test
testGetWlanWakeReasonCount()2514     public void testGetWlanWakeReasonCount() throws Exception {
2515         WifiDebugHostWakeReasonStats stats = new WifiDebugHostWakeReasonStats();
2516         Random rand = new Random();
2517         stats.totalCmdEventWakeCnt = rand.nextInt();
2518         stats.totalDriverFwLocalWakeCnt = rand.nextInt();
2519         stats.totalRxPacketWakeCnt = rand.nextInt();
2520         stats.rxPktWakeDetails.rxUnicastCnt = rand.nextInt();
2521         stats.rxPktWakeDetails.rxMulticastCnt = rand.nextInt();
2522         stats.rxIcmpPkWakeDetails.icmpPkt = rand.nextInt();
2523         stats.rxIcmpPkWakeDetails.icmp6Pkt = rand.nextInt();
2524         stats.rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt = rand.nextInt();
2525         stats.rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt = rand.nextInt();
2526 
2527         doAnswer(new AnswerWithArguments() {
2528             public void answer(IWifiChip.getDebugHostWakeReasonStatsCallback cb) {
2529                 cb.onValues(mWifiStatusSuccess, stats);
2530             }
2531         }).when(mIWifiChip).getDebugHostWakeReasonStats(
2532                 any(IWifiChip.getDebugHostWakeReasonStatsCallback.class));
2533 
2534         assertNull(mWifiVendorHal.getWlanWakeReasonCount());
2535         verify(mIWifiChip, never())
2536                 .getDebugHostWakeReasonStats(
2537                         any(IWifiChip.getDebugHostWakeReasonStatsCallback.class));
2538 
2539         assertTrue(mWifiVendorHal.startVendorHalSta());
2540 
2541         WlanWakeReasonAndCounts retrievedStats = mWifiVendorHal.getWlanWakeReasonCount();
2542         verify(mIWifiChip).getDebugHostWakeReasonStats(
2543                 any(IWifiChip.getDebugHostWakeReasonStatsCallback.class));
2544         assertNotNull(retrievedStats);
2545         assertEquals(stats.totalCmdEventWakeCnt, retrievedStats.totalCmdEventWake);
2546         assertEquals(stats.totalDriverFwLocalWakeCnt, retrievedStats.totalDriverFwLocalWake);
2547         assertEquals(stats.totalRxPacketWakeCnt, retrievedStats.totalRxDataWake);
2548         assertEquals(stats.rxPktWakeDetails.rxUnicastCnt, retrievedStats.rxUnicast);
2549         assertEquals(stats.rxPktWakeDetails.rxMulticastCnt, retrievedStats.rxMulticast);
2550         assertEquals(stats.rxIcmpPkWakeDetails.icmpPkt, retrievedStats.icmp);
2551         assertEquals(stats.rxIcmpPkWakeDetails.icmp6Pkt, retrievedStats.icmp6);
2552         assertEquals(stats.rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt,
2553                 retrievedStats.ipv4RxMulticast);
2554         assertEquals(stats.rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt,
2555                 retrievedStats.ipv6Multicast);
2556     }
2557 
2558     /**
2559      * Tests the failure in retrieval of wlan wake reason stats.
2560      */
2561     @Test
testGetWlanWakeReasonCountFailure()2562     public void testGetWlanWakeReasonCountFailure() throws Exception {
2563         doAnswer(new AnswerWithArguments() {
2564             public void answer(IWifiChip.getDebugHostWakeReasonStatsCallback cb) {
2565                 cb.onValues(mWifiStatusFailure, new WifiDebugHostWakeReasonStats());
2566             }
2567         }).when(mIWifiChip).getDebugHostWakeReasonStats(
2568                 any(IWifiChip.getDebugHostWakeReasonStatsCallback.class));
2569 
2570         // This should work in both AP & STA mode.
2571         assertTrue(mWifiVendorHal.startVendorHalAp());
2572 
2573         assertNull(mWifiVendorHal.getWlanWakeReasonCount());
2574         verify(mIWifiChip).getDebugHostWakeReasonStats(
2575                 any(IWifiChip.getDebugHostWakeReasonStatsCallback.class));
2576     }
2577 
2578     /**
2579      * Test that getFwMemoryDump is properly plumbed
2580      */
2581     @Test
testGetFwMemoryDump()2582     public void testGetFwMemoryDump() throws Exception {
2583         byte [] sample = NativeUtil.hexStringToByteArray("268c7a3fbfa4661c0bdd6a36");
2584         ArrayList<Byte> halBlob = NativeUtil.byteArrayToArrayList(sample);
2585 
2586         doAnswer(new AnswerWithArguments() {
2587             public void answer(IWifiChip.requestFirmwareDebugDumpCallback cb)
2588                     throws RemoteException {
2589                 cb.onValues(mWifiStatusSuccess, halBlob);
2590             }
2591         }).when(mIWifiChip).requestFirmwareDebugDump(any(
2592                 IWifiChip.requestFirmwareDebugDumpCallback.class));
2593 
2594         assertTrue(mWifiVendorHal.startVendorHalSta());
2595         assertArrayEquals(sample, mWifiVendorHal.getFwMemoryDump());
2596     }
2597 
2598     /**
2599      * Test that getDriverStateDump is properly plumbed
2600      *
2601      * Just for variety, use AP mode here.
2602      */
2603     @Test
testGetDriverStateDump()2604     public void testGetDriverStateDump() throws Exception {
2605         byte [] sample = NativeUtil.hexStringToByteArray("e83ff543cf80083e6459d20f");
2606         ArrayList<Byte> halBlob = NativeUtil.byteArrayToArrayList(sample);
2607 
2608         doAnswer(new AnswerWithArguments() {
2609             public void answer(IWifiChip.requestDriverDebugDumpCallback cb)
2610                     throws RemoteException {
2611                 cb.onValues(mWifiStatusSuccess, halBlob);
2612             }
2613         }).when(mIWifiChip).requestDriverDebugDump(any(
2614                 IWifiChip.requestDriverDebugDumpCallback.class));
2615 
2616         assertTrue(mWifiVendorHal.startVendorHalAp());
2617         assertArrayEquals(sample, mWifiVendorHal.getDriverStateDump());
2618     }
2619 
2620     /**
2621      * Test that background scan failure is handled correctly.
2622      */
2623     @Test
testBgScanFailureCallback()2624     public void testBgScanFailureCallback() throws Exception {
2625         assertTrue(mWifiVendorHal.startVendorHalSta());
2626         assertNotNull(mIWifiStaIfaceEventCallback);
2627 
2628         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
2629         startBgScan(eventHandler);
2630 
2631         mIWifiStaIfaceEventCallback.onBackgroundScanFailure(mWifiVendorHal.mScan.cmdId);
2632         verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_FAILED);
2633     }
2634 
2635     /**
2636      * Test that background scan failure with wrong id is not reported.
2637      */
2638     @Test
testBgScanFailureCallbackWithInvalidCmdId()2639     public void testBgScanFailureCallbackWithInvalidCmdId() throws Exception {
2640         assertTrue(mWifiVendorHal.startVendorHalSta());
2641         assertNotNull(mIWifiStaIfaceEventCallback);
2642 
2643         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
2644         startBgScan(eventHandler);
2645 
2646         mIWifiStaIfaceEventCallback.onBackgroundScanFailure(mWifiVendorHal.mScan.cmdId + 1);
2647         verify(eventHandler, never()).onScanStatus(WifiNative.WIFI_SCAN_FAILED);
2648     }
2649 
2650     /**
2651      * Test that background scan full results are handled correctly.
2652      */
2653     @Test
testBgScanFullScanResults()2654     public void testBgScanFullScanResults() throws Exception {
2655         assertTrue(mWifiVendorHal.startVendorHalSta());
2656         assertNotNull(mIWifiStaIfaceEventCallback);
2657 
2658         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
2659         startBgScan(eventHandler);
2660 
2661         Pair<StaScanResult, ScanResult> result = createHidlAndFrameworkBgScanResult();
2662         mIWifiStaIfaceEventCallback.onBackgroundFullScanResult(
2663                 mWifiVendorHal.mScan.cmdId, 5, result.first);
2664 
2665         ArgumentCaptor<ScanResult> scanResultCaptor = ArgumentCaptor.forClass(ScanResult.class);
2666         verify(eventHandler).onFullScanResult(scanResultCaptor.capture(), eq(5));
2667 
2668         assertScanResultEqual(result.second, scanResultCaptor.getValue());
2669     }
2670 
2671     /**
2672      * Test that background scan results are handled correctly.
2673      */
2674     @Test
testBgScanScanResults()2675     public void testBgScanScanResults() throws Exception {
2676         assertTrue(mWifiVendorHal.startVendorHalSta());
2677         assertNotNull(mIWifiStaIfaceEventCallback);
2678 
2679         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
2680         startBgScan(eventHandler);
2681 
2682         Pair<ArrayList<StaScanData>, ArrayList<WifiScanner.ScanData>> data =
2683                 createHidlAndFrameworkBgScanDatas();
2684         mIWifiStaIfaceEventCallback.onBackgroundScanResults(
2685                 mWifiVendorHal.mScan.cmdId, data.first);
2686 
2687         verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
2688         assertScanDatasEqual(
2689                 data.second, Arrays.asList(mWifiVendorHal.mScan.latestScanResults));
2690     }
2691 
2692     /**
2693      * Test that starting a new background scan when one is active will stop the previous one.
2694      */
2695     @Test
testBgScanReplacement()2696     public void testBgScanReplacement() throws Exception {
2697         when(mIWifiStaIface.stopBackgroundScan(anyInt())).thenReturn(mWifiStatusSuccess);
2698         assertTrue(mWifiVendorHal.startVendorHalSta());
2699         assertNotNull(mIWifiStaIfaceEventCallback);
2700         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
2701         startBgScan(eventHandler);
2702         int cmdId1 = mWifiVendorHal.mScan.cmdId;
2703         startBgScan(eventHandler);
2704         assertNotEquals(mWifiVendorHal.mScan.cmdId, cmdId1);
2705         verify(mIWifiStaIface, times(2)).startBackgroundScan(anyInt(), any());
2706         verify(mIWifiStaIface).stopBackgroundScan(cmdId1);
2707     }
2708 
2709     /**
2710      * Test stopping a background scan.
2711      */
2712     @Test
testBgScanStop()2713     public void testBgScanStop() throws Exception {
2714         when(mIWifiStaIface.stopBackgroundScan(anyInt())).thenReturn(mWifiStatusSuccess);
2715         assertTrue(mWifiVendorHal.startVendorHalSta());
2716         assertNotNull(mIWifiStaIfaceEventCallback);
2717         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
2718         startBgScan(eventHandler);
2719 
2720         int cmdId = mWifiVendorHal.mScan.cmdId;
2721 
2722         mWifiVendorHal.stopBgScan(TEST_IFACE_NAME);
2723         mWifiVendorHal.stopBgScan(TEST_IFACE_NAME); // second call should not do anything
2724         verify(mIWifiStaIface).stopBackgroundScan(cmdId); // Should be called just once
2725     }
2726 
2727     /**
2728      * Test pausing and restarting a background scan.
2729      */
2730     @Test
testBgScanPauseAndRestart()2731     public void testBgScanPauseAndRestart() throws Exception {
2732         when(mIWifiStaIface.stopBackgroundScan(anyInt())).thenReturn(mWifiStatusSuccess);
2733         assertTrue(mWifiVendorHal.startVendorHalSta());
2734         assertNotNull(mIWifiStaIfaceEventCallback);
2735         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
2736         startBgScan(eventHandler);
2737 
2738         int cmdId = mWifiVendorHal.mScan.cmdId;
2739 
2740         mWifiVendorHal.pauseBgScan(TEST_IFACE_NAME);
2741         mWifiVendorHal.restartBgScan(TEST_IFACE_NAME);
2742         verify(mIWifiStaIface).stopBackgroundScan(cmdId); // Should be called just once
2743         verify(mIWifiStaIface, times(2)).startBackgroundScan(eq(cmdId), any());
2744     }
2745 
2746     /**
2747      * Test the handling of log handler set.
2748      */
2749     @Test
testSetLogHandler()2750     public void testSetLogHandler() throws Exception {
2751         when(mIWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(mWifiStatusSuccess);
2752 
2753         WifiNative.WifiLoggerEventHandler eventHandler =
2754                 mock(WifiNative.WifiLoggerEventHandler.class);
2755 
2756         assertFalse(mWifiVendorHal.setLoggingEventHandler(eventHandler));
2757         verify(mIWifiChip, never()).enableDebugErrorAlerts(anyBoolean());
2758 
2759         assertTrue(mWifiVendorHal.startVendorHalSta());
2760 
2761         assertTrue(mWifiVendorHal.setLoggingEventHandler(eventHandler));
2762         verify(mIWifiChip).enableDebugErrorAlerts(eq(true));
2763         reset(mIWifiChip);
2764 
2765         // Second call should fail.
2766         assertFalse(mWifiVendorHal.setLoggingEventHandler(eventHandler));
2767         verify(mIWifiChip, never()).enableDebugErrorAlerts(anyBoolean());
2768     }
2769 
2770     /**
2771      * Test the handling of log handler reset.
2772      */
2773     @Test
testResetLogHandler()2774     public void testResetLogHandler() throws Exception {
2775         when(mIWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(mWifiStatusSuccess);
2776         when(mIWifiChip.stopLoggingToDebugRingBuffer()).thenReturn(mWifiStatusSuccess);
2777 
2778         assertFalse(mWifiVendorHal.resetLogHandler());
2779         verify(mIWifiChip, never()).enableDebugErrorAlerts(anyBoolean());
2780         verify(mIWifiChip, never()).stopLoggingToDebugRingBuffer();
2781 
2782         assertTrue(mWifiVendorHal.startVendorHalSta());
2783 
2784         // Now set and then reset.
2785         assertTrue(mWifiVendorHal.setLoggingEventHandler(
2786                 mock(WifiNative.WifiLoggerEventHandler.class)));
2787         assertTrue(mWifiVendorHal.resetLogHandler());
2788         verify(mIWifiChip).enableDebugErrorAlerts(eq(false));
2789         verify(mIWifiChip).stopLoggingToDebugRingBuffer();
2790         reset(mIWifiChip);
2791     }
2792 
2793     /**
2794      * Test the handling of log handler reset.
2795      */
2796     @Test
testResetLogHandlerAfterHalStop()2797     public void testResetLogHandlerAfterHalStop() throws Exception {
2798         when(mIWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(mWifiStatusSuccess);
2799         when(mIWifiChip.stopLoggingToDebugRingBuffer()).thenReturn(mWifiStatusSuccess);
2800 
2801         // Start in STA mode.
2802         assertTrue(mWifiVendorHal.startVendorHalSta());
2803 
2804         // Now set the log handler, succeeds.
2805         assertTrue(mWifiVendorHal.setLoggingEventHandler(
2806                 mock(WifiNative.WifiLoggerEventHandler.class)));
2807         verify(mIWifiChip).enableDebugErrorAlerts(eq(true));
2808 
2809         // Stop
2810         mWifiVendorHal.stopVendorHal();
2811 
2812         // Reset the log handler after stop, not HAL methods invoked.
2813         assertFalse(mWifiVendorHal.resetLogHandler());
2814         verify(mIWifiChip, never()).enableDebugErrorAlerts(eq(false));
2815         verify(mIWifiChip, never()).stopLoggingToDebugRingBuffer();
2816 
2817         // Start in STA mode again.
2818         assertTrue(mWifiVendorHal.startVendorHalSta());
2819 
2820         // Now set the log handler again, should succeed.
2821         assertTrue(mWifiVendorHal.setLoggingEventHandler(
2822                 mock(WifiNative.WifiLoggerEventHandler.class)));
2823         verify(mIWifiChip, times(2)).enableDebugErrorAlerts(eq(true));
2824     }
2825 
2826     /**
2827      * Test the handling of alert callback.
2828      */
2829     @Test
testAlertCallback()2830     public void testAlertCallback() throws Exception {
2831         assertTrue(mWifiVendorHal.startVendorHalSta());
2832         assertNotNull(mIWifiChipEventCallback);
2833 
2834         testAlertCallbackUsingProvidedCallback(mIWifiChipEventCallback);
2835     }
2836 
2837     /**
2838      * Test the handling of ring buffer callback.
2839      */
2840     @Test
testRingBufferDataCallback()2841     public void testRingBufferDataCallback() throws Exception {
2842         when(mIWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(mWifiStatusSuccess);
2843         when(mIWifiChip.stopLoggingToDebugRingBuffer()).thenReturn(mWifiStatusSuccess);
2844 
2845         assertTrue(mWifiVendorHal.startVendorHalSta());
2846         assertNotNull(mIWifiChipEventCallback);
2847 
2848         byte[] errorData = new byte[45];
2849         new Random().nextBytes(errorData);
2850 
2851         // Randomly raise the HIDL callback before we register for the log callback.
2852         // This should be safely ignored. (Not trigger NPE.)
2853         mIWifiChipEventCallback.onDebugRingBufferDataAvailable(
2854                 new WifiDebugRingBufferStatus(), NativeUtil.byteArrayToArrayList(errorData));
2855         mLooper.dispatchAll();
2856 
2857         WifiNative.WifiLoggerEventHandler eventHandler =
2858                 mock(WifiNative.WifiLoggerEventHandler.class);
2859         assertTrue(mWifiVendorHal.setLoggingEventHandler(eventHandler));
2860         verify(mIWifiChip).enableDebugErrorAlerts(eq(true));
2861 
2862         // Now raise the HIDL callback, this should be properly handled.
2863         mIWifiChipEventCallback.onDebugRingBufferDataAvailable(
2864                 new WifiDebugRingBufferStatus(), NativeUtil.byteArrayToArrayList(errorData));
2865         mLooper.dispatchAll();
2866         verify(eventHandler).onRingBufferData(
2867                 any(WifiNative.RingBufferStatus.class), eq(errorData));
2868 
2869         // Now stop the logging and invoke the callback. This should be ignored.
2870         reset(eventHandler);
2871         assertTrue(mWifiVendorHal.resetLogHandler());
2872         mIWifiChipEventCallback.onDebugRingBufferDataAvailable(
2873                 new WifiDebugRingBufferStatus(), NativeUtil.byteArrayToArrayList(errorData));
2874         mLooper.dispatchAll();
2875         verify(eventHandler, never()).onRingBufferData(anyObject(), anyObject());
2876     }
2877 
2878     /**
2879      * Test the handling of Vendor HAL death.
2880      */
2881     @Test
testVendorHalDeath()2882     public void testVendorHalDeath() {
2883         // Invoke the HAL device manager status callback with ready set to false to indicate the
2884         // death of the HAL.
2885         when(mHalDeviceManager.isReady()).thenReturn(false);
2886         mHalDeviceManagerStatusCallbacks.onStatusChanged();
2887         mLooper.dispatchAll();
2888 
2889         verify(mVendorHalDeathHandler).onDeath();
2890     }
2891 
2892     /**
2893      * Test the selectTxPowerScenario HIDL method invocation for 1.0 interface.
2894      * This should return failure since SAR is not supported for this interface version.
2895      */
2896     @Test
testSelectTxPowerScenario_1_0()2897     public void testSelectTxPowerScenario_1_0() throws RemoteException {
2898         // Create a SAR info record
2899         SarInfo sarInfo = new SarInfo();
2900         sarInfo.isVoiceCall = true;
2901 
2902         assertTrue(mWifiVendorHal.startVendorHalSta());
2903         // Should fail because we exposed the 1.0 IWifiChip.
2904         assertFalse(mWifiVendorHal.selectTxPowerScenario(sarInfo));
2905         verify(mIWifiChipV11, never()).selectTxPowerScenario(anyInt());
2906         mWifiVendorHal.stopVendorHal();
2907     }
2908 
2909     /**
2910      * Test the selectTxPowerScenario HIDL method invocation for 1.1 interface.
2911      * This should return success.
2912      */
2913     @Test
testSelectTxPowerScenario_1_1()2914     public void testSelectTxPowerScenario_1_1() throws RemoteException {
2915         // Create a SAR info record
2916         SarInfo sarInfo = new SarInfo();
2917         sarInfo.sarVoiceCallSupported = true;
2918         sarInfo.sarSapSupported = false;
2919 
2920         sarInfo.isVoiceCall = true;
2921 
2922         // Now expose the 1.1 IWifiChip.
2923         mWifiVendorHal = new WifiVendorHalSpyV1_1(mContext, mHalDeviceManager, mHandler,
2924                 mWifiGlobals);
2925         when(mIWifiChipV11.selectTxPowerScenario(anyInt())).thenReturn(mWifiStatusSuccess);
2926 
2927         assertTrue(mWifiVendorHal.startVendorHalSta());
2928         assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
2929         verify(mIWifiChipV11).selectTxPowerScenario(
2930                 eq(android.hardware.wifi.V1_1.IWifiChip.TxPowerScenario.VOICE_CALL));
2931         verify(mIWifiChipV11, never()).resetTxPowerScenario();
2932         mWifiVendorHal.stopVendorHal();
2933     }
2934 
2935    /**
2936      * Test the selectTxPowerScenario HIDL method invocation for 1.2 interface.
2937      * This should return success.
2938      */
2939     @Test
testSelectTxPowerScenario_1_2()2940     public void testSelectTxPowerScenario_1_2() throws RemoteException {
2941         // Create a SAR info record
2942         SarInfo sarInfo = new SarInfo();
2943         sarInfo.sarVoiceCallSupported = true;
2944         sarInfo.sarSapSupported = false;
2945 
2946         sarInfo.isVoiceCall = true;
2947 
2948         // Now expose the 1.2 IWifiChip
2949         mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
2950                 mWifiGlobals);
2951         when(mIWifiChipV12.selectTxPowerScenario_1_2(anyInt())).thenReturn(mWifiStatusSuccess);
2952 
2953         assertTrue(mWifiVendorHal.startVendorHalSta());
2954         assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
2955         verify(mIWifiChipV12).selectTxPowerScenario_1_2(
2956                 eq(android.hardware.wifi.V1_2.IWifiChip.TxPowerScenario.VOICE_CALL));
2957         verify(mIWifiChipV12, never()).resetTxPowerScenario();
2958         mWifiVendorHal.stopVendorHal();
2959     }
2960 
2961     /**
2962      * Test the resetTxPowerScenario HIDL method invocation for 1.0 interface.
2963      * This should return failure since it does not supprt SAR.
2964      */
2965     @Test
testResetTxPowerScenario_1_0()2966     public void testResetTxPowerScenario_1_0() throws RemoteException {
2967         // Create a SAR info record
2968         SarInfo sarInfo = new SarInfo();
2969 
2970         assertTrue(mWifiVendorHal.startVendorHalSta());
2971         // Should fail because we exposed the 1.0 IWifiChip.
2972         assertFalse(mWifiVendorHal.selectTxPowerScenario(sarInfo));
2973         verify(mIWifiChipV11, never()).resetTxPowerScenario();
2974         mWifiVendorHal.stopVendorHal();
2975     }
2976 
2977     /**
2978      * Test the resetTxPowerScenario HIDL method invocation for 1.1 interface.
2979      * This should return success.
2980      */
2981     @Test
testResetTxPowerScenario_1_1()2982     public void testResetTxPowerScenario_1_1() throws RemoteException {
2983         // Create a SAR info record
2984         SarInfo sarInfo = new SarInfo();
2985         sarInfo.sarVoiceCallSupported = true;
2986         sarInfo.sarSapSupported = false;
2987 
2988         // Now expose the 1.1 IWifiChip.
2989         mWifiVendorHal = new WifiVendorHalSpyV1_1(mContext, mHalDeviceManager, mHandler,
2990                 mWifiGlobals);
2991         when(mIWifiChipV11.resetTxPowerScenario()).thenReturn(mWifiStatusSuccess);
2992 
2993         assertTrue(mWifiVendorHal.startVendorHalSta());
2994         assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
2995         verify(mIWifiChipV11).resetTxPowerScenario();
2996         verify(mIWifiChipV11, never()).selectTxPowerScenario(anyInt());
2997         mWifiVendorHal.stopVendorHal();
2998     }
2999 
3000     /**
3001      * Test resetting SAR scenario when not needed, should return true without invoking
3002      * the HAL method.
3003      * This is using HAL 1.1 interface.
3004      */
3005     @Test
testResetTxPowerScenario_not_needed_1_1()3006     public void testResetTxPowerScenario_not_needed_1_1() throws RemoteException {
3007         InOrder inOrder = inOrder(mIWifiChipV11);
3008 
3009         // Create a SAR info record (no SAP support)
3010         SarInfo sarInfo = new SarInfo();
3011         sarInfo.sarVoiceCallSupported = true;
3012         sarInfo.sarSapSupported = false;
3013 
3014         // Now expose the 1.1 IWifiChip.
3015         mWifiVendorHal = new WifiVendorHalSpyV1_1(mContext, mHalDeviceManager, mHandler,
3016                 mWifiGlobals);
3017         when(mIWifiChipV11.resetTxPowerScenario()).thenReturn(mWifiStatusSuccess);
3018 
3019         assertTrue(mWifiVendorHal.startVendorHalSta());
3020 
3021         /* Calling reset once */
3022         assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
3023         inOrder.verify(mIWifiChipV11).resetTxPowerScenario();
3024         inOrder.verify(mIWifiChipV11, never()).selectTxPowerScenario(anyInt());
3025         sarInfo.reportingSuccessful();
3026 
3027         /* Calling reset second time */
3028         assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
3029         inOrder.verify(mIWifiChipV11, never()).resetTxPowerScenario();
3030         inOrder.verify(mIWifiChipV11, never()).selectTxPowerScenario(anyInt());
3031 
3032         mWifiVendorHal.stopVendorHal();
3033     }
3034 
3035     /**
3036      * Test the new resetTxPowerScenario HIDL method invocation for 1.2 interface.
3037      * This should return success.
3038      */
3039     @Test
testResetTxPowerScenario_1_2()3040     public void testResetTxPowerScenario_1_2() throws RemoteException {
3041         // Create a SAR info record (no SAP support)
3042         SarInfo sarInfo = new SarInfo();
3043         sarInfo.sarVoiceCallSupported = true;
3044         sarInfo.sarSapSupported = false;
3045 
3046         // Now expose the 1.2 IWifiChip.
3047         mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
3048                 mWifiGlobals);
3049         when(mIWifiChipV12.resetTxPowerScenario()).thenReturn(mWifiStatusSuccess);
3050 
3051         assertTrue(mWifiVendorHal.startVendorHalSta());
3052         assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
3053         verify(mIWifiChipV12).resetTxPowerScenario();
3054         verify(mIWifiChipV12, never()).selectTxPowerScenario_1_2(anyInt());
3055         mWifiVendorHal.stopVendorHal();
3056     }
3057 
3058     /**
3059      * Test resetting SAR scenario when not needed, should return true without invoking
3060      * the HAL method.
3061      * This is using HAL 1.2 interface.
3062      */
3063     @Test
testResetTxPowerScenario_not_needed_1_2()3064     public void testResetTxPowerScenario_not_needed_1_2() throws RemoteException {
3065         InOrder inOrder = inOrder(mIWifiChipV12);
3066 
3067         // Create a SAR info record (no SAP support)
3068         SarInfo sarInfo = new SarInfo();
3069         sarInfo.sarVoiceCallSupported = true;
3070         sarInfo.sarSapSupported = false;
3071 
3072         // Now expose the 1.2 IWifiChip.
3073         mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
3074                 mWifiGlobals);
3075         when(mIWifiChipV12.resetTxPowerScenario()).thenReturn(mWifiStatusSuccess);
3076 
3077         assertTrue(mWifiVendorHal.startVendorHalSta());
3078 
3079         /* Calling reset once */
3080         assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
3081         inOrder.verify(mIWifiChipV12).resetTxPowerScenario();
3082         inOrder.verify(mIWifiChipV12, never()).selectTxPowerScenario(anyInt());
3083         sarInfo.reportingSuccessful();
3084 
3085         /* Calling reset second time */
3086         assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
3087         inOrder.verify(mIWifiChipV12, never()).resetTxPowerScenario();
3088         inOrder.verify(mIWifiChipV12, never()).selectTxPowerScenario(anyInt());
3089 
3090         mWifiVendorHal.stopVendorHal();
3091     }
3092 
3093      /**
3094      * Test the selectTxPowerScenario HIDL method invocation with SAP and voice call support.
3095      * When SAP is enabled, should result in SAP with near body scenario
3096      * Using IWifiChip 1.2 interface
3097      */
3098     @Test
testSapScenarios_SelectTxPowerV1_2()3099     public void testSapScenarios_SelectTxPowerV1_2() throws RemoteException {
3100         // Create a SAR info record (with SAP support)
3101         SarInfo sarInfo = new SarInfo();
3102         sarInfo.sarVoiceCallSupported = true;
3103         sarInfo.sarSapSupported = true;
3104         sarInfo.isWifiSapEnabled = true;
3105 
3106         // Expose the 1.2 IWifiChip.
3107         mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
3108                 mWifiGlobals);
3109         when(mIWifiChipV12.selectTxPowerScenario_1_2(anyInt())).thenReturn(mWifiStatusSuccess);
3110 
3111         // ON_BODY_CELL_ON
3112         assertTrue(mWifiVendorHal.startVendorHalSta());
3113         assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
3114         verify(mIWifiChipV12).selectTxPowerScenario_1_2(
3115                 eq(android.hardware.wifi.V1_2.IWifiChip.TxPowerScenario.ON_BODY_CELL_ON));
3116         verify(mIWifiChipV12, never()).resetTxPowerScenario();
3117         mWifiVendorHal.stopVendorHal();
3118     }
3119 
3120     /**
3121      * Test the selectTxPowerScenario HIDL method invocation with SAP and voice call support.
3122      * When a voice call is ongoing, should result in cell with near head scenario
3123      * Using IWifiChip 1.2 interface
3124      */
3125     @Test
testVoiceCallScenarios_SelectTxPowerV1_2()3126     public void testVoiceCallScenarios_SelectTxPowerV1_2() throws RemoteException {
3127         // Create a SAR info record (with SAP support)
3128         SarInfo sarInfo = new SarInfo();
3129         sarInfo.sarVoiceCallSupported = true;
3130         sarInfo.sarSapSupported = true;
3131 
3132         sarInfo.isVoiceCall = true;
3133 
3134         // Expose the 1.2 IWifiChip.
3135         mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
3136                 mWifiGlobals);
3137         when(mIWifiChipV12.selectTxPowerScenario_1_2(anyInt())).thenReturn(mWifiStatusSuccess);
3138 
3139         // ON_HEAD_CELL_ON
3140         assertTrue(mWifiVendorHal.startVendorHalSta());
3141         assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
3142         verify(mIWifiChipV12).selectTxPowerScenario_1_2(
3143                 eq(android.hardware.wifi.V1_2.IWifiChip.TxPowerScenario.ON_HEAD_CELL_ON));
3144         verify(mIWifiChipV12, never()).resetTxPowerScenario();
3145         mWifiVendorHal.stopVendorHal();
3146     }
3147 
3148     /**
3149      * Test the selectTxPowerScenario HIDL method invocation with SAP and voice call support.
3150      * When earpiece is active, should result in cell with near head scenario
3151      * Using IWifiChip 1.2 interface
3152      */
3153     @Test
testEarPieceScenarios_SelectTxPowerV1_2()3154     public void testEarPieceScenarios_SelectTxPowerV1_2() throws RemoteException {
3155         // Create a SAR info record (with SAP support)
3156         SarInfo sarInfo = new SarInfo();
3157         sarInfo.sarVoiceCallSupported = true;
3158         sarInfo.sarSapSupported = true;
3159 
3160         sarInfo.isEarPieceActive = true;
3161 
3162         // Expose the 1.2 IWifiChip.
3163         mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
3164                 mWifiGlobals);
3165         when(mIWifiChipV12.selectTxPowerScenario_1_2(anyInt())).thenReturn(mWifiStatusSuccess);
3166 
3167         // ON_HEAD_CELL_ON
3168         assertTrue(mWifiVendorHal.startVendorHalSta());
3169         assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
3170         verify(mIWifiChipV12).selectTxPowerScenario_1_2(
3171                 eq(android.hardware.wifi.V1_2.IWifiChip.TxPowerScenario.ON_HEAD_CELL_ON));
3172         verify(mIWifiChipV12, never()).resetTxPowerScenario();
3173         mWifiVendorHal.stopVendorHal();
3174     }
3175 
3176     /**
3177      * Test setting SAR scenario when not needed, should return true without invoking
3178      * the HAL method.
3179      * This is using HAL 1.2 interface.
3180      */
3181     @Test
testSetTxPowerScenario_not_needed_1_2()3182     public void testSetTxPowerScenario_not_needed_1_2() throws RemoteException {
3183         InOrder inOrder = inOrder(mIWifiChipV12);
3184 
3185         // Create a SAR info record (no SAP support)
3186         SarInfo sarInfo = new SarInfo();
3187         sarInfo.sarVoiceCallSupported = true;
3188         sarInfo.sarSapSupported = true;
3189 
3190         // Now expose the 1.2 IWifiChip.
3191         mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
3192                 mWifiGlobals);
3193         when(mIWifiChipV12.resetTxPowerScenario()).thenReturn(mWifiStatusSuccess);
3194 
3195         assertTrue(mWifiVendorHal.startVendorHalSta());
3196 
3197         /* Calling set once */
3198         assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
3199         inOrder.verify(mIWifiChipV12).resetTxPowerScenario();
3200         sarInfo.reportingSuccessful();
3201 
3202         /* Calling set second time */
3203         assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
3204         inOrder.verify(mIWifiChipV12, never()).resetTxPowerScenario();
3205         inOrder.verify(mIWifiChipV12, never()).selectTxPowerScenario(anyInt());
3206 
3207         mWifiVendorHal.stopVendorHal();
3208     }
3209 
3210     /**
3211      * Test the selectTxPowerScenario HIDL method invocation with IWifiChip 1.2 interface.
3212      * The following inputs:
3213      *   - SAP is enabled
3214      *   - No voice call
3215      */
3216     @Test
testSelectTxPowerScenario_1_2_sap()3217     public void testSelectTxPowerScenario_1_2_sap() throws RemoteException {
3218         // Create a SAR info record (with SAP support)
3219         SarInfo sarInfo = new SarInfo();
3220         sarInfo.sarVoiceCallSupported = true;
3221         sarInfo.sarSapSupported = true;
3222 
3223         sarInfo.isWifiSapEnabled = true;
3224         sarInfo.isVoiceCall = false;
3225 
3226         // Expose the 1.2 IWifiChip.
3227         mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
3228                 mWifiGlobals);
3229         when(mIWifiChipV12.selectTxPowerScenario_1_2(anyInt())).thenReturn(mWifiStatusSuccess);
3230 
3231         assertTrue(mWifiVendorHal.startVendorHalSta());
3232         assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
3233         verify(mIWifiChipV12).selectTxPowerScenario_1_2(
3234                 eq(android.hardware.wifi.V1_2.IWifiChip.TxPowerScenario.ON_BODY_CELL_ON));
3235 
3236         mWifiVendorHal.stopVendorHal();
3237     }
3238 
3239     /**
3240      * Test the selectTxPowerScenario HIDL method invocation with IWifiChip 1.2 interface.
3241      * The following inputs:
3242      *   - SAP is enabled
3243      *   - voice call is enabled
3244      */
3245     @Test
testSelectTxPowerScenario_1_2_head_sap_call()3246     public void testSelectTxPowerScenario_1_2_head_sap_call() throws RemoteException {
3247         // Create a SAR info record (with SAP support)
3248         SarInfo sarInfo = new SarInfo();
3249         sarInfo.sarVoiceCallSupported = true;
3250         sarInfo.sarSapSupported = true;
3251 
3252         sarInfo.isWifiSapEnabled = true;
3253         sarInfo.isVoiceCall = true;
3254 
3255         // Expose the 1.2 IWifiChip.
3256         mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
3257                 mWifiGlobals);
3258         when(mIWifiChipV12.selectTxPowerScenario_1_2(anyInt())).thenReturn(mWifiStatusSuccess);
3259 
3260         assertTrue(mWifiVendorHal.startVendorHalSta());
3261         assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
3262         verify(mIWifiChipV12).selectTxPowerScenario_1_2(
3263                 eq(android.hardware.wifi.V1_2.IWifiChip.TxPowerScenario.ON_HEAD_CELL_ON));
3264 
3265         mWifiVendorHal.stopVendorHal();
3266     }
3267 
3268     /**
3269      * Test the setLowLatencyMode HIDL method invocation with IWifiChip 1.2 interface.
3270      * Function should return false
3271      */
3272     @Test
testSetLowLatencyMode_1_2()3273     public void testSetLowLatencyMode_1_2() throws RemoteException {
3274         // Expose the 1.2 IWifiChip.
3275         mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
3276                 mWifiGlobals);
3277         assertFalse(mWifiVendorHal.setLowLatencyMode(true));
3278         assertFalse(mWifiVendorHal.setLowLatencyMode(false));
3279     }
3280 
3281     /**
3282      * Test the setLowLatencyMode HIDL method invocation with IWifiChip 1.3 interface
3283      */
3284     @Test
testSetLowLatencyMode_1_3_enabled()3285     public void testSetLowLatencyMode_1_3_enabled() throws RemoteException {
3286         int mode = android.hardware.wifi.V1_3.IWifiChip.LatencyMode.LOW;
3287 
3288         // Expose the 1.3 IWifiChip.
3289         mWifiVendorHal = new WifiVendorHalSpyV1_3(mContext, mHalDeviceManager, mHandler,
3290                 mWifiGlobals);
3291         when(mIWifiChipV13.setLatencyMode(anyInt())).thenReturn(mWifiStatusSuccess);
3292         assertTrue(mWifiVendorHal.setLowLatencyMode(true));
3293         verify(mIWifiChipV13).setLatencyMode(eq(mode));
3294     }
3295 
3296     /**
3297      * Test the setLowLatencyMode HIDL method invocation with IWifiChip 1.3 interface
3298      */
3299     @Test
testSetLowLatencyMode_1_3_disabled()3300     public void testSetLowLatencyMode_1_3_disabled() throws RemoteException {
3301         int mode = android.hardware.wifi.V1_3.IWifiChip.LatencyMode.NORMAL;
3302 
3303         // Expose the 1.3 IWifiChip.
3304         mWifiVendorHal = new WifiVendorHalSpyV1_3(mContext, mHalDeviceManager, mHandler,
3305                 mWifiGlobals);
3306         when(mIWifiChipV13.setLatencyMode(anyInt())).thenReturn(mWifiStatusSuccess);
3307         assertTrue(mWifiVendorHal.setLowLatencyMode(false));
3308         verify(mIWifiChipV13).setLatencyMode(eq(mode));
3309     }
3310 
3311     /**
3312      * Test the STA Iface creation failure due to iface name retrieval failure.
3313      */
3314     @Test
testCreateStaIfaceFailureInIfaceName()3315     public void testCreateStaIfaceFailureInIfaceName() throws RemoteException {
3316         doAnswer(new AnswerWithArguments() {
3317             public void answer(IWifiIface.getNameCallback cb)
3318                     throws RemoteException {
3319                 cb.onValues(mWifiStatusFailure, "wlan0");
3320             }
3321         }).when(mIWifiStaIface).getName(any(IWifiIface.getNameCallback.class));
3322 
3323         assertTrue(mWifiVendorHal.startVendorHal());
3324         assertNull(mWifiVendorHal.createStaIface(null, TEST_WORKSOURCE));
3325         verify(mHalDeviceManager).createStaIface(any(), eq(null), eq(TEST_WORKSOURCE));
3326     }
3327 
3328     /**
3329      * Test the STA Iface creation failure due to iface name retrieval failure.
3330      */
3331     @Test
testCreateApIfaceFailureInIfaceName()3332     public void testCreateApIfaceFailureInIfaceName() throws RemoteException {
3333         doAnswer(new AnswerWithArguments() {
3334             public void answer(IWifiIface.getNameCallback cb)
3335                     throws RemoteException {
3336                 cb.onValues(mWifiStatusFailure, "wlan0");
3337             }
3338         }).when(mIWifiApIface).getName(any(IWifiIface.getNameCallback.class));
3339 
3340         assertTrue(mWifiVendorHal.startVendorHal());
3341         assertNull(mWifiVendorHal.createApIface(
3342                 null, TEST_WORKSOURCE, SoftApConfiguration.BAND_2GHZ, false));
3343         verify(mHalDeviceManager).createApIface(
3344                 anyLong(), any(), eq(null), eq(TEST_WORKSOURCE), eq(false));
3345     }
3346 
3347     /**
3348      * Test the creation and removal of STA Iface.
3349      */
3350     @Test
testCreateRemoveStaIface()3351     public void testCreateRemoveStaIface() throws RemoteException {
3352         assertTrue(mWifiVendorHal.startVendorHal());
3353         String ifaceName = mWifiVendorHal.createStaIface(null, TEST_WORKSOURCE);
3354         verify(mHalDeviceManager).createStaIface(any(), eq(null), eq(TEST_WORKSOURCE));
3355         assertEquals(TEST_IFACE_NAME, ifaceName);
3356         assertTrue(mWifiVendorHal.removeStaIface(ifaceName));
3357         verify(mHalDeviceManager).removeIface(eq(mIWifiStaIface));
3358     }
3359 
3360     /**
3361      * Test the creation and removal of Ap Iface.
3362      */
3363     @Test
testCreateRemoveApIface()3364     public void testCreateRemoveApIface() throws RemoteException {
3365         assertTrue(mWifiVendorHal.startVendorHal());
3366         String ifaceName = mWifiVendorHal.createApIface(
3367                 null, TEST_WORKSOURCE, SoftApConfiguration.BAND_2GHZ, false);
3368         verify(mHalDeviceManager).createApIface(
3369                 anyLong(), any(), eq(null), eq(TEST_WORKSOURCE), eq(false));
3370         assertEquals(TEST_IFACE_NAME, ifaceName);
3371         assertTrue(mWifiVendorHal.removeApIface(ifaceName));
3372         verify(mHalDeviceManager).removeIface(eq(mIWifiApIface));
3373     }
3374 
3375     /**
3376      * Test removeIfaceInstanceFromBridgedApIface
3377      */
3378     @Test
testRemoveIfaceInstanceFromBridgedApIface()3379     public void testRemoveIfaceInstanceFromBridgedApIface() throws RemoteException {
3380         mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler,
3381                 mWifiGlobals);
3382         when(mIWifiChipV15.removeIfaceInstanceFromBridgedApIface(any(), any()))
3383                 .thenReturn(mWifiStatusSuccess);
3384         assertTrue(mWifiVendorHal.removeIfaceInstanceFromBridgedApIface(any(), any()));
3385     }
3386 
3387     /**
3388      * Test setCoexUnsafeChannels
3389      */
3390     @Test
testSetCoexUnsafeChannels()3391     public void testSetCoexUnsafeChannels() throws RemoteException {
3392         assumeTrue(SdkLevel.isAtLeastS());
3393         mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler,
3394                 mWifiGlobals);
3395         when(mIWifiChipV15.setCoexUnsafeChannels(any(), anyInt()))
3396                 .thenReturn(mWifiStatusSuccess);
3397         final List<CoexUnsafeChannel> unsafeChannels = new ArrayList<>();
3398         unsafeChannels.add(new CoexUnsafeChannel(WifiScanner.WIFI_BAND_24_GHZ, 6));
3399         unsafeChannels.add(new CoexUnsafeChannel(WifiScanner.WIFI_BAND_5_GHZ, 36));
3400         final int restrictions = WifiManager.COEX_RESTRICTION_WIFI_DIRECT
3401                 | WifiManager.COEX_RESTRICTION_WIFI_AWARE | WifiManager.COEX_RESTRICTION_SOFTAP;
3402         assertTrue(mWifiVendorHal.setCoexUnsafeChannels(unsafeChannels, restrictions));
3403     }
3404 
3405     /**
3406      * Test the callback handling for the 1.2 HAL.
3407      */
3408     @Test
testAlertCallbackUsing_1_2_EventCallback()3409     public void testAlertCallbackUsing_1_2_EventCallback() throws Exception {
3410         // Expose the 1.2 IWifiChip.
3411         mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
3412                 mWifiGlobals);
3413 
3414         assertTrue(mWifiVendorHal.startVendorHalSta());
3415         assertNotNull(mIWifiChipEventCallbackV12);
3416 
3417         testAlertCallbackUsingProvidedCallback(mIWifiChipEventCallbackV12);
3418     }
3419 
3420     /**
3421      * Verifies setMacAddress() success.
3422      */
3423     @Test
testSetStaMacAddressSuccess()3424     public void testSetStaMacAddressSuccess() throws Exception {
3425         // Expose the 1.2 IWifiStaIface.
3426         mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
3427                 mWifiGlobals);
3428         byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray();
3429         when(mIWifiStaIfaceV12.setMacAddress(macByteArray)).thenReturn(mWifiStatusSuccess);
3430 
3431         assertTrue(mWifiVendorHal.setStaMacAddress(TEST_IFACE_NAME, TEST_MAC_ADDRESS));
3432         verify(mIWifiStaIfaceV12).setMacAddress(macByteArray);
3433     }
3434 
3435     /**
3436      * Verifies setMacAddress() can handle failure status.
3437      */
3438     @Test
testSetStaMacAddressFailDueToStatusFailure()3439     public void testSetStaMacAddressFailDueToStatusFailure() throws Exception {
3440         // Expose the 1.2 IWifiStaIface.
3441         mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
3442                 mWifiGlobals);
3443         byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray();
3444         when(mIWifiStaIfaceV12.setMacAddress(macByteArray)).thenReturn(mWifiStatusFailure);
3445 
3446         assertFalse(mWifiVendorHal.setStaMacAddress(TEST_IFACE_NAME, TEST_MAC_ADDRESS));
3447         verify(mIWifiStaIfaceV12).setMacAddress(macByteArray);
3448     }
3449 
3450     /**
3451      * Verifies setMacAddress() can handle RemoteException.
3452      */
3453     @Test
testSetStaMacAddressFailDueToRemoteException()3454     public void testSetStaMacAddressFailDueToRemoteException() throws Exception {
3455         // Expose the 1.2 IWifiStaIface.
3456         mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
3457                 mWifiGlobals);
3458         byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray();
3459         doThrow(new RemoteException()).when(mIWifiStaIfaceV12).setMacAddress(macByteArray);
3460 
3461         assertFalse(mWifiVendorHal.setStaMacAddress(TEST_IFACE_NAME, TEST_MAC_ADDRESS));
3462         verify(mIWifiStaIfaceV12).setMacAddress(macByteArray);
3463     }
3464 
3465     /**
3466      * Verifies setMacAddress() success.
3467      */
3468     @Test
testSetApMacAddressSuccess()3469     public void testSetApMacAddressSuccess() throws Exception {
3470         mWifiVendorHal = spy(mWifiVendorHal);
3471         when(mWifiVendorHal.getWifiApIfaceForV1_4Mockable(TEST_IFACE_NAME_1))
3472                 .thenReturn(mIWifiApIfaceV14);
3473         byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray();
3474         when(mIWifiApIfaceV14.setMacAddress(macByteArray)).thenReturn(mWifiStatusSuccess);
3475 
3476         assertTrue(mWifiVendorHal.setApMacAddress(TEST_IFACE_NAME_1, TEST_MAC_ADDRESS));
3477         verify(mIWifiApIfaceV14).setMacAddress(macByteArray);
3478     }
3479 
3480     /**
3481      * Verifies setMacAddress() can handle failure status.
3482      */
3483     @Test
testSetApMacAddressFailDueToStatusFailure()3484     public void testSetApMacAddressFailDueToStatusFailure() throws Exception {
3485         mWifiVendorHal = spy(mWifiVendorHal);
3486         when(mWifiVendorHal.getWifiApIfaceForV1_4Mockable(TEST_IFACE_NAME_1))
3487                 .thenReturn(mIWifiApIfaceV14);
3488         byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray();
3489         when(mIWifiApIfaceV14.setMacAddress(macByteArray)).thenReturn(mWifiStatusFailure);
3490 
3491         assertFalse(mWifiVendorHal.setApMacAddress(TEST_IFACE_NAME_1, TEST_MAC_ADDRESS));
3492         verify(mIWifiApIfaceV14).setMacAddress(macByteArray);
3493     }
3494 
3495     /**
3496      * Verifies setMacAddress() can handle RemoteException.
3497      */
3498     @Test
testSetApMacAddressFailDueToRemoteException()3499     public void testSetApMacAddressFailDueToRemoteException() throws Exception {
3500         mWifiVendorHal = spy(mWifiVendorHal);
3501         when(mWifiVendorHal.getWifiApIfaceForV1_4Mockable(TEST_IFACE_NAME_1))
3502                 .thenReturn(mIWifiApIfaceV14);
3503         byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray();
3504         doThrow(new RemoteException()).when(mIWifiApIfaceV14).setMacAddress(macByteArray);
3505 
3506         assertFalse(mWifiVendorHal.setApMacAddress(TEST_IFACE_NAME_1, TEST_MAC_ADDRESS));
3507         verify(mIWifiApIfaceV14).setMacAddress(macByteArray);
3508     }
3509 
3510     /**
3511      * Verifies setMacAddress() does not crash with older HALs.
3512      */
3513     @Test
testSetMacAddressDoesNotCrashOnOlderHal()3514     public void testSetMacAddressDoesNotCrashOnOlderHal() throws Exception {
3515         byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray();
3516         assertFalse(mWifiVendorHal.setStaMacAddress(TEST_IFACE_NAME, TEST_MAC_ADDRESS));
3517         assertFalse(mWifiVendorHal.setApMacAddress(TEST_IFACE_NAME, TEST_MAC_ADDRESS));
3518     }
3519 
3520     /**
3521      * Verifies resetApMacToFactoryMacAddress resetToFactoryMacAddress() success.
3522      */
3523     @Test
testResetApMacToFactoryMacAddressSuccess()3524     public void testResetApMacToFactoryMacAddressSuccess() throws Exception {
3525         mWifiVendorHal = spy(mWifiVendorHal);
3526         when(mWifiVendorHal.getWifiApIfaceForV1_5Mockable(TEST_IFACE_NAME_1))
3527                 .thenReturn(mIWifiApIfaceV15);
3528         when(mIWifiApIfaceV15.resetToFactoryMacAddress()).thenReturn(mWifiStatusSuccess);
3529 
3530         assertTrue(mWifiVendorHal.resetApMacToFactoryMacAddress(TEST_IFACE_NAME_1));
3531         verify(mIWifiApIfaceV15).resetToFactoryMacAddress();
3532     }
3533 
3534     /**
3535      * Verifies resetApMacToFactoryMacAddress() can handle failure status.
3536      */
3537     @Test
testResetApMacToFactoryMacAddressFailDueToStatusFailure()3538     public void testResetApMacToFactoryMacAddressFailDueToStatusFailure() throws Exception {
3539         mWifiVendorHal = spy(mWifiVendorHal);
3540         when(mWifiVendorHal.getWifiApIfaceForV1_5Mockable(TEST_IFACE_NAME_1))
3541                 .thenReturn(mIWifiApIfaceV15);
3542         when(mIWifiApIfaceV15.resetToFactoryMacAddress()).thenReturn(mWifiStatusFailure);
3543 
3544         assertFalse(mWifiVendorHal.resetApMacToFactoryMacAddress(TEST_IFACE_NAME_1));
3545         verify(mIWifiApIfaceV15).resetToFactoryMacAddress();
3546     }
3547 
3548     /**
3549      * Verifies resetApMacToFactoryMacAddress() can handle RemoteException.
3550      */
3551     @Test
testResetApMacToFactoryMacAddressFailDueToRemoteException()3552     public void testResetApMacToFactoryMacAddressFailDueToRemoteException() throws Exception {
3553         mWifiVendorHal = spy(mWifiVendorHal);
3554         when(mWifiVendorHal.getWifiApIfaceForV1_5Mockable(TEST_IFACE_NAME_1))
3555                 .thenReturn(mIWifiApIfaceV15);
3556         doThrow(new RemoteException()).when(mIWifiApIfaceV15).resetToFactoryMacAddress();
3557         assertFalse(mWifiVendorHal.resetApMacToFactoryMacAddress(TEST_IFACE_NAME_1));
3558         verify(mIWifiApIfaceV15).resetToFactoryMacAddress();
3559     }
3560 
3561     /**
3562      * Verifies resetApMacToFactoryMacAddress() does not crash with older HALs.
3563      */
3564     @Test
testResetApMacToFactoryMacAddressDoesNotCrashOnOlderHal()3565     public void testResetApMacToFactoryMacAddressDoesNotCrashOnOlderHal() throws Exception {
3566         assertFalse(mWifiVendorHal.resetApMacToFactoryMacAddress(TEST_IFACE_NAME));
3567     }
3568 
3569     /**
3570      * Verifies getBridgedApInstances() success.
3571      */
3572     @Test
testGetBridgedApInstancesSuccess()3573     public void testGetBridgedApInstancesSuccess() throws Exception {
3574         doAnswer(new AnswerWithArguments() {
3575             public void answer(
3576                     android.hardware.wifi.V1_5.IWifiApIface.getBridgedInstancesCallback cb)
3577                     throws RemoteException {
3578                 cb.onValues(mWifiStatusSuccess,
3579                         new ArrayList<String>() {{ add(TEST_IFACE_NAME_1); }});
3580             }
3581         }).when(mIWifiApIfaceV15).getBridgedInstances(any(
3582                 android.hardware.wifi.V1_5.IWifiApIface.getBridgedInstancesCallback.class));
3583         mWifiVendorHal = spy(mWifiVendorHal);
3584         when(mWifiVendorHal.getWifiApIfaceForV1_5Mockable(TEST_IFACE_NAME_1))
3585                 .thenReturn(mIWifiApIfaceV15);
3586 
3587         assertNotNull(mWifiVendorHal.getBridgedApInstances(TEST_IFACE_NAME_1));
3588         verify(mIWifiApIfaceV15).getBridgedInstances(any());
3589     }
3590 
3591     /**
3592      * Verifies getBridgedApInstances() can handle failure status.
3593      */
3594     @Test
testGetBridgedApInstancesFailDueToStatusFailure()3595     public void testGetBridgedApInstancesFailDueToStatusFailure() throws Exception {
3596         doAnswer(new AnswerWithArguments() {
3597             public void answer(
3598                     android.hardware.wifi.V1_5.IWifiApIface.getBridgedInstancesCallback cb)
3599                     throws RemoteException {
3600                 cb.onValues(mWifiStatusFailure, null);
3601             }
3602         }).when(mIWifiApIfaceV15).getBridgedInstances(any(
3603                 android.hardware.wifi.V1_5.IWifiApIface.getBridgedInstancesCallback.class));
3604 
3605         mWifiVendorHal = spy(mWifiVendorHal);
3606         when(mWifiVendorHal.getWifiApIfaceForV1_5Mockable(TEST_IFACE_NAME_1))
3607                 .thenReturn(mIWifiApIfaceV15);
3608         assertNull(mWifiVendorHal.getBridgedApInstances(TEST_IFACE_NAME_1));
3609         verify(mIWifiApIfaceV15).getBridgedInstances(any());
3610     }
3611 
3612     /**
3613      * Verifies getBridgedApInstances() can handle RemoteException.
3614      */
3615     @Test
testGetBridgedApInstancesFailDueToRemoteException()3616     public void testGetBridgedApInstancesFailDueToRemoteException() throws Exception {
3617         mWifiVendorHal = spy(mWifiVendorHal);
3618         when(mWifiVendorHal.getWifiApIfaceForV1_5Mockable(TEST_IFACE_NAME_1))
3619                 .thenReturn(mIWifiApIfaceV15);
3620         doThrow(new RemoteException()).when(mIWifiApIfaceV15).getBridgedInstances(any());
3621         assertNull(mWifiVendorHal.getBridgedApInstances(TEST_IFACE_NAME_1));
3622         verify(mIWifiApIfaceV15).getBridgedInstances(any());
3623     }
3624 
3625     /**
3626      * Verifies getBridgedApInstances() does not crash with older HALs.
3627      */
3628     @Test
testGetBridgedApInstancesNotCrashOnOlderHal()3629     public void testGetBridgedApInstancesNotCrashOnOlderHal() throws Exception {
3630         assertNull(mWifiVendorHal.getBridgedApInstances(TEST_IFACE_NAME));
3631     }
3632 
3633     /**
3634      * Verifies isSetMacAddressSupported().
3635      */
3636     @Test
testIsApSetMacAddressSupportedWhenV1_4Support()3637     public void testIsApSetMacAddressSupportedWhenV1_4Support() throws Exception {
3638         mWifiVendorHal = spy(mWifiVendorHal);
3639         when(mWifiVendorHal.getWifiApIfaceForV1_4Mockable(TEST_IFACE_NAME_1))
3640                 .thenReturn(mIWifiApIfaceV14);
3641 
3642         assertTrue(mWifiVendorHal.isApSetMacAddressSupported(TEST_IFACE_NAME_1));
3643     }
3644 
3645     /**
3646      * Verifies isSetMacAddressSupported().
3647      */
3648     @Test
testIsStaSetMacAddressSupportedWhenV1_2Support()3649     public void testIsStaSetMacAddressSupportedWhenV1_2Support() throws Exception {
3650         // Expose the 1.2 IWifiStaIface.
3651         mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
3652                 mWifiGlobals);
3653         assertTrue(mWifiVendorHal.isStaSetMacAddressSupported(TEST_IFACE_NAME));
3654     }
3655 
3656     /**
3657      * Verifies isSetMacAddressSupported() does not crash with older HALs.
3658      */
3659     @Test
testIsSetMacAddressSupportedOnOlderHal()3660     public void testIsSetMacAddressSupportedOnOlderHal() throws Exception {
3661         assertFalse(mWifiVendorHal.isStaSetMacAddressSupported(TEST_IFACE_NAME));
3662         assertFalse(mWifiVendorHal.isApSetMacAddressSupported(TEST_IFACE_NAME));
3663     }
3664 
3665     /**
3666      * Verifies radio mode change callback to indicate DBS mode.
3667      */
3668     @Test
testRadioModeChangeCallbackToDbsMode()3669     public void testRadioModeChangeCallbackToDbsMode() throws Exception {
3670         startHalInStaModeAndRegisterRadioModeChangeCallback();
3671 
3672         RadioModeInfo radioModeInfo0 = new RadioModeInfo();
3673         radioModeInfo0.bandInfo = WifiScanner.WIFI_BAND_5_GHZ;
3674         RadioModeInfo radioModeInfo1 = new RadioModeInfo();
3675         radioModeInfo1.bandInfo = WifiScanner.WIFI_BAND_24_GHZ;
3676 
3677         IfaceInfo ifaceInfo0 = new IfaceInfo();
3678         ifaceInfo0.name = TEST_IFACE_NAME;
3679         ifaceInfo0.channel = 34;
3680         IfaceInfo ifaceInfo1 = new IfaceInfo();
3681         ifaceInfo1.name = TEST_IFACE_NAME_1;
3682         ifaceInfo1.channel = 1;
3683 
3684         radioModeInfo0.ifaceInfos.add(ifaceInfo0);
3685         radioModeInfo1.ifaceInfos.add(ifaceInfo1);
3686 
3687         ArrayList<RadioModeInfo> radioModeInfos = new ArrayList<>();
3688         radioModeInfos.add(radioModeInfo0);
3689         radioModeInfos.add(radioModeInfo1);
3690 
3691         mIWifiChipEventCallbackV12.onRadioModeChange(radioModeInfos);
3692         mLooper.dispatchAll();
3693         verify(mVendorHalRadioModeChangeHandler).onDbs();
3694 
3695         verifyNoMoreInteractions(mVendorHalRadioModeChangeHandler);
3696     }
3697 
3698     /**
3699      * Verifies radio mode change callback to indicate DBS mode using V1.4 callback.
3700      */
3701     @Test
testRadioModeChangeCallbackToDbsModeV14()3702     public void testRadioModeChangeCallbackToDbsModeV14() throws Exception {
3703         startHalInStaModeAndRegisterRadioModeChangeCallback14();
3704 
3705         android.hardware.wifi.V1_4.IWifiChipEventCallback.RadioModeInfo radioModeInfo0 =
3706                 new android.hardware.wifi.V1_4.IWifiChipEventCallback.RadioModeInfo();
3707         radioModeInfo0.bandInfo = WifiScanner.WIFI_BAND_6_GHZ;
3708         android.hardware.wifi.V1_4.IWifiChipEventCallback.RadioModeInfo radioModeInfo1 =
3709                 new android.hardware.wifi.V1_4.IWifiChipEventCallback.RadioModeInfo();
3710         radioModeInfo1.bandInfo = WifiScanner.WIFI_BAND_24_GHZ;
3711 
3712         IfaceInfo ifaceInfo0 = new IfaceInfo();
3713         ifaceInfo0.name = TEST_IFACE_NAME;
3714         ifaceInfo0.channel = 34;
3715         IfaceInfo ifaceInfo1 = new IfaceInfo();
3716         ifaceInfo1.name = TEST_IFACE_NAME_1;
3717         ifaceInfo1.channel = 1;
3718 
3719         radioModeInfo0.ifaceInfos.add(ifaceInfo0);
3720         radioModeInfo1.ifaceInfos.add(ifaceInfo1);
3721 
3722         ArrayList<android.hardware.wifi.V1_4.IWifiChipEventCallback.RadioModeInfo> radioModeInfos =
3723                 new ArrayList<>();
3724         radioModeInfos.add(radioModeInfo0);
3725         radioModeInfos.add(radioModeInfo1);
3726 
3727         mIWifiChipEventCallbackV14.onRadioModeChange_1_4(radioModeInfos);
3728         mLooper.dispatchAll();
3729         verify(mVendorHalRadioModeChangeHandler).onDbs();
3730 
3731         verifyNoMoreInteractions(mVendorHalRadioModeChangeHandler);
3732     }
3733 
3734     /**
3735      * Verifies radio mode change callback to indicate SBS mode.
3736      */
3737     @Test
testRadioModeChangeCallbackToSbsMode()3738     public void testRadioModeChangeCallbackToSbsMode() throws Exception {
3739         startHalInStaModeAndRegisterRadioModeChangeCallback();
3740 
3741         RadioModeInfo radioModeInfo0 = new RadioModeInfo();
3742         radioModeInfo0.bandInfo = WifiScanner.WIFI_BAND_5_GHZ;
3743         RadioModeInfo radioModeInfo1 = new RadioModeInfo();
3744         radioModeInfo1.bandInfo = WifiScanner.WIFI_BAND_5_GHZ;
3745 
3746         IfaceInfo ifaceInfo0 = new IfaceInfo();
3747         ifaceInfo0.name = TEST_IFACE_NAME;
3748         ifaceInfo0.channel = 34;
3749         IfaceInfo ifaceInfo1 = new IfaceInfo();
3750         ifaceInfo1.name = TEST_IFACE_NAME_1;
3751         ifaceInfo1.channel = 36;
3752 
3753         radioModeInfo0.ifaceInfos.add(ifaceInfo0);
3754         radioModeInfo1.ifaceInfos.add(ifaceInfo1);
3755 
3756         ArrayList<RadioModeInfo> radioModeInfos = new ArrayList<>();
3757         radioModeInfos.add(radioModeInfo0);
3758         radioModeInfos.add(radioModeInfo1);
3759 
3760         mIWifiChipEventCallbackV12.onRadioModeChange(radioModeInfos);
3761         mLooper.dispatchAll();
3762         verify(mVendorHalRadioModeChangeHandler).onSbs(WifiScanner.WIFI_BAND_5_GHZ);
3763 
3764         verifyNoMoreInteractions(mVendorHalRadioModeChangeHandler);
3765     }
3766 
3767     /**
3768      * Verifies radio mode change callback to indicate SCC mode.
3769      */
3770     @Test
testRadioModeChangeCallbackToSccMode()3771     public void testRadioModeChangeCallbackToSccMode() throws Exception {
3772         startHalInStaModeAndRegisterRadioModeChangeCallback();
3773 
3774         RadioModeInfo radioModeInfo0 = new RadioModeInfo();
3775         radioModeInfo0.bandInfo = WifiScanner.WIFI_BAND_5_GHZ;
3776 
3777         IfaceInfo ifaceInfo0 = new IfaceInfo();
3778         ifaceInfo0.name = TEST_IFACE_NAME;
3779         ifaceInfo0.channel = 34;
3780         IfaceInfo ifaceInfo1 = new IfaceInfo();
3781         ifaceInfo1.name = TEST_IFACE_NAME_1;
3782         ifaceInfo1.channel = 34;
3783 
3784         radioModeInfo0.ifaceInfos.add(ifaceInfo0);
3785         radioModeInfo0.ifaceInfos.add(ifaceInfo1);
3786 
3787         ArrayList<RadioModeInfo> radioModeInfos = new ArrayList<>();
3788         radioModeInfos.add(radioModeInfo0);
3789 
3790         mIWifiChipEventCallbackV12.onRadioModeChange(radioModeInfos);
3791         mLooper.dispatchAll();
3792         verify(mVendorHalRadioModeChangeHandler).onScc(WifiScanner.WIFI_BAND_5_GHZ);
3793 
3794         verifyNoMoreInteractions(mVendorHalRadioModeChangeHandler);
3795     }
3796 
3797     /**
3798      * Verifies radio mode change callback to indicate MCC mode.
3799      */
3800     @Test
testRadioModeChangeCallbackToMccMode()3801     public void testRadioModeChangeCallbackToMccMode() throws Exception {
3802         startHalInStaModeAndRegisterRadioModeChangeCallback();
3803 
3804         RadioModeInfo radioModeInfo0 = new RadioModeInfo();
3805         radioModeInfo0.bandInfo = WifiScanner.WIFI_BAND_BOTH;
3806 
3807         IfaceInfo ifaceInfo0 = new IfaceInfo();
3808         ifaceInfo0.name = TEST_IFACE_NAME;
3809         ifaceInfo0.channel = 1;
3810         IfaceInfo ifaceInfo1 = new IfaceInfo();
3811         ifaceInfo1.name = TEST_IFACE_NAME_1;
3812         ifaceInfo1.channel = 36;
3813 
3814         radioModeInfo0.ifaceInfos.add(ifaceInfo0);
3815         radioModeInfo0.ifaceInfos.add(ifaceInfo1);
3816 
3817         ArrayList<RadioModeInfo> radioModeInfos = new ArrayList<>();
3818         radioModeInfos.add(radioModeInfo0);
3819 
3820         mIWifiChipEventCallbackV12.onRadioModeChange(radioModeInfos);
3821         mLooper.dispatchAll();
3822         verify(mVendorHalRadioModeChangeHandler).onMcc(WifiScanner.WIFI_BAND_BOTH);
3823 
3824         verifyNoMoreInteractions(mVendorHalRadioModeChangeHandler);
3825     }
3826 
3827     /**
3828      * Verifies radio mode change callback error cases.
3829      */
3830     @Test
testRadioModeChangeCallbackErrorSimultaneousWithSameIfaceOnBothRadios()3831     public void testRadioModeChangeCallbackErrorSimultaneousWithSameIfaceOnBothRadios()
3832             throws Exception {
3833         startHalInStaModeAndRegisterRadioModeChangeCallback();
3834 
3835         RadioModeInfo radioModeInfo0 = new RadioModeInfo();
3836         radioModeInfo0.bandInfo = WifiScanner.WIFI_BAND_24_GHZ;
3837         RadioModeInfo radioModeInfo1 = new RadioModeInfo();
3838         radioModeInfo1.bandInfo = WifiScanner.WIFI_BAND_5_GHZ;
3839 
3840         IfaceInfo ifaceInfo0 = new IfaceInfo();
3841         ifaceInfo0.name = TEST_IFACE_NAME;
3842         ifaceInfo0.channel = 34;
3843 
3844         radioModeInfo0.ifaceInfos.add(ifaceInfo0);
3845         radioModeInfo1.ifaceInfos.add(ifaceInfo0);
3846 
3847         ArrayList<RadioModeInfo> radioModeInfos = new ArrayList<>();
3848         radioModeInfos.add(radioModeInfo0);
3849         radioModeInfos.add(radioModeInfo1);
3850 
3851         mIWifiChipEventCallbackV12.onRadioModeChange(radioModeInfos);
3852         mLooper.dispatchAll();
3853         // Ignored....
3854 
3855         verifyNoMoreInteractions(mVendorHalRadioModeChangeHandler);
3856     }
3857 
3858     @Test
testIsItPossibleToCreateIface()3859     public void testIsItPossibleToCreateIface() {
3860         when(mHalDeviceManager.isItPossibleToCreateIface(eq(IfaceType.AP), any())).thenReturn(true);
3861         assertTrue(mWifiVendorHal.isItPossibleToCreateApIface(new WorkSource()));
3862 
3863         when(mHalDeviceManager.isItPossibleToCreateIface(eq(IfaceType.STA), any()))
3864                 .thenReturn(true);
3865         assertTrue(mWifiVendorHal.isItPossibleToCreateStaIface(new WorkSource()));
3866     }
3867 
3868     @Test
testIsStaApConcurrencySupported()3869     public void testIsStaApConcurrencySupported() {
3870         when(mHalDeviceManager.canSupportIfaceCombo(
3871                 argThat(ifaceCombo -> ifaceCombo.get(IfaceType.STA) == 1
3872                         && ifaceCombo.get(IfaceType.AP) == 1))).thenReturn(true);
3873         assertTrue(mWifiVendorHal.isStaApConcurrencySupported());
3874     }
3875 
3876     @Test
testIsStaStaConcurrencySupported()3877     public void testIsStaStaConcurrencySupported() {
3878         when(mHalDeviceManager.canSupportIfaceCombo(
3879                 argThat(ifaceCombo -> ifaceCombo.get(IfaceType.STA) == 2))).thenReturn(true);
3880         assertTrue(mWifiVendorHal.isStaStaConcurrencySupported());
3881     }
3882 
3883     @Test
testSetMultiStaPrimaryConnection()3884     public void testSetMultiStaPrimaryConnection() throws Exception {
3885         mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler,
3886                 mWifiGlobals);
3887         when(mIWifiChipV15.setMultiStaPrimaryConnection(any())).thenReturn(mWifiStatusSuccess);
3888         assertTrue(mWifiVendorHal.setMultiStaPrimaryConnection(TEST_IFACE_NAME));
3889         verify(mIWifiChipV15).setMultiStaPrimaryConnection(TEST_IFACE_NAME);
3890     }
3891 
3892     @Test
testSetMultiStaUseCase()3893     public void testSetMultiStaUseCase() throws Exception {
3894         mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler,
3895                 mWifiGlobals);
3896         when(mIWifiChipV15.setMultiStaUseCase(MultiStaUseCase.DUAL_STA_TRANSIENT_PREFER_PRIMARY))
3897                 .thenReturn(mWifiStatusSuccess);
3898         when(mIWifiChipV15.setMultiStaUseCase(MultiStaUseCase.DUAL_STA_NON_TRANSIENT_UNBIASED))
3899                 .thenReturn(mWifiStatusFailure);
3900 
3901         assertTrue(mWifiVendorHal.setMultiStaUseCase(WifiNative.DUAL_STA_TRANSIENT_PREFER_PRIMARY));
3902         verify(mIWifiChipV15).setMultiStaUseCase(MultiStaUseCase.DUAL_STA_TRANSIENT_PREFER_PRIMARY);
3903 
3904         assertFalse(mWifiVendorHal.setMultiStaUseCase(WifiNative.DUAL_STA_NON_TRANSIENT_UNBIASED));
3905         verify(mIWifiChipV15).setMultiStaUseCase(MultiStaUseCase.DUAL_STA_NON_TRANSIENT_UNBIASED);
3906 
3907         // illegal value.
3908         assertFalse(mWifiVendorHal.setMultiStaUseCase(5));
3909     }
3910 
startHalInStaModeAndRegisterRadioModeChangeCallback()3911     private void startHalInStaModeAndRegisterRadioModeChangeCallback() {
3912         // Expose the 1.2 IWifiChip.
3913         mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
3914                 mWifiGlobals);
3915         mWifiVendorHal.registerRadioModeChangeHandler(mVendorHalRadioModeChangeHandler);
3916         assertTrue(mWifiVendorHal.startVendorHalSta());
3917         assertNotNull(mIWifiChipEventCallbackV12);
3918     }
3919 
startHalInStaModeAndRegisterRadioModeChangeCallback14()3920     private void startHalInStaModeAndRegisterRadioModeChangeCallback14() {
3921         // Expose the 1.4 IWifiChip.
3922         mWifiVendorHal = new WifiVendorHalSpyV1_4(mContext, mHalDeviceManager, mHandler,
3923                 mWifiGlobals);
3924         mWifiVendorHal.registerRadioModeChangeHandler(mVendorHalRadioModeChangeHandler);
3925         assertTrue(mWifiVendorHal.startVendorHalSta());
3926         assertNotNull(mIWifiChipEventCallbackV14);
3927     }
3928 
startHalInStaModeAndRegisterRadioModeChangeCallback15()3929     private void startHalInStaModeAndRegisterRadioModeChangeCallback15() {
3930         // Expose the 1.5 IWifiChip.
3931         mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler,
3932                 mWifiGlobals);
3933         mWifiVendorHal.registerRadioModeChangeHandler(mVendorHalRadioModeChangeHandler);
3934         assertTrue(mWifiVendorHal.startVendorHalSta());
3935         assertNotNull(mIWifiChipEventCallbackV14);
3936     }
3937 
testAlertCallbackUsingProvidedCallback(IWifiChipEventCallback chipCallback)3938     private void testAlertCallbackUsingProvidedCallback(IWifiChipEventCallback chipCallback)
3939             throws Exception {
3940         when(mIWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(mWifiStatusSuccess);
3941         when(mIWifiChip.stopLoggingToDebugRingBuffer()).thenReturn(mWifiStatusSuccess);
3942 
3943         int errorCode = 5;
3944         byte[] errorData = new byte[45];
3945         new Random().nextBytes(errorData);
3946 
3947         // Randomly raise the HIDL callback before we register for the log callback.
3948         // This should be safely ignored. (Not trigger NPE.)
3949         chipCallback.onDebugErrorAlert(
3950                 errorCode, NativeUtil.byteArrayToArrayList(errorData));
3951         mLooper.dispatchAll();
3952 
3953         WifiNative.WifiLoggerEventHandler eventHandler =
3954                 mock(WifiNative.WifiLoggerEventHandler.class);
3955         assertTrue(mWifiVendorHal.setLoggingEventHandler(eventHandler));
3956         verify(mIWifiChip).enableDebugErrorAlerts(eq(true));
3957 
3958         // Now raise the HIDL callback, this should be properly handled.
3959         chipCallback.onDebugErrorAlert(
3960                 errorCode, NativeUtil.byteArrayToArrayList(errorData));
3961         mLooper.dispatchAll();
3962         verify(eventHandler).onWifiAlert(eq(errorCode), eq(errorData));
3963 
3964         // Now stop the logging and invoke the callback. This should be ignored.
3965         reset(eventHandler);
3966         assertTrue(mWifiVendorHal.resetLogHandler());
3967         chipCallback.onDebugErrorAlert(
3968                 errorCode, NativeUtil.byteArrayToArrayList(errorData));
3969         mLooper.dispatchAll();
3970         verify(eventHandler, never()).onWifiAlert(anyInt(), anyObject());
3971     }
3972 
startBgScan(WifiNative.ScanEventHandler eventHandler)3973     private void startBgScan(WifiNative.ScanEventHandler eventHandler) throws Exception {
3974         when(mIWifiStaIface.startBackgroundScan(
3975                 anyInt(), any(StaBackgroundScanParameters.class))).thenReturn(mWifiStatusSuccess);
3976         WifiNative.ScanSettings settings = new WifiNative.ScanSettings();
3977         settings.num_buckets = 1;
3978         WifiNative.BucketSettings bucketSettings = new WifiNative.BucketSettings();
3979         bucketSettings.bucket = 0;
3980         bucketSettings.period_ms = 16000;
3981         bucketSettings.report_events = WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN;
3982         settings.buckets = new WifiNative.BucketSettings[] {bucketSettings};
3983         assertTrue(mWifiVendorHal.startBgScan(TEST_IFACE_NAME, settings, eventHandler));
3984     }
3985 
3986     // Create a pair of HIDL scan result and its corresponding framework scan result for
3987     // comparison.
createHidlAndFrameworkBgScanResult()3988     private Pair<StaScanResult, ScanResult> createHidlAndFrameworkBgScanResult() {
3989         StaScanResult staScanResult = new StaScanResult();
3990         Random random = new Random();
3991         byte[] ssid = new byte[8];
3992         random.nextBytes(ssid);
3993         staScanResult.ssid.addAll(NativeUtil.byteArrayToArrayList(ssid));
3994         random.nextBytes(staScanResult.bssid);
3995         staScanResult.frequency = 2432;
3996         staScanResult.rssi = -45;
3997         staScanResult.timeStampInUs = 5;
3998         WifiInformationElement ie1 = new WifiInformationElement();
3999         byte[] ie1_data = new byte[56];
4000         random.nextBytes(ie1_data);
4001         ie1.id = 1;
4002         ie1.data.addAll(NativeUtil.byteArrayToArrayList(ie1_data));
4003         staScanResult.informationElements.add(ie1);
4004 
4005         // Now create the corresponding Scan result structure.
4006         ScanResult scanResult = new ScanResult();
4007         scanResult.SSID = NativeUtil.encodeSsid(staScanResult.ssid);
4008         scanResult.BSSID = NativeUtil.macAddressFromByteArray(staScanResult.bssid);
4009         scanResult.wifiSsid = WifiSsid.createFromByteArray(ssid);
4010         scanResult.frequency = staScanResult.frequency;
4011         scanResult.level = staScanResult.rssi;
4012         scanResult.timestamp = staScanResult.timeStampInUs;
4013 
4014         return Pair.create(staScanResult, scanResult);
4015     }
4016 
4017     // Create a pair of HIDL scan datas and its corresponding framework scan datas for
4018     // comparison.
4019     private Pair<ArrayList<StaScanData>, ArrayList<WifiScanner.ScanData>>
createHidlAndFrameworkBgScanDatas()4020             createHidlAndFrameworkBgScanDatas() {
4021         ArrayList<StaScanData> staScanDatas = new ArrayList<>();
4022         StaScanData staScanData = new StaScanData();
4023 
4024         Pair<StaScanResult, ScanResult> result = createHidlAndFrameworkBgScanResult();
4025         staScanData.results.add(result.first);
4026         staScanData.bucketsScanned = 5;
4027         staScanData.flags = StaScanDataFlagMask.INTERRUPTED;
4028         staScanDatas.add(staScanData);
4029 
4030         ArrayList<WifiScanner.ScanData> scanDatas = new ArrayList<>();
4031         ScanResult[] scanResults = new ScanResult[1];
4032         scanResults[0] = result.second;
4033         WifiScanner.ScanData scanData =
4034                 new WifiScanner.ScanData(mWifiVendorHal.mScan.cmdId, 1,
4035                         staScanData.bucketsScanned, WifiScanner.WIFI_BAND_UNSPECIFIED, scanResults);
4036         scanDatas.add(scanData);
4037         return Pair.create(staScanDatas, scanDatas);
4038     }
4039 
assertScanResultEqual(ScanResult expected, ScanResult actual)4040     private void assertScanResultEqual(ScanResult expected, ScanResult actual) {
4041         assertEquals(expected.SSID, actual.SSID);
4042         assertEquals(expected.wifiSsid.getHexString(), actual.wifiSsid.getHexString());
4043         assertEquals(expected.BSSID, actual.BSSID);
4044         assertEquals(expected.frequency, actual.frequency);
4045         assertEquals(expected.level, actual.level);
4046         assertEquals(expected.timestamp, actual.timestamp);
4047     }
4048 
assertScanResultsEqual(ScanResult[] expected, ScanResult[] actual)4049     private void assertScanResultsEqual(ScanResult[] expected, ScanResult[] actual) {
4050         assertEquals(expected.length, actual.length);
4051         for (int i = 0; i < expected.length; i++) {
4052             assertScanResultEqual(expected[i], actual[i]);
4053         }
4054     }
4055 
assertScanDataEqual(WifiScanner.ScanData expected, WifiScanner.ScanData actual)4056     private void assertScanDataEqual(WifiScanner.ScanData expected, WifiScanner.ScanData actual) {
4057         assertEquals(expected.getId(), actual.getId());
4058         assertEquals(expected.getFlags(), actual.getFlags());
4059         assertEquals(expected.getBucketsScanned(), actual.getBucketsScanned());
4060         assertScanResultsEqual(expected.getResults(), actual.getResults());
4061     }
4062 
assertScanDatasEqual( List<WifiScanner.ScanData> expected, List<WifiScanner.ScanData> actual)4063     private void assertScanDatasEqual(
4064             List<WifiScanner.ScanData> expected, List<WifiScanner.ScanData> actual) {
4065         assertEquals(expected.size(), actual.size());
4066         for (int i = 0; i < expected.size(); i++) {
4067             assertScanDataEqual(expected.get(i), actual.get(i));
4068         }
4069     }
4070 
4071     /**
4072      * Test setCountryCode gets called when the hal version is V1_5.
4073      */
4074     @Test
testSetCountryCodeWithHalV1_5()4075     public void testSetCountryCodeWithHalV1_5() throws Exception {
4076         byte[] expected = new byte[]{(byte) 'U', (byte) 'S'};
4077         mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler,
4078                 mWifiGlobals);
4079         when(mIWifiChipV15.setCountryCode(any())).thenReturn(mWifiStatusSuccess);
4080 
4081         // Invalid cases
4082         assertFalse(mWifiVendorHal.setChipCountryCode(null));
4083         assertFalse(mWifiVendorHal.setChipCountryCode(""));
4084         assertFalse(mWifiVendorHal.setChipCountryCode("A"));
4085         verify(mIWifiChipV15, never()).setCountryCode(any());
4086 
4087         //valid country code
4088         assertTrue(mWifiVendorHal.setChipCountryCode("US"));
4089         verify(mIWifiChipV15).setCountryCode(eq(expected));
4090     }
4091 
4092     @Test
testSetScanMode()4093     public void testSetScanMode() throws Exception {
4094         mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler,
4095                 mWifiGlobals);
4096         when(mIWifiStaIfaceV15.setScanMode(anyBoolean())).thenReturn(mWifiStatusSuccess);
4097 
4098         assertTrue(mWifiVendorHal.setScanMode(TEST_IFACE_NAME, true));
4099         verify(mIWifiStaIfaceV15).setScanMode(true);
4100 
4101         assertTrue(mWifiVendorHal.setScanMode(TEST_IFACE_NAME, false));
4102         verify(mIWifiStaIfaceV15).setScanMode(false);
4103     }
4104 
4105     @Test
testGetUsableChannels()4106     public void testGetUsableChannels() throws Exception {
4107         assertTrue(mWifiVendorHal.startVendorHalSta());
4108         mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler,
4109                 mWifiGlobals);
4110         ArrayList<WifiUsableChannel> channels = new ArrayList<>();
4111         doAnswer(new AnswerWithArguments() {
4112             public void answer(int band, int mode, int filter,
4113                     android.hardware.wifi.V1_5.IWifiChip.getUsableChannelsCallback cb)
4114                     throws RemoteException {
4115                 cb.onValues(mWifiStatusSuccess, channels);
4116             }
4117         }).when(mIWifiChipV15).getUsableChannels(anyInt(), anyInt(), anyInt(),
4118                 any(android.hardware.wifi.V1_5.IWifiChip.getUsableChannelsCallback.class));
4119         mWifiVendorHal.getUsableChannels(
4120                 WifiScanner.WIFI_BAND_24_GHZ,
4121                 WifiAvailableChannel.OP_MODE_WIFI_DIRECT_CLI,
4122                 WifiAvailableChannel.FILTER_CELLULAR_COEXISTENCE);
4123         verify(mIWifiChipV15).getUsableChannels(anyInt(), anyInt(), anyInt(),
4124                 any(android.hardware.wifi.V1_5.IWifiChip.getUsableChannelsCallback.class));
4125     }
4126 }
4127