• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.wifi;
18 import android.app.test.MockAnswerUtil.AnswerWithArguments;
19 import android.hardware.wifi.V1_0.IWifiApIface;
20 import android.hardware.wifi.V1_0.IWifiChip;
21 import android.hardware.wifi.V1_0.IWifiChipEventCallback;
22 import android.hardware.wifi.V1_0.IWifiIface;
23 import android.hardware.wifi.V1_0.IWifiRttController;
24 import android.hardware.wifi.V1_0.IWifiRttControllerEventCallback;
25 import android.hardware.wifi.V1_0.IWifiStaIface;
26 import android.hardware.wifi.V1_0.IWifiStaIfaceEventCallback;
27 import android.hardware.wifi.V1_0.IfaceType;
28 import android.hardware.wifi.V1_0.RttCapabilities;
29 import android.hardware.wifi.V1_0.RttConfig;
30 import android.hardware.wifi.V1_0.StaApfPacketFilterCapabilities;
31 import android.hardware.wifi.V1_0.StaBackgroundScanCapabilities;
32 import android.hardware.wifi.V1_0.StaBackgroundScanParameters;
33 import android.hardware.wifi.V1_0.StaLinkLayerIfacePacketStats;
34 import android.hardware.wifi.V1_0.StaLinkLayerRadioStats;
35 import android.hardware.wifi.V1_0.StaLinkLayerStats;
36 import android.hardware.wifi.V1_0.StaScanData;
37 import android.hardware.wifi.V1_0.StaScanDataFlagMask;
38 import android.hardware.wifi.V1_0.StaScanResult;
39 import android.hardware.wifi.V1_0.WifiDebugHostWakeReasonStats;
40 import android.hardware.wifi.V1_0.WifiDebugPacketFateFrameType;
41 import android.hardware.wifi.V1_0.WifiDebugRingBufferFlags;
42 import android.hardware.wifi.V1_0.WifiDebugRingBufferStatus;
43 import android.hardware.wifi.V1_0.WifiDebugRingBufferVerboseLevel;
44 import android.hardware.wifi.V1_0.WifiDebugRxPacketFate;
45 import android.hardware.wifi.V1_0.WifiDebugRxPacketFateReport;
46 import android.hardware.wifi.V1_0.WifiDebugTxPacketFate;
47 import android.hardware.wifi.V1_0.WifiDebugTxPacketFateReport;
48 import android.hardware.wifi.V1_0.WifiInformationElement;
49 import android.hardware.wifi.V1_0.WifiStatus;
50 import android.hardware.wifi.V1_0.WifiStatusCode;
51 import android.net.apf.ApfCapabilities;
52 import android.net.wifi.RttManager;
53 import android.net.wifi.ScanResult;
54 import android.net.wifi.WifiLinkLayerStats;
55 import android.net.wifi.WifiManager;
56 import android.net.wifi.WifiScanner;
57 import android.net.wifi.WifiSsid;
58 import android.net.wifi.WifiWakeReasonAndCounts;
59 import android.os.Looper;
60 import android.os.RemoteException;
61 import android.os.test.TestLooper;
62 import android.util.Pair;
63 
64 import com.android.server.connectivity.KeepalivePacketData;
65 import com.android.server.wifi.util.NativeUtil;
66 
67 import static org.junit.Assert.*;
68 import static org.mockito.Mockito.*;
69 
70 import org.junit.Before;
71 import org.junit.Test;
72 import org.mockito.ArgumentCaptor;
73 import org.mockito.Mock;
74 import org.mockito.MockitoAnnotations;
75 import org.mockito.stubbing.Answer;
76 
77 import java.net.InetAddress;
78 import java.util.ArrayList;
79 import java.util.Arrays;
80 import java.util.HashSet;
81 import java.util.List;
82 import java.util.Random;
83 import java.util.Set;
84 
85 /**
86  * Unit tests for {@link com.android.server.wifi.WifiVendorHal}.
87  */
88 public class WifiVendorHalTest {
89 
90     WifiVendorHal mWifiVendorHal;
91     private WifiStatus mWifiStatusSuccess;
92     private WifiStatus mWifiStatusFailure;
93     WifiLog mWifiLog;
94     @Mock
95     private HalDeviceManager mHalDeviceManager;
96     @Mock
97     private TestLooper mLooper;
98     @Mock
99     private WifiVendorHal.HalDeviceManagerStatusListener mHalDeviceManagerStatusCallbacks;
100     @Mock
101     private IWifiApIface mIWifiApIface;
102     @Mock
103     private IWifiChip mIWifiChip;
104     @Mock
105     private android.hardware.wifi.V1_1.IWifiChip mIWifiChipV11;
106     @Mock
107     private IWifiStaIface mIWifiStaIface;
108     @Mock
109     private IWifiRttController mIWifiRttController;
110     private IWifiStaIfaceEventCallback mIWifiStaIfaceEventCallback;
111     private IWifiChipEventCallback mIWifiChipEventCallback;
112     @Mock
113     private WifiNative.VendorHalDeathEventHandler mVendorHalDeathHandler;
114 
115     /**
116      * Spy used to return the V1_1 IWifiChip mock object to simulate the 1.1 HAL running on the
117      * device.
118      */
119     private class WifiVendorHalSpyV1_1 extends WifiVendorHal {
WifiVendorHalSpyV1_1(HalDeviceManager halDeviceManager, Looper looper)120         WifiVendorHalSpyV1_1(HalDeviceManager halDeviceManager, Looper looper) {
121             super(halDeviceManager, looper);
122         }
123 
124         @Override
getWifiChipForV1_1Mockable()125         protected android.hardware.wifi.V1_1.IWifiChip getWifiChipForV1_1Mockable() {
126             return mIWifiChipV11;
127         }
128     }
129 
130     /**
131      * Identity function to supply a type to its argument, which is a lambda
132      */
answerWifiStatus(Answer<WifiStatus> statusLambda)133     static Answer<WifiStatus> answerWifiStatus(Answer<WifiStatus> statusLambda) {
134         return (statusLambda);
135     }
136 
137     /**
138      * Sets up for unit test
139      */
140     @Before
setUp()141     public void setUp() throws Exception {
142         MockitoAnnotations.initMocks(this);
143         mWifiLog = new FakeWifiLog();
144         mLooper = new TestLooper();
145         mWifiStatusSuccess = new WifiStatus();
146         mWifiStatusSuccess.code = WifiStatusCode.SUCCESS;
147         mWifiStatusFailure = new WifiStatus();
148         mWifiStatusFailure.code = WifiStatusCode.ERROR_UNKNOWN;
149         mWifiStatusFailure.description = "I don't even know what a Mock Turtle is.";
150         when(mIWifiStaIface.enableLinkLayerStatsCollection(false)).thenReturn(mWifiStatusSuccess);
151 
152         // Setup the HalDeviceManager mock's start/stop behaviour. This can be overridden in
153         // individual tests, if needed.
154         doAnswer(new AnswerWithArguments() {
155             public boolean answer() {
156                 when(mHalDeviceManager.isReady()).thenReturn(true);
157                 when(mHalDeviceManager.isStarted()).thenReturn(true);
158                 mHalDeviceManagerStatusCallbacks.onStatusChanged();
159                 return true;
160             }
161         }).when(mHalDeviceManager).start();
162 
163         doAnswer(new AnswerWithArguments() {
164             public void answer() {
165                 when(mHalDeviceManager.isReady()).thenReturn(true);
166                 when(mHalDeviceManager.isStarted()).thenReturn(false);
167                 mHalDeviceManagerStatusCallbacks.onStatusChanged();
168             }
169         }).when(mHalDeviceManager).stop();
170         when(mHalDeviceManager.createStaIface(eq(null), eq(null)))
171                 .thenReturn(mIWifiStaIface);
172         when(mHalDeviceManager.createApIface(eq(null), eq(null)))
173                 .thenReturn(mIWifiApIface);
174         when(mHalDeviceManager.getChip(any(IWifiIface.class)))
175                 .thenReturn(mIWifiChip);
176         when(mHalDeviceManager.createRttController(any(IWifiIface.class)))
177                 .thenReturn(mIWifiRttController);
178         when(mIWifiChip.registerEventCallback(any(IWifiChipEventCallback.class)))
179                 .thenReturn(mWifiStatusSuccess);
180         mIWifiStaIfaceEventCallback = null;
181         when(mIWifiStaIface.registerEventCallback(any(IWifiStaIfaceEventCallback.class)))
182                 .thenAnswer(answerWifiStatus((invocation) -> {
183                     Object[] args = invocation.getArguments();
184                     mIWifiStaIfaceEventCallback = (IWifiStaIfaceEventCallback) args[0];
185                     return (mWifiStatusSuccess);
186                 }));
187         mIWifiChipEventCallback = null;
188         when(mIWifiChip.registerEventCallback(any(IWifiChipEventCallback.class)))
189                 .thenAnswer(answerWifiStatus((invocation) -> {
190                     Object[] args = invocation.getArguments();
191                     mIWifiChipEventCallback = (IWifiChipEventCallback) args[0];
192                     return (mWifiStatusSuccess);
193                 }));
194 
195         when(mIWifiRttController.registerEventCallback(any(IWifiRttControllerEventCallback.class)))
196                 .thenReturn(mWifiStatusSuccess);
197 
198         // Create the vendor HAL object under test.
199         mWifiVendorHal = new WifiVendorHal(mHalDeviceManager, mLooper.getLooper());
200 
201         // Initialize the vendor HAL to capture the registered callback.
202         mWifiVendorHal.initialize(mVendorHalDeathHandler);
203         ArgumentCaptor<WifiVendorHal.HalDeviceManagerStatusListener> hdmCallbackCaptor =
204                 ArgumentCaptor.forClass(WifiVendorHal.HalDeviceManagerStatusListener.class);
205         verify(mHalDeviceManager).registerStatusListener(hdmCallbackCaptor.capture(), any());
206         mHalDeviceManagerStatusCallbacks = hdmCallbackCaptor.getValue();
207 
208     }
209 
210     /**
211      * Tests the successful starting of HAL in STA mode using
212      * {@link WifiVendorHal#startVendorHal(boolean)}.
213      */
214     @Test
testStartHalSuccessInStaMode()215     public void testStartHalSuccessInStaMode() throws  Exception {
216         assertTrue(mWifiVendorHal.startVendorHal(true));
217         assertTrue(mWifiVendorHal.isHalStarted());
218 
219         verify(mHalDeviceManager).start();
220         verify(mHalDeviceManager).createStaIface(eq(null), eq(null));
221         verify(mHalDeviceManager).getChip(eq(mIWifiStaIface));
222         verify(mHalDeviceManager).createRttController(eq(mIWifiStaIface));
223         verify(mHalDeviceManager).isReady();
224         verify(mHalDeviceManager).isStarted();
225         verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class));
226         verify(mIWifiChip).registerEventCallback(any(IWifiChipEventCallback.class));
227 
228         verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null));
229     }
230 
231     /**
232      * Tests the successful starting of HAL in AP mode using
233      * {@link WifiVendorHal#startVendorHal(boolean)}.
234      */
235     @Test
testStartHalSuccessInApMode()236     public void testStartHalSuccessInApMode() throws Exception {
237         assertTrue(mWifiVendorHal.startVendorHal(false));
238         assertTrue(mWifiVendorHal.isHalStarted());
239 
240         verify(mHalDeviceManager).start();
241         verify(mHalDeviceManager).createApIface(eq(null), eq(null));
242         verify(mHalDeviceManager).getChip(eq(mIWifiApIface));
243         verify(mHalDeviceManager).isReady();
244         verify(mHalDeviceManager).isStarted();
245 
246         verify(mHalDeviceManager, never()).createStaIface(eq(null), eq(null));
247         verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class));
248     }
249 
250     /**
251      * Tests the failure to start HAL in STA mode using
252      * {@link WifiVendorHal#startVendorHal(boolean)}.
253      */
254     @Test
testStartHalFailureInStaMode()255     public void testStartHalFailureInStaMode() throws Exception {
256         // No callbacks are invoked in this case since the start itself failed. So, override
257         // default AnswerWithArguments that we setup.
258         doAnswer(new AnswerWithArguments() {
259             public boolean answer() throws Exception {
260                 return false;
261             }
262         }).when(mHalDeviceManager).start();
263         assertFalse(mWifiVendorHal.startVendorHal(true));
264         assertFalse(mWifiVendorHal.isHalStarted());
265 
266         verify(mHalDeviceManager).start();
267 
268         verify(mHalDeviceManager, never()).createStaIface(eq(null), eq(null));
269         verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null));
270         verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
271         verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class));
272         verify(mIWifiStaIface, never())
273                 .registerEventCallback(any(IWifiStaIfaceEventCallback.class));
274     }
275 
276     /**
277      * Tests the failure to start HAL in STA mode using
278      * {@link WifiVendorHal#startVendorHal(boolean)}.
279      */
280     @Test
testStartHalFailureInIfaceCreationInStaMode()281     public void testStartHalFailureInIfaceCreationInStaMode() throws Exception {
282         when(mHalDeviceManager.createStaIface(eq(null), eq(null))).thenReturn(null);
283         assertFalse(mWifiVendorHal.startVendorHal(true));
284         assertFalse(mWifiVendorHal.isHalStarted());
285 
286         verify(mHalDeviceManager).start();
287         verify(mHalDeviceManager).createStaIface(eq(null), eq(null));
288         verify(mHalDeviceManager).stop();
289 
290         verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null));
291         verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
292         verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class));
293         verify(mIWifiStaIface, never())
294                 .registerEventCallback(any(IWifiStaIfaceEventCallback.class));
295     }
296 
297     /**
298      * Tests the failure to start HAL in STA mode using
299      * {@link WifiVendorHal#startVendorHal(boolean)}.
300      */
301     @Test
testStartHalFailureInRttControllerCreationInStaMode()302     public void testStartHalFailureInRttControllerCreationInStaMode() throws Exception {
303         when(mHalDeviceManager.createRttController(any(IWifiIface.class))).thenReturn(null);
304         assertFalse(mWifiVendorHal.startVendorHal(true));
305         assertFalse(mWifiVendorHal.isHalStarted());
306 
307         verify(mHalDeviceManager).start();
308         verify(mHalDeviceManager).createStaIface(eq(null), eq(null));
309         verify(mHalDeviceManager).createRttController(eq(mIWifiStaIface));
310         verify(mHalDeviceManager).stop();
311         verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class));
312 
313         verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null));
314         verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
315     }
316 
317     /**
318      * Tests the failure to start HAL in STA mode using
319      * {@link WifiVendorHal#startVendorHal(boolean)}.
320      */
321     @Test
testStartHalFailureInChipGetInStaMode()322     public void testStartHalFailureInChipGetInStaMode() throws Exception {
323         when(mHalDeviceManager.getChip(any(IWifiIface.class))).thenReturn(null);
324         assertFalse(mWifiVendorHal.startVendorHal(true));
325         assertFalse(mWifiVendorHal.isHalStarted());
326 
327         verify(mHalDeviceManager).start();
328         verify(mHalDeviceManager).createStaIface(eq(null), eq(null));
329         verify(mHalDeviceManager).createRttController(eq(mIWifiStaIface));
330         verify(mHalDeviceManager).getChip(any(IWifiIface.class));
331         verify(mHalDeviceManager).stop();
332         verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class));
333 
334         verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null));
335     }
336 
337     /**
338      * Tests the failure to start HAL in STA mode using
339      * {@link WifiVendorHal#startVendorHal(boolean)}.
340      */
341     @Test
testStartHalFailureInStaIfaceCallbackRegistration()342     public void testStartHalFailureInStaIfaceCallbackRegistration() throws Exception {
343         when(mIWifiStaIface.registerEventCallback(any(IWifiStaIfaceEventCallback.class)))
344                 .thenReturn(mWifiStatusFailure);
345         assertFalse(mWifiVendorHal.startVendorHal(true));
346         assertFalse(mWifiVendorHal.isHalStarted());
347 
348         verify(mHalDeviceManager).start();
349         verify(mHalDeviceManager).createStaIface(eq(null), eq(null));
350         verify(mHalDeviceManager).stop();
351         verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class));
352 
353         verify(mHalDeviceManager, never()).createRttController(eq(mIWifiStaIface));
354         verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
355         verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null));
356     }
357 
358     /**
359      * Tests the failure to start HAL in STA mode using
360      * {@link WifiVendorHal#startVendorHal(boolean)}.
361      */
362     @Test
testStartHalFailureInChipCallbackRegistration()363     public void testStartHalFailureInChipCallbackRegistration() throws Exception {
364         when(mIWifiChip.registerEventCallback(any(IWifiChipEventCallback.class)))
365                 .thenReturn(mWifiStatusFailure);
366         assertFalse(mWifiVendorHal.startVendorHal(true));
367         assertFalse(mWifiVendorHal.isHalStarted());
368 
369         verify(mHalDeviceManager).start();
370         verify(mHalDeviceManager).createStaIface(eq(null), eq(null));
371         verify(mHalDeviceManager).createRttController(eq(mIWifiStaIface));
372         verify(mHalDeviceManager).getChip(any(IWifiIface.class));
373         verify(mHalDeviceManager).stop();
374         verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class));
375         verify(mIWifiChip).registerEventCallback(any(IWifiChipEventCallback.class));
376 
377         verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null));
378     }
379 
380     /**
381      * Tests the failure to start HAL in STA mode using
382      * {@link WifiVendorHal#startVendorHal(boolean)}.
383      */
384     @Test
testStartHalFailureInApMode()385     public void testStartHalFailureInApMode() throws Exception {
386         when(mHalDeviceManager.createApIface(eq(null), eq(null))).thenReturn(null);
387         assertFalse(mWifiVendorHal.startVendorHal(false));
388         assertFalse(mWifiVendorHal.isHalStarted());
389 
390         verify(mHalDeviceManager).start();
391         verify(mHalDeviceManager).createApIface(eq(null), eq(null));
392         verify(mHalDeviceManager).stop();
393 
394         verify(mHalDeviceManager, never()).createStaIface(eq(null), eq(null));
395         verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
396         verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class));
397     }
398 
399     /**
400      * Tests the stopping of HAL in STA mode using
401      * {@link WifiVendorHal#stopVendorHal()}.
402      */
403     @Test
testStopHalInStaMode()404     public void testStopHalInStaMode() {
405         assertTrue(mWifiVendorHal.startVendorHal(true));
406         assertTrue(mWifiVendorHal.isHalStarted());
407 
408         mWifiVendorHal.stopVendorHal();
409         assertFalse(mWifiVendorHal.isHalStarted());
410 
411         verify(mHalDeviceManager).start();
412         verify(mHalDeviceManager).stop();
413         verify(mHalDeviceManager).createStaIface(eq(null), eq(null));
414         verify(mHalDeviceManager).getChip(eq(mIWifiStaIface));
415         verify(mHalDeviceManager).createRttController(eq(mIWifiStaIface));
416         verify(mHalDeviceManager, times(2)).isReady();
417         verify(mHalDeviceManager, times(2)).isStarted();
418 
419         verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null));
420     }
421 
422     /**
423      * Tests the stopping of HAL in AP mode using
424      * {@link WifiVendorHal#stopVendorHal()}.
425      */
426     @Test
testStopHalInApMode()427     public void testStopHalInApMode() {
428         assertTrue(mWifiVendorHal.startVendorHal(false));
429         assertTrue(mWifiVendorHal.isHalStarted());
430 
431         mWifiVendorHal.stopVendorHal();
432         assertFalse(mWifiVendorHal.isHalStarted());
433 
434         verify(mHalDeviceManager).start();
435         verify(mHalDeviceManager).stop();
436         verify(mHalDeviceManager).createApIface(eq(null), eq(null));
437         verify(mHalDeviceManager).getChip(eq(mIWifiApIface));
438         verify(mHalDeviceManager, times(2)).isReady();
439         verify(mHalDeviceManager, times(2)).isStarted();
440 
441         verify(mHalDeviceManager, never()).createStaIface(eq(null), eq(null));
442         verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class));
443     }
444 
445     /**
446      * Test that enter logs when verbose logging is enabled
447      */
448     @Test
testEnterLogging()449     public void testEnterLogging() {
450         mWifiVendorHal.mLog = spy(mWifiLog);
451         mWifiVendorHal.enableVerboseLogging(true);
452         mWifiVendorHal.installPacketFilter(new byte[0]);
453         verify(mWifiVendorHal.mLog).trace(eq("% filter length %"));
454     }
455 
456     /**
457      * Test that enter does not log when verbose logging is not enabled
458      */
459     @Test
testEnterSilenceWhenNotEnabled()460     public void testEnterSilenceWhenNotEnabled() {
461         mWifiVendorHal.mLog = spy(mWifiLog);
462         mWifiVendorHal.installPacketFilter(new byte[0]);
463         mWifiVendorHal.enableVerboseLogging(true);
464         mWifiVendorHal.enableVerboseLogging(false);
465         mWifiVendorHal.installPacketFilter(new byte[0]);
466         verify(mWifiVendorHal.mLog, never()).trace(eq("% filter length %"));
467     }
468 
469     /**
470      * Test that boolResult logs a false result
471      */
472     @Test
testBoolResultFalse()473     public void testBoolResultFalse() {
474         mWifiLog = spy(mWifiLog);
475         mWifiVendorHal.mLog = mWifiLog;
476         mWifiVendorHal.mVerboseLog = mWifiLog;
477         assertFalse(mWifiVendorHal.getBgScanCapabilities(new WifiNative.ScanCapabilities()));
478         verify(mWifiLog).err("% returns %");
479     }
480 
481     /**
482      * Test that getBgScanCapabilities is hooked up to the HAL correctly
483      *
484      * A call before the vendor HAL is started should return a non-null result with version 0
485      *
486      * A call after the HAL is started should return the mocked values.
487      */
488     @Test
testGetBgScanCapabilities()489     public void testGetBgScanCapabilities() throws Exception {
490         StaBackgroundScanCapabilities capabilities = new StaBackgroundScanCapabilities();
491         capabilities.maxCacheSize = 12;
492         capabilities.maxBuckets = 34;
493         capabilities.maxApCachePerScan = 56;
494         capabilities.maxReportingThreshold = 78;
495 
496         doAnswer(new AnswerWithArguments() {
497             public void answer(IWifiStaIface.getBackgroundScanCapabilitiesCallback cb)
498                     throws RemoteException {
499                 cb.onValues(mWifiStatusSuccess, capabilities);
500             }
501         }).when(mIWifiStaIface).getBackgroundScanCapabilities(any(
502                 IWifiStaIface.getBackgroundScanCapabilitiesCallback.class));
503 
504         WifiNative.ScanCapabilities result = new WifiNative.ScanCapabilities();
505 
506         assertFalse(mWifiVendorHal.getBgScanCapabilities(result));  // should fail - not started
507         assertTrue(mWifiVendorHal.startVendorHalSta());           // Start the vendor hal
508         assertTrue(mWifiVendorHal.getBgScanCapabilities(result));   // should succeed
509 
510         assertEquals(12, result.max_scan_cache_size);
511         assertEquals(34, result.max_scan_buckets);
512         assertEquals(56, result.max_ap_cache_per_scan);
513         assertEquals(78, result.max_scan_reporting_threshold);
514     }
515 
setupValidFrequenciesForBand(ArrayList<Integer> frequencies)516     private void setupValidFrequenciesForBand(ArrayList<Integer> frequencies) throws Exception {
517 
518         doAnswer(new AnswerWithArguments() {
519             public void answer(int band, IWifiStaIface.getValidFrequenciesForBandCallback cb)
520                     throws RemoteException {
521                 cb.onValues(mWifiStatusSuccess, frequencies);
522             }
523         }).when(mIWifiStaIface).getValidFrequenciesForBand(anyInt(), any(
524                 IWifiStaIface.getValidFrequenciesForBandCallback.class));
525 
526         doAnswer(new AnswerWithArguments() {
527             public void answer(int band, IWifiApIface.getValidFrequenciesForBandCallback cb)
528                     throws RemoteException {
529                 cb.onValues(mWifiStatusSuccess, frequencies);
530             }
531         }).when(mIWifiApIface).getValidFrequenciesForBand(anyInt(), any(
532                 IWifiApIface.getValidFrequenciesForBandCallback.class));
533 
534     }
535 
intArrayFromArrayList(ArrayList<Integer> in)536     private int[] intArrayFromArrayList(ArrayList<Integer> in) {
537         int[] ans = new int[in.size()];
538         int i = 0;
539         for (Integer e : in) ans[i++] = e;
540         return ans;
541     }
542 
543     /**
544      * Test that isGetChannelsForBandSupported works in STA mode
545      */
546     @Test
testGetChannelsForBandSupportedSta()547     public void testGetChannelsForBandSupportedSta() throws Exception {
548         ArrayList<Integer> freq = new ArrayList<>();
549         freq.add(2405);
550 
551         setupValidFrequenciesForBand(freq);
552 
553         assertFalse(mWifiVendorHal.isGetChannelsForBandSupported());
554 
555         assertTrue(mWifiVendorHal.startVendorHalSta());
556 
557         assertTrue(mWifiVendorHal.isGetChannelsForBandSupported());
558     }
559 
560     /**
561      * Test that isGetChannelsForBandSupported works in AP mode
562      */
563     @Test
testGetChannelsForBandSupportedAp()564     public void testGetChannelsForBandSupportedAp() throws Exception {
565         ArrayList<Integer> freq = new ArrayList<>();
566         freq.add(2405);
567 
568         setupValidFrequenciesForBand(freq);
569 
570         assertFalse(mWifiVendorHal.isGetChannelsForBandSupported());
571 
572         assertTrue(mWifiVendorHal.startVendorHalAp());
573 
574         assertTrue(mWifiVendorHal.isGetChannelsForBandSupported());
575     }
576 
577     /**
578      * Test translation to WifiManager.WIFI_FEATURE_*
579      *
580      * Just do a spot-check with a few feature bits here; since the code is table-
581      * driven we don't have to work hard to exercise all of it.
582      */
583     @Test
testStaIfaceFeatureMaskTranslation()584     public void testStaIfaceFeatureMaskTranslation() {
585         int caps = (
586                 IWifiStaIface.StaIfaceCapabilityMask.BACKGROUND_SCAN
587                 | IWifiStaIface.StaIfaceCapabilityMask.LINK_LAYER_STATS
588             );
589         int expected = (
590                 WifiManager.WIFI_FEATURE_SCANNER
591                 | WifiManager.WIFI_FEATURE_LINK_LAYER_STATS);
592         assertEquals(expected, mWifiVendorHal.wifiFeatureMaskFromStaCapabilities(caps));
593     }
594 
595     /**
596      * Test translation to WifiManager.WIFI_FEATURE_*
597      *
598      * Just do a spot-check with a few feature bits here; since the code is table-
599      * driven we don't have to work hard to exercise all of it.
600      */
601     @Test
testChipFeatureMaskTranslation()602     public void testChipFeatureMaskTranslation() {
603         int caps = (
604                 android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.SET_TX_POWER_LIMIT
605                         | android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.D2D_RTT
606                         | android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.D2AP_RTT
607         );
608         int expected = (
609                 WifiManager.WIFI_FEATURE_TX_POWER_LIMIT
610                         | WifiManager.WIFI_FEATURE_D2D_RTT
611                         | WifiManager.WIFI_FEATURE_D2AP_RTT
612         );
613         assertEquals(expected, mWifiVendorHal.wifiFeatureMaskFromChipCapabilities(caps));
614     }
615 
616     /**
617      * Test get supported features. Tests whether we coalesce information from different sources
618      * (IWifiStaIface, IWifiChip and HalDeviceManager) into the bitmask of supported features
619      * correctly.
620      */
621     @Test
testGetSupportedFeatures()622     public void testGetSupportedFeatures() throws Exception {
623         assertTrue(mWifiVendorHal.startVendorHal(true));
624 
625         int staIfaceHidlCaps = (
626                 IWifiStaIface.StaIfaceCapabilityMask.BACKGROUND_SCAN
627                         | IWifiStaIface.StaIfaceCapabilityMask.LINK_LAYER_STATS
628         );
629         int chipHidlCaps =
630                 android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.SET_TX_POWER_LIMIT;
631         Set<Integer>  halDeviceManagerSupportedIfaces = new HashSet<Integer>() {{
632                 add(IfaceType.STA);
633                 add(IfaceType.P2P);
634             }};
635         int expectedFeatureSet = (
636                 WifiManager.WIFI_FEATURE_SCANNER
637                         | WifiManager.WIFI_FEATURE_LINK_LAYER_STATS
638                         | WifiManager.WIFI_FEATURE_TX_POWER_LIMIT
639                         | WifiManager.WIFI_FEATURE_INFRA
640                         | WifiManager.WIFI_FEATURE_P2P
641         );
642 
643         doAnswer(new AnswerWithArguments() {
644             public void answer(IWifiStaIface.getCapabilitiesCallback cb) throws RemoteException {
645                 cb.onValues(mWifiStatusSuccess, staIfaceHidlCaps);
646             }
647         }).when(mIWifiStaIface).getCapabilities(any(IWifiStaIface.getCapabilitiesCallback.class));
648         doAnswer(new AnswerWithArguments() {
649             public void answer(IWifiChip.getCapabilitiesCallback cb) throws RemoteException {
650                 cb.onValues(mWifiStatusSuccess, chipHidlCaps);
651             }
652         }).when(mIWifiChip).getCapabilities(any(IWifiChip.getCapabilitiesCallback.class));
653         when(mHalDeviceManager.getSupportedIfaceTypes())
654                 .thenReturn(halDeviceManagerSupportedIfaces);
655 
656         assertEquals(expectedFeatureSet, mWifiVendorHal.getSupportedFeatureSet());
657     }
658 
659     /**
660      * Test enablement of link layer stats after startup
661      *
662      * Request link layer stats before HAL start
663      * - should not make it to the HAL layer
664      * Start the HAL in STA mode
665      * Request link layer stats twice more
666      * - enable request should make it to the HAL layer
667      * - HAL layer should have been called to make the requests (i.e., two calls total)
668      */
669     @Test
testLinkLayerStatsEnableAfterStartup()670     public void testLinkLayerStatsEnableAfterStartup() throws Exception {
671         doNothing().when(mIWifiStaIface).getLinkLayerStats(any());
672 
673         assertNull(mWifiVendorHal.getWifiLinkLayerStats());
674         assertTrue(mWifiVendorHal.startVendorHalSta());
675         assertTrue(mWifiVendorHal.isHalStarted());
676 
677         verify(mHalDeviceManager).start();
678         mWifiVendorHal.getWifiLinkLayerStats();
679         mWifiVendorHal.getWifiLinkLayerStats();
680         verify(mIWifiStaIface).enableLinkLayerStatsCollection(false); // mLinkLayerStatsDebug
681         verify(mIWifiStaIface, times(2)).getLinkLayerStats(any());
682     }
683 
684     /**
685      * Test that link layer stats are not enabled and harmless in AP mode
686      *
687      * Start the HAL in AP mode
688      * - stats should not be enabled
689      * Request link layer stats
690      * - HAL layer should have been called to make the request
691      */
692     @Test
testLinkLayerStatsNotEnabledAndHarmlessInApMode()693     public void testLinkLayerStatsNotEnabledAndHarmlessInApMode() throws Exception {
694         doNothing().when(mIWifiStaIface).getLinkLayerStats(any());
695 
696         assertTrue(mWifiVendorHal.startVendorHalAp());
697         assertTrue(mWifiVendorHal.isHalStarted());
698         assertNull(mWifiVendorHal.getWifiLinkLayerStats());
699 
700         verify(mHalDeviceManager).start();
701 
702         verify(mIWifiStaIface, never()).enableLinkLayerStatsCollection(false);
703         verify(mIWifiStaIface, never()).getLinkLayerStats(any());
704     }
705 
706     /**
707      * Test that the link layer stats fields are populated correctly.
708      *
709      * This is done by filling with random values and then using toString on the
710      * original and converted values, comparing just the numerics in the result.
711      * This makes the assumption that the fields are in the same order in both string
712      * representations, which is not quite true. So apply some fixups before the final
713      * comparison.
714      */
715     @Test
testLinkLayerStatsAssignment()716     public void testLinkLayerStatsAssignment() throws Exception {
717         Random r = new Random(1775968256);
718         StaLinkLayerStats stats = new StaLinkLayerStats();
719         randomizePacketStats(r, stats.iface.wmeBePktStats);
720         randomizePacketStats(r, stats.iface.wmeBkPktStats);
721         randomizePacketStats(r, stats.iface.wmeViPktStats);
722         randomizePacketStats(r, stats.iface.wmeVoPktStats);
723         randomizeRadioStats(r, stats.radios);
724 
725         stats.timeStampInMs = 42; // currently dropped in conversion
726 
727         String expected = numbersOnly(stats.toString());
728 
729         WifiLinkLayerStats converted = WifiVendorHal.frameworkFromHalLinkLayerStats(stats);
730 
731         String actual = numbersOnly(converted.toString());
732 
733         // Do the required fixups to the both expected and actual
734         expected = rmValue(expected, stats.radios.get(0).rxTimeInMs);
735         expected = rmValue(expected, stats.radios.get(0).onTimeInMsForScan);
736 
737         actual = rmValue(actual, stats.radios.get(0).rxTimeInMs);
738         actual = rmValue(actual, stats.radios.get(0).onTimeInMsForScan);
739         actual = actual + "42 ";
740 
741         // The remaining fields should agree
742         assertEquals(expected, actual);
743     }
744 
745     /** Just the digits with delimiting spaces, please */
numbersOnly(String s)746     private static String numbersOnly(String s) {
747         return s.replaceAll("[^0-9]+", " ");
748     }
749 
750     /** Remove the given value from the space-delimited string, or die trying. */
rmValue(String s, long value)751     private static String rmValue(String s, long value) throws Exception {
752         String ans = s.replaceAll(" " + value + " ", " ");
753         assertNotEquals(s, ans);
754         return ans;
755     }
756 
757     /**
758      * Populate packet stats with non-negative random values
759      */
randomizePacketStats(Random r, StaLinkLayerIfacePacketStats pstats)760     private static void randomizePacketStats(Random r, StaLinkLayerIfacePacketStats pstats) {
761         pstats.rxMpdu = r.nextLong() & 0xFFFFFFFFFFL; // more than 32 bits
762         pstats.txMpdu = r.nextLong() & 0xFFFFFFFFFFL;
763         pstats.lostMpdu = r.nextLong() & 0xFFFFFFFFFFL;
764         pstats.retries = r.nextLong() & 0xFFFFFFFFFFL;
765     }
766 
767    /**
768      * Populate radio stats with non-negative random values
769      */
randomizeRadioStats(Random r, ArrayList<StaLinkLayerRadioStats> rstats)770     private static void randomizeRadioStats(Random r, ArrayList<StaLinkLayerRadioStats> rstats) {
771         StaLinkLayerRadioStats rstat = new StaLinkLayerRadioStats();
772         rstat.onTimeInMs = r.nextInt() & 0xFFFFFF;
773         rstat.txTimeInMs = r.nextInt() & 0xFFFFFF;
774         for (int i = 0; i < 4; i++) {
775             Integer v = r.nextInt() & 0xFFFFFF;
776             rstat.txTimeInMsPerLevel.add(v);
777         }
778         rstat.rxTimeInMs = r.nextInt() & 0xFFFFFF;
779         rstat.onTimeInMsForScan = r.nextInt() & 0xFFFFFF;
780         rstats.add(rstat);
781     }
782 
783     /**
784      * Test that getFirmwareVersion() and getDriverVersion() work
785      *
786      * Calls before the STA is started are expected to return null.
787      */
788     @Test
testVersionGetters()789     public void testVersionGetters() throws Exception {
790         String firmwareVersion = "fuzzy";
791         String driverVersion = "dizzy";
792         IWifiChip.ChipDebugInfo chipDebugInfo = new IWifiChip.ChipDebugInfo();
793         chipDebugInfo.firmwareDescription = firmwareVersion;
794         chipDebugInfo.driverDescription = driverVersion;
795 
796         doAnswer(new AnswerWithArguments() {
797             public void answer(IWifiChip.requestChipDebugInfoCallback cb) throws RemoteException {
798                 cb.onValues(mWifiStatusSuccess, chipDebugInfo);
799             }
800         }).when(mIWifiChip).requestChipDebugInfo(any(IWifiChip.requestChipDebugInfoCallback.class));
801 
802         assertNull(mWifiVendorHal.getFirmwareVersion());
803         assertNull(mWifiVendorHal.getDriverVersion());
804 
805         assertTrue(mWifiVendorHal.startVendorHalSta());
806 
807         assertEquals(firmwareVersion, mWifiVendorHal.getFirmwareVersion());
808         assertEquals(driverVersion, mWifiVendorHal.getDriverVersion());
809     }
810 
811     /**
812      * For checkRoundTripIntTranslation lambdas
813      */
814     interface IntForInt {
translate(int value)815         int translate(int value);
816     }
817 
818     /**
819      * Checks that translation from x to y and back again is the identity function
820      *
821      * @param xFromY reverse translator
822      * @param yFromX forward translator
823      * @param xLimit non-inclusive upper bound on x (lower bound is zero)
824      */
checkRoundTripIntTranslation( IntForInt xFromY, IntForInt yFromX, int xFirst, int xLimit)825     private void checkRoundTripIntTranslation(
826             IntForInt xFromY, IntForInt yFromX, int xFirst, int xLimit) throws Exception {
827         int ex = 0;
828         for (int i = xFirst; i < xLimit; i++) {
829             assertEquals(i, xFromY.translate(yFromX.translate(i)));
830         }
831         try {
832             yFromX.translate(xLimit);
833             assertTrue("expected an exception here", false);
834         } catch (IllegalArgumentException e) {
835             ex++;
836         }
837         try {
838             xFromY.translate(yFromX.translate(xLimit - 1) + 1);
839             assertTrue("expected an exception here", false);
840         } catch (IllegalArgumentException e) {
841             ex++;
842         }
843         assertEquals(2, ex);
844     }
845 
846 
847     /**
848      * Test translations of RTT type
849      */
850     @Test
testRttTypeTranslation()851     public void testRttTypeTranslation() throws Exception {
852         checkRoundTripIntTranslation(
853                 (y) -> WifiVendorHal.halRttTypeFromFrameworkRttType(y),
854                 (x) -> WifiVendorHal.frameworkRttTypeFromHalRttType(x),
855                 1, 3);
856     }
857 
858     /**
859      * Test translations of peer type
860      */
861     @Test
testPeerTranslation()862     public void testPeerTranslation() throws Exception {
863         checkRoundTripIntTranslation(
864                 (y) -> WifiVendorHal.halPeerFromFrameworkPeer(y),
865                 (x) -> WifiVendorHal.frameworkPeerFromHalPeer(x),
866                 1, 6);
867     }
868 
869     /**
870      * Test translations of channel width
871      */
872     @Test
testChannelWidth()873     public void testChannelWidth() throws Exception {
874         checkRoundTripIntTranslation(
875                 (y) -> WifiVendorHal.halChannelWidthFromFrameworkChannelWidth(y),
876                 (x) -> WifiVendorHal.frameworkChannelWidthFromHalChannelWidth(x),
877                 0, 5);
878     }
879 
880     /**
881      * Test translations of preamble type mask
882      */
883     @Test
testPreambleTranslation()884     public void testPreambleTranslation() throws Exception {
885         checkRoundTripIntTranslation(
886                 (y) -> WifiVendorHal.halPreambleFromFrameworkPreamble(y),
887                 (x) -> WifiVendorHal.frameworkPreambleFromHalPreamble(x),
888                 0, 8);
889     }
890 
891     /**
892      * Test translations of bandwidth mask
893      */
894     @Test
testBandwidthTranslations()895     public void testBandwidthTranslations() throws Exception {
896         checkRoundTripIntTranslation(
897                 (y) -> WifiVendorHal.halBwFromFrameworkBw(y),
898                 (x) -> WifiVendorHal.frameworkBwFromHalBw(x),
899                 0, 64);
900     }
901 
902     @Test
testGetRttStuff()903     public void testGetRttStuff() throws Exception {
904         RttManager.RttParams params = new RttManager.RttParams();
905         //TODO(b/34901744) populate
906         RttConfig config = WifiVendorHal.halRttConfigFromFrameworkRttParams(params);
907         //TODO(b/34901744) check
908     }
909 
910     @Test
testGetRttCapabilities()911     public void testGetRttCapabilities() throws Exception {
912         RttCapabilities capabilities = new RttCapabilities();
913         //TODO(b/34901744) populate
914 
915         doAnswer(new AnswerWithArguments() {
916             public void answer(IWifiRttController.getCapabilitiesCallback cb)
917                     throws RemoteException {
918                 cb.onValues(mWifiStatusSuccess, capabilities);
919             }
920         }).when(mIWifiRttController).getCapabilities(any(
921                 IWifiRttController.getCapabilitiesCallback.class));
922 
923         assertNull(mWifiVendorHal.getRttCapabilities());
924 
925         assertTrue(mWifiVendorHal.startVendorHalSta());
926 
927         RttManager.RttCapabilities actual = mWifiVendorHal.getRttCapabilities();
928         //TODO(b/34901744) check
929 
930     }
931 
932     //TODO(b/34901744) negative RTT test cases as well.
933     // e.g. invoke RTT without putting the HAL in the correct mode.
934 
935     /**
936      * Test that setScanningMacOui is hooked up to the HAL correctly
937      */
938     @Test
testSetScanningMacOui()939     public void testSetScanningMacOui() throws Exception {
940         byte[] oui = NativeUtil.macAddressOuiToByteArray("DA:A1:19");
941         byte[] zzz = NativeUtil.macAddressOuiToByteArray("00:00:00");
942 
943         when(mIWifiStaIface.setScanningMacOui(any())).thenReturn(mWifiStatusSuccess);
944 
945         assertFalse(mWifiVendorHal.setScanningMacOui(oui)); // expect fail - STA not started
946         assertTrue(mWifiVendorHal.startVendorHalSta());
947         assertFalse(mWifiVendorHal.setScanningMacOui(null));  // expect fail - null
948         assertFalse(mWifiVendorHal.setScanningMacOui(new byte[]{(byte) 1})); // expect fail - len
949         assertTrue(mWifiVendorHal.setScanningMacOui(oui));
950         assertTrue(mWifiVendorHal.setScanningMacOui(zzz));
951 
952         verify(mIWifiStaIface).setScanningMacOui(eq(oui));
953         verify(mIWifiStaIface).setScanningMacOui(eq(zzz));
954     }
955 
956     @Test
testStartSendingOffloadedPacket()957     public void testStartSendingOffloadedPacket() throws Exception {
958         byte[] srcMac = NativeUtil.macAddressToByteArray("4007b2088c81");
959         InetAddress src = InetAddress.parseNumericAddress("192.168.13.13");
960         InetAddress dst = InetAddress.parseNumericAddress("93.184.216.34");
961         int slot = 13;
962         int millis = 16000;
963 
964         KeepalivePacketData kap = KeepalivePacketData.nattKeepalivePacket(src, 63000, dst, 4500);
965 
966         when(mIWifiStaIface.startSendingKeepAlivePackets(
967                 anyInt(), any(), anyShort(), any(), any(), anyInt()
968         )).thenReturn(mWifiStatusSuccess);
969 
970         assertTrue(mWifiVendorHal.startVendorHalSta());
971         assertTrue(0 == mWifiVendorHal.startSendingOffloadedPacket(slot, srcMac, kap, millis));
972 
973         verify(mIWifiStaIface).startSendingKeepAlivePackets(
974                 eq(slot), any(), anyShort(), any(), any(), eq(millis));
975     }
976 
977     @Test
testStopSendingOffloadedPacket()978     public void testStopSendingOffloadedPacket() throws Exception {
979         int slot = 13;
980 
981         when(mIWifiStaIface.stopSendingKeepAlivePackets(anyInt())).thenReturn(mWifiStatusSuccess);
982 
983         assertTrue(mWifiVendorHal.startVendorHalSta());
984         assertTrue(0 == mWifiVendorHal.stopSendingOffloadedPacket(slot));
985 
986         verify(mIWifiStaIface).stopSendingKeepAlivePackets(eq(slot));
987     }
988 
989     /**
990      * Test the setup, invocation, and removal of a RSSI event handler
991      *
992      */
993     @Test
testRssiMonitoring()994     public void testRssiMonitoring() throws Exception {
995         when(mIWifiStaIface.startRssiMonitoring(anyInt(), anyInt(), anyInt()))
996                 .thenReturn(mWifiStatusSuccess);
997         when(mIWifiStaIface.stopRssiMonitoring(anyInt()))
998                 .thenReturn(mWifiStatusSuccess);
999 
1000         ArrayList<Byte> breach = new ArrayList<>(10);
1001         byte hi = -21;
1002         byte med = -42;
1003         byte lo = -84;
1004         Byte lower = -88;
1005         WifiNative.WifiRssiEventHandler handler;
1006         handler = ((cur) -> {
1007             breach.add(cur);
1008         });
1009         assertEquals(-1, mWifiVendorHal.startRssiMonitoring(hi, lo, handler)); // not started
1010         assertEquals(-1, mWifiVendorHal.stopRssiMonitoring()); // not started
1011         assertTrue(mWifiVendorHal.startVendorHalSta());
1012         assertEquals(0, mWifiVendorHal.startRssiMonitoring(hi, lo, handler));
1013         int theCmdId = mWifiVendorHal.sRssiMonCmdId;
1014         breach.clear();
1015         mIWifiStaIfaceEventCallback.onRssiThresholdBreached(theCmdId, new byte[6], lower);
1016         assertEquals(breach.get(0), lower);
1017         assertEquals(0, mWifiVendorHal.stopRssiMonitoring());
1018         assertEquals(0, mWifiVendorHal.startRssiMonitoring(hi, lo, handler));
1019         assertEquals(0, mWifiVendorHal.startRssiMonitoring(med, lo, handler)); // replacing works
1020         assertEquals(-1, mWifiVendorHal.startRssiMonitoring(hi, lo, null)); // null handler fails
1021         assertEquals(0, mWifiVendorHal.startRssiMonitoring(hi, lo, handler));
1022         assertEquals(-1, mWifiVendorHal.startRssiMonitoring(lo, hi, handler)); // empty range
1023     }
1024 
1025     /**
1026      * Test that getApfCapabilities is hooked up to the HAL correctly
1027      *
1028      * A call before the vendor HAL is started should return a non-null result with version 0
1029      *
1030      * A call after the HAL is started should return the mocked values.
1031      */
1032     @Test
testApfCapabilities()1033     public void testApfCapabilities() throws Exception {
1034         int myVersion = 33;
1035         int myMaxSize = 1234;
1036 
1037         StaApfPacketFilterCapabilities capabilities = new StaApfPacketFilterCapabilities();
1038         capabilities.version = myVersion;
1039         capabilities.maxLength = myMaxSize;
1040 
1041         doAnswer(new AnswerWithArguments() {
1042             public void answer(IWifiStaIface.getApfPacketFilterCapabilitiesCallback cb)
1043                     throws RemoteException {
1044                 cb.onValues(mWifiStatusSuccess, capabilities);
1045             }
1046         }).when(mIWifiStaIface).getApfPacketFilterCapabilities(any(
1047                 IWifiStaIface.getApfPacketFilterCapabilitiesCallback.class));
1048 
1049 
1050         assertEquals(0, mWifiVendorHal.getApfCapabilities().apfVersionSupported);
1051 
1052         assertTrue(mWifiVendorHal.startVendorHalSta());
1053 
1054         ApfCapabilities actual = mWifiVendorHal.getApfCapabilities();
1055 
1056         assertEquals(myVersion, actual.apfVersionSupported);
1057         assertEquals(myMaxSize, actual.maximumApfProgramSize);
1058         assertEquals(android.system.OsConstants.ARPHRD_ETHER, actual.apfPacketFormat);
1059         assertNotEquals(0, actual.apfPacketFormat);
1060     }
1061 
1062     /**
1063      * Test that an APF program can be installed.
1064      */
1065     @Test
testInstallApf()1066     public void testInstallApf() throws Exception {
1067         byte[] filter = new byte[] {19, 53, 10};
1068 
1069         ArrayList<Byte> expected = new ArrayList<>(3);
1070         for (byte b : filter) expected.add(b);
1071 
1072         when(mIWifiStaIface.installApfPacketFilter(anyInt(), any(ArrayList.class)))
1073                 .thenReturn(mWifiStatusSuccess);
1074 
1075         assertTrue(mWifiVendorHal.startVendorHalSta());
1076         assertTrue(mWifiVendorHal.installPacketFilter(filter));
1077 
1078         verify(mIWifiStaIface).installApfPacketFilter(eq(0), eq(expected));
1079     }
1080 
1081     /**
1082      * Test that the country code is set in AP mode (when it should be).
1083      */
1084     @Test
testSetCountryCodeHal()1085     public void testSetCountryCodeHal() throws Exception {
1086         byte[] expected = new byte[]{(byte) 'C', (byte) 'A'};
1087 
1088         when(mIWifiApIface.setCountryCode(any()))
1089                 .thenReturn(mWifiStatusSuccess);
1090 
1091         assertTrue(mWifiVendorHal.startVendorHalAp());
1092 
1093         assertFalse(mWifiVendorHal.setCountryCodeHal(null));
1094         assertFalse(mWifiVendorHal.setCountryCodeHal(""));
1095         assertFalse(mWifiVendorHal.setCountryCodeHal("A"));
1096         assertTrue(mWifiVendorHal.setCountryCodeHal("CA")); // Only one expected to succeed
1097         assertFalse(mWifiVendorHal.setCountryCodeHal("ZZZ"));
1098 
1099         verify(mIWifiApIface).setCountryCode(eq(expected));
1100     }
1101 
1102     /**
1103      * Test that RemoteException is caught and logged.
1104      */
1105     @Test
testRemoteExceptionIsHandled()1106     public void testRemoteExceptionIsHandled() throws Exception {
1107         mWifiLog = spy(mWifiLog);
1108         mWifiVendorHal.mVerboseLog = mWifiLog;
1109         when(mIWifiApIface.setCountryCode(any()))
1110                 .thenThrow(new RemoteException("oops"));
1111         assertTrue(mWifiVendorHal.startVendorHalAp());
1112         assertFalse(mWifiVendorHal.setCountryCodeHal("CA"));
1113         assertFalse(mWifiVendorHal.isHalStarted());
1114         verify(mWifiLog).err(any());
1115     }
1116 
1117     /**
1118      * Test that startLoggingToDebugRingBuffer is plumbed to chip
1119      *
1120      * A call before the vendor hal is started should just return false.
1121      * After starting in STA mode, the call should succeed, and pass ther right things down.
1122      */
1123     @Test
testStartLoggingRingBuffer()1124     public void testStartLoggingRingBuffer() throws Exception {
1125         when(mIWifiChip.startLoggingToDebugRingBuffer(
1126                 any(String.class), anyInt(), anyInt(), anyInt()
1127         )).thenReturn(mWifiStatusSuccess);
1128 
1129         assertFalse(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 0, 0, "One"));
1130         assertTrue(mWifiVendorHal.startVendorHalSta());
1131         assertTrue(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 11, 3000, "One"));
1132 
1133         verify(mIWifiChip).startLoggingToDebugRingBuffer("One", 1, 11, 3000);
1134     }
1135 
1136     /**
1137      * Same test as testStartLoggingRingBuffer, but in AP mode rather than STA.
1138      */
1139     @Test
testStartLoggingRingBufferOnAp()1140     public void testStartLoggingRingBufferOnAp() throws Exception {
1141         when(mIWifiChip.startLoggingToDebugRingBuffer(
1142                 any(String.class), anyInt(), anyInt(), anyInt()
1143         )).thenReturn(mWifiStatusSuccess);
1144 
1145         assertFalse(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 0, 0, "One"));
1146         assertTrue(mWifiVendorHal.startVendorHalAp());
1147         assertTrue(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 11, 3000, "One"));
1148 
1149         verify(mIWifiChip).startLoggingToDebugRingBuffer("One", 1, 11, 3000);
1150     }
1151 
1152     /**
1153      * Test that getRingBufferStatus gets and translates its stuff correctly
1154      */
1155     @Test
testRingBufferStatus()1156     public void testRingBufferStatus() throws Exception {
1157         WifiDebugRingBufferStatus one = new WifiDebugRingBufferStatus();
1158         one.ringName = "One";
1159         one.flags = WifiDebugRingBufferFlags.HAS_BINARY_ENTRIES;
1160         one.ringId = 5607371;
1161         one.sizeInBytes = 54321;
1162         one.freeSizeInBytes = 42;
1163         one.verboseLevel = WifiDebugRingBufferVerboseLevel.VERBOSE;
1164         String oneExpect = "name: One flag: 1 ringBufferId: 5607371 ringBufferByteSize: 54321"
1165                 + " verboseLevel: 2 writtenBytes: 0 readBytes: 0 writtenRecords: 0";
1166 
1167         WifiDebugRingBufferStatus two = new WifiDebugRingBufferStatus();
1168         two.ringName = "Two";
1169         two.flags = WifiDebugRingBufferFlags.HAS_ASCII_ENTRIES
1170                 | WifiDebugRingBufferFlags.HAS_PER_PACKET_ENTRIES;
1171         two.ringId = 4512470;
1172         two.sizeInBytes = 300;
1173         two.freeSizeInBytes = 42;
1174         two.verboseLevel = WifiDebugRingBufferVerboseLevel.DEFAULT;
1175 
1176         ArrayList<WifiDebugRingBufferStatus> halBufferStatus = new ArrayList<>(2);
1177         halBufferStatus.add(one);
1178         halBufferStatus.add(two);
1179 
1180         WifiNative.RingBufferStatus[] actual;
1181 
1182         doAnswer(new AnswerWithArguments() {
1183             public void answer(IWifiChip.getDebugRingBuffersStatusCallback cb)
1184                     throws RemoteException {
1185                 cb.onValues(mWifiStatusSuccess, halBufferStatus);
1186             }
1187         }).when(mIWifiChip).getDebugRingBuffersStatus(any(
1188                 IWifiChip.getDebugRingBuffersStatusCallback.class));
1189 
1190         assertTrue(mWifiVendorHal.startVendorHalSta());
1191         actual = mWifiVendorHal.getRingBufferStatus();
1192 
1193         assertEquals(halBufferStatus.size(), actual.length);
1194         assertEquals(oneExpect, actual[0].toString());
1195         assertEquals(two.ringId, actual[1].ringBufferId);
1196 
1197     }
1198 
1199     /**
1200      * Test that getRingBufferData calls forceDumpToDebugRingBuffer
1201      *
1202      * Try once before hal start, and twice after (one success, one failure).
1203      */
1204     @Test
testForceRingBufferDump()1205     public void testForceRingBufferDump() throws Exception {
1206         when(mIWifiChip.forceDumpToDebugRingBuffer(eq("Gunk"))).thenReturn(mWifiStatusSuccess);
1207         when(mIWifiChip.forceDumpToDebugRingBuffer(eq("Glop"))).thenReturn(mWifiStatusFailure);
1208 
1209         assertFalse(mWifiVendorHal.getRingBufferData("Gunk")); // hal not started
1210 
1211         assertTrue(mWifiVendorHal.startVendorHalSta());
1212 
1213         assertTrue(mWifiVendorHal.getRingBufferData("Gunk")); // mocked call succeeds
1214         assertFalse(mWifiVendorHal.getRingBufferData("Glop")); // mocked call fails
1215 
1216         verify(mIWifiChip).forceDumpToDebugRingBuffer("Gunk");
1217         verify(mIWifiChip).forceDumpToDebugRingBuffer("Glop");
1218     }
1219 
1220     /**
1221      * Tests the start of packet fate monitoring.
1222      *
1223      * Try once before hal start, and once after (one success, one failure).
1224      */
1225     @Test
testStartPktFateMonitoring()1226     public void testStartPktFateMonitoring() throws Exception {
1227         when(mIWifiStaIface.startDebugPacketFateMonitoring()).thenReturn(mWifiStatusSuccess);
1228 
1229         assertFalse(mWifiVendorHal.startPktFateMonitoring());
1230         verify(mIWifiStaIface, never()).startDebugPacketFateMonitoring();
1231 
1232         assertTrue(mWifiVendorHal.startVendorHalSta());
1233         assertTrue(mWifiVendorHal.startPktFateMonitoring());
1234         verify(mIWifiStaIface).startDebugPacketFateMonitoring();
1235     }
1236 
1237     /**
1238      * Tests the retrieval of tx packet fates.
1239      *
1240      * Try once before hal start, and once after.
1241      */
1242     @Test
testGetTxPktFates()1243     public void testGetTxPktFates() throws Exception {
1244         byte[] frameContentBytes = new byte[30];
1245         new Random().nextBytes(frameContentBytes);
1246         WifiDebugTxPacketFateReport fateReport = new WifiDebugTxPacketFateReport();
1247         fateReport.fate = WifiDebugTxPacketFate.DRV_QUEUED;
1248         fateReport.frameInfo.driverTimestampUsec = new Random().nextLong();
1249         fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.ETHERNET_II;
1250         fateReport.frameInfo.frameContent.addAll(
1251                 NativeUtil.byteArrayToArrayList(frameContentBytes));
1252 
1253         doAnswer(new AnswerWithArguments() {
1254             public void answer(IWifiStaIface.getDebugTxPacketFatesCallback cb) {
1255                 cb.onValues(mWifiStatusSuccess,
1256                         new ArrayList<WifiDebugTxPacketFateReport>(Arrays.asList(fateReport)));
1257             }
1258         }).when(mIWifiStaIface)
1259                 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
1260 
1261         WifiNative.TxFateReport[] retrievedFates = new WifiNative.TxFateReport[1];
1262         assertFalse(mWifiVendorHal.getTxPktFates(retrievedFates));
1263         verify(mIWifiStaIface, never())
1264                 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
1265 
1266         assertTrue(mWifiVendorHal.startVendorHalSta());
1267 
1268         assertTrue(mWifiVendorHal.getTxPktFates(retrievedFates));
1269         verify(mIWifiStaIface)
1270                 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
1271         assertEquals(WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED, retrievedFates[0].mFate);
1272         assertEquals(fateReport.frameInfo.driverTimestampUsec,
1273                 retrievedFates[0].mDriverTimestampUSec);
1274         assertEquals(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, retrievedFates[0].mFrameType);
1275         assertArrayEquals(frameContentBytes, retrievedFates[0].mFrameBytes);
1276     }
1277 
1278     /**
1279      * Tests the retrieval of tx packet fates when the number of fates retrieved exceeds the
1280      * input array.
1281      *
1282      * Try once before hal start, and once after.
1283      */
1284     @Test
testGetTxPktFatesExceedsInputArrayLength()1285     public void testGetTxPktFatesExceedsInputArrayLength() throws Exception {
1286         byte[] frameContentBytes = new byte[30];
1287         new Random().nextBytes(frameContentBytes);
1288         WifiDebugTxPacketFateReport fateReport = new WifiDebugTxPacketFateReport();
1289         fateReport.fate = WifiDebugTxPacketFate.FW_DROP_OTHER;
1290         fateReport.frameInfo.driverTimestampUsec = new Random().nextLong();
1291         fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.MGMT_80211;
1292         fateReport.frameInfo.frameContent.addAll(
1293                 NativeUtil.byteArrayToArrayList(frameContentBytes));
1294 
1295         doAnswer(new AnswerWithArguments() {
1296             public void answer(IWifiStaIface.getDebugTxPacketFatesCallback cb) {
1297                 cb.onValues(mWifiStatusSuccess,
1298                         new ArrayList<WifiDebugTxPacketFateReport>(Arrays.asList(
1299                                 fateReport, fateReport)));
1300             }
1301         }).when(mIWifiStaIface)
1302                 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
1303 
1304         WifiNative.TxFateReport[] retrievedFates = new WifiNative.TxFateReport[1];
1305         assertFalse(mWifiVendorHal.getTxPktFates(retrievedFates));
1306         verify(mIWifiStaIface, never())
1307                 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
1308 
1309         assertTrue(mWifiVendorHal.startVendorHalSta());
1310 
1311         assertTrue(mWifiVendorHal.getTxPktFates(retrievedFates));
1312         verify(mIWifiStaIface)
1313                 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
1314         assertEquals(WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER, retrievedFates[0].mFate);
1315         assertEquals(fateReport.frameInfo.driverTimestampUsec,
1316                 retrievedFates[0].mDriverTimestampUSec);
1317         assertEquals(WifiLoggerHal.FRAME_TYPE_80211_MGMT, retrievedFates[0].mFrameType);
1318         assertArrayEquals(frameContentBytes, retrievedFates[0].mFrameBytes);
1319     }
1320 
1321     /**
1322      * Tests the retrieval of rx packet fates.
1323      *
1324      * Try once before hal start, and once after.
1325      */
1326     @Test
testGetRxPktFates()1327     public void testGetRxPktFates() throws Exception {
1328         byte[] frameContentBytes = new byte[30];
1329         new Random().nextBytes(frameContentBytes);
1330         WifiDebugRxPacketFateReport fateReport = new WifiDebugRxPacketFateReport();
1331         fateReport.fate = WifiDebugRxPacketFate.SUCCESS;
1332         fateReport.frameInfo.driverTimestampUsec = new Random().nextLong();
1333         fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.ETHERNET_II;
1334         fateReport.frameInfo.frameContent.addAll(
1335                 NativeUtil.byteArrayToArrayList(frameContentBytes));
1336 
1337         doAnswer(new AnswerWithArguments() {
1338             public void answer(IWifiStaIface.getDebugRxPacketFatesCallback cb) {
1339                 cb.onValues(mWifiStatusSuccess,
1340                         new ArrayList<WifiDebugRxPacketFateReport>(Arrays.asList(fateReport)));
1341             }
1342         }).when(mIWifiStaIface)
1343                 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
1344 
1345         WifiNative.RxFateReport[] retrievedFates = new WifiNative.RxFateReport[1];
1346         assertFalse(mWifiVendorHal.getRxPktFates(retrievedFates));
1347         verify(mIWifiStaIface, never())
1348                 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
1349 
1350         assertTrue(mWifiVendorHal.startVendorHalSta());
1351 
1352         assertTrue(mWifiVendorHal.getRxPktFates(retrievedFates));
1353         verify(mIWifiStaIface)
1354                 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
1355         assertEquals(WifiLoggerHal.RX_PKT_FATE_SUCCESS, retrievedFates[0].mFate);
1356         assertEquals(fateReport.frameInfo.driverTimestampUsec,
1357                 retrievedFates[0].mDriverTimestampUSec);
1358         assertEquals(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, retrievedFates[0].mFrameType);
1359         assertArrayEquals(frameContentBytes, retrievedFates[0].mFrameBytes);
1360     }
1361 
1362     /**
1363      * Tests the retrieval of rx packet fates when the number of fates retrieved exceeds the
1364      * input array.
1365      *
1366      * Try once before hal start, and once after.
1367      */
1368     @Test
testGetRxPktFatesExceedsInputArrayLength()1369     public void testGetRxPktFatesExceedsInputArrayLength() throws Exception {
1370         byte[] frameContentBytes = new byte[30];
1371         new Random().nextBytes(frameContentBytes);
1372         WifiDebugRxPacketFateReport fateReport = new WifiDebugRxPacketFateReport();
1373         fateReport.fate = WifiDebugRxPacketFate.FW_DROP_FILTER;
1374         fateReport.frameInfo.driverTimestampUsec = new Random().nextLong();
1375         fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.MGMT_80211;
1376         fateReport.frameInfo.frameContent.addAll(
1377                 NativeUtil.byteArrayToArrayList(frameContentBytes));
1378 
1379         doAnswer(new AnswerWithArguments() {
1380             public void answer(IWifiStaIface.getDebugRxPacketFatesCallback cb) {
1381                 cb.onValues(mWifiStatusSuccess,
1382                         new ArrayList<WifiDebugRxPacketFateReport>(Arrays.asList(
1383                                 fateReport, fateReport)));
1384             }
1385         }).when(mIWifiStaIface)
1386                 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
1387 
1388         WifiNative.RxFateReport[] retrievedFates = new WifiNative.RxFateReport[1];
1389         assertFalse(mWifiVendorHal.getRxPktFates(retrievedFates));
1390         verify(mIWifiStaIface, never())
1391                 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
1392 
1393         assertTrue(mWifiVendorHal.startVendorHalSta());
1394 
1395         assertTrue(mWifiVendorHal.getRxPktFates(retrievedFates));
1396         verify(mIWifiStaIface)
1397                 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
1398         assertEquals(WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER, retrievedFates[0].mFate);
1399         assertEquals(fateReport.frameInfo.driverTimestampUsec,
1400                 retrievedFates[0].mDriverTimestampUSec);
1401         assertEquals(WifiLoggerHal.FRAME_TYPE_80211_MGMT, retrievedFates[0].mFrameType);
1402         assertArrayEquals(frameContentBytes, retrievedFates[0].mFrameBytes);
1403     }
1404 
1405     /**
1406      * Tests the failure to retrieve tx packet fates when the input array is empty.
1407      */
1408     @Test
testGetTxPktFatesEmptyInputArray()1409     public void testGetTxPktFatesEmptyInputArray() throws Exception {
1410         assertTrue(mWifiVendorHal.startVendorHalSta());
1411         assertFalse(mWifiVendorHal.getTxPktFates(new WifiNative.TxFateReport[0]));
1412         verify(mIWifiStaIface, never())
1413                 .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
1414     }
1415 
1416     /**
1417      * Tests the failure to retrieve rx packet fates when the input array is empty.
1418      */
1419     @Test
testGetRxPktFatesEmptyInputArray()1420     public void testGetRxPktFatesEmptyInputArray() throws Exception {
1421         assertTrue(mWifiVendorHal.startVendorHalSta());
1422         assertFalse(mWifiVendorHal.getRxPktFates(new WifiNative.RxFateReport[0]));
1423         verify(mIWifiStaIface, never())
1424                 .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
1425     }
1426 
1427     /**
1428      * Tests the nd offload enable/disable.
1429      */
1430     @Test
testEnableDisableNdOffload()1431     public void testEnableDisableNdOffload() throws Exception {
1432         when(mIWifiStaIface.enableNdOffload(anyBoolean())).thenReturn(mWifiStatusSuccess);
1433 
1434         assertFalse(mWifiVendorHal.configureNeighborDiscoveryOffload(true));
1435         verify(mIWifiStaIface, never()).enableNdOffload(anyBoolean());
1436 
1437         assertTrue(mWifiVendorHal.startVendorHalSta());
1438 
1439         assertTrue(mWifiVendorHal.configureNeighborDiscoveryOffload(true));
1440         verify(mIWifiStaIface).enableNdOffload(eq(true));
1441         assertTrue(mWifiVendorHal.configureNeighborDiscoveryOffload(false));
1442         verify(mIWifiStaIface).enableNdOffload(eq(false));
1443     }
1444 
1445     /**
1446      * Tests the nd offload enable failure.
1447      */
1448     @Test
testEnableNdOffloadFailure()1449     public void testEnableNdOffloadFailure() throws Exception {
1450         when(mIWifiStaIface.enableNdOffload(eq(true))).thenReturn(mWifiStatusFailure);
1451 
1452         assertTrue(mWifiVendorHal.startVendorHalSta());
1453 
1454         assertFalse(mWifiVendorHal.configureNeighborDiscoveryOffload(true));
1455         verify(mIWifiStaIface).enableNdOffload(eq(true));
1456     }
1457 
1458     /**
1459      * Tests the retrieval of wlan wake reason stats.
1460      */
1461     @Test
testGetWlanWakeReasonCount()1462     public void testGetWlanWakeReasonCount() throws Exception {
1463         WifiDebugHostWakeReasonStats stats = new WifiDebugHostWakeReasonStats();
1464         Random rand = new Random();
1465         stats.totalCmdEventWakeCnt = rand.nextInt();
1466         stats.totalDriverFwLocalWakeCnt = rand.nextInt();
1467         stats.totalRxPacketWakeCnt = rand.nextInt();
1468         stats.rxPktWakeDetails.rxUnicastCnt = rand.nextInt();
1469         stats.rxPktWakeDetails.rxMulticastCnt = rand.nextInt();
1470         stats.rxIcmpPkWakeDetails.icmpPkt = rand.nextInt();
1471         stats.rxIcmpPkWakeDetails.icmp6Pkt = rand.nextInt();
1472         stats.rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt = rand.nextInt();
1473         stats.rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt = rand.nextInt();
1474 
1475         doAnswer(new AnswerWithArguments() {
1476             public void answer(IWifiChip.getDebugHostWakeReasonStatsCallback cb) {
1477                 cb.onValues(mWifiStatusSuccess, stats);
1478             }
1479         }).when(mIWifiChip).getDebugHostWakeReasonStats(
1480                 any(IWifiChip.getDebugHostWakeReasonStatsCallback.class));
1481 
1482         assertNull(mWifiVendorHal.getWlanWakeReasonCount());
1483         verify(mIWifiChip, never())
1484                 .getDebugHostWakeReasonStats(
1485                         any(IWifiChip.getDebugHostWakeReasonStatsCallback.class));
1486 
1487         assertTrue(mWifiVendorHal.startVendorHalSta());
1488 
1489         WifiWakeReasonAndCounts retrievedStats = mWifiVendorHal.getWlanWakeReasonCount();
1490         verify(mIWifiChip).getDebugHostWakeReasonStats(
1491                 any(IWifiChip.getDebugHostWakeReasonStatsCallback.class));
1492         assertNotNull(retrievedStats);
1493         assertEquals(stats.totalCmdEventWakeCnt, retrievedStats.totalCmdEventWake);
1494         assertEquals(stats.totalDriverFwLocalWakeCnt, retrievedStats.totalDriverFwLocalWake);
1495         assertEquals(stats.totalRxPacketWakeCnt, retrievedStats.totalRxDataWake);
1496         assertEquals(stats.rxPktWakeDetails.rxUnicastCnt, retrievedStats.rxUnicast);
1497         assertEquals(stats.rxPktWakeDetails.rxMulticastCnt, retrievedStats.rxMulticast);
1498         assertEquals(stats.rxIcmpPkWakeDetails.icmpPkt, retrievedStats.icmp);
1499         assertEquals(stats.rxIcmpPkWakeDetails.icmp6Pkt, retrievedStats.icmp6);
1500         assertEquals(stats.rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt,
1501                 retrievedStats.ipv4RxMulticast);
1502         assertEquals(stats.rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt,
1503                 retrievedStats.ipv6Multicast);
1504     }
1505 
1506     /**
1507      * Tests the failure in retrieval of wlan wake reason stats.
1508      */
1509     @Test
testGetWlanWakeReasonCountFailure()1510     public void testGetWlanWakeReasonCountFailure() throws Exception {
1511         doAnswer(new AnswerWithArguments() {
1512             public void answer(IWifiChip.getDebugHostWakeReasonStatsCallback cb) {
1513                 cb.onValues(mWifiStatusFailure, new WifiDebugHostWakeReasonStats());
1514             }
1515         }).when(mIWifiChip).getDebugHostWakeReasonStats(
1516                 any(IWifiChip.getDebugHostWakeReasonStatsCallback.class));
1517 
1518         // This should work in both AP & STA mode.
1519         assertTrue(mWifiVendorHal.startVendorHalAp());
1520 
1521         assertNull(mWifiVendorHal.getWlanWakeReasonCount());
1522         verify(mIWifiChip).getDebugHostWakeReasonStats(
1523                 any(IWifiChip.getDebugHostWakeReasonStatsCallback.class));
1524     }
1525 
1526     /**
1527      * Test that getFwMemoryDump is properly plumbed
1528      */
1529     @Test
testGetFwMemoryDump()1530     public void testGetFwMemoryDump() throws Exception {
1531         byte [] sample = NativeUtil.hexStringToByteArray("268c7a3fbfa4661c0bdd6a36");
1532         ArrayList<Byte> halBlob = NativeUtil.byteArrayToArrayList(sample);
1533 
1534         doAnswer(new AnswerWithArguments() {
1535             public void answer(IWifiChip.requestFirmwareDebugDumpCallback cb)
1536                     throws RemoteException {
1537                 cb.onValues(mWifiStatusSuccess, halBlob);
1538             }
1539         }).when(mIWifiChip).requestFirmwareDebugDump(any(
1540                 IWifiChip.requestFirmwareDebugDumpCallback.class));
1541 
1542         assertTrue(mWifiVendorHal.startVendorHalSta());
1543         assertArrayEquals(sample, mWifiVendorHal.getFwMemoryDump());
1544     }
1545 
1546     /**
1547      * Test that getDriverStateDump is properly plumbed
1548      *
1549      * Just for variety, use AP mode here.
1550      */
1551     @Test
testGetDriverStateDump()1552     public void testGetDriverStateDump() throws Exception {
1553         byte [] sample = NativeUtil.hexStringToByteArray("e83ff543cf80083e6459d20f");
1554         ArrayList<Byte> halBlob = NativeUtil.byteArrayToArrayList(sample);
1555 
1556         doAnswer(new AnswerWithArguments() {
1557             public void answer(IWifiChip.requestDriverDebugDumpCallback cb)
1558                     throws RemoteException {
1559                 cb.onValues(mWifiStatusSuccess, halBlob);
1560             }
1561         }).when(mIWifiChip).requestDriverDebugDump(any(
1562                 IWifiChip.requestDriverDebugDumpCallback.class));
1563 
1564         assertTrue(mWifiVendorHal.startVendorHalAp());
1565         assertArrayEquals(sample, mWifiVendorHal.getDriverStateDump());
1566     }
1567 
1568     /**
1569      * Test that background scan failure is handled correctly.
1570      */
1571     @Test
testBgScanFailureCallback()1572     public void testBgScanFailureCallback() throws Exception {
1573         assertTrue(mWifiVendorHal.startVendorHalSta());
1574         assertNotNull(mIWifiStaIfaceEventCallback);
1575 
1576         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
1577         startBgScan(eventHandler);
1578 
1579         mIWifiStaIfaceEventCallback.onBackgroundScanFailure(mWifiVendorHal.mScan.cmdId);
1580         verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_FAILED);
1581     }
1582 
1583     /**
1584      * Test that background scan failure with wrong id is not reported.
1585      */
1586     @Test
testBgScanFailureCallbackWithInvalidCmdId()1587     public void testBgScanFailureCallbackWithInvalidCmdId() throws Exception {
1588         assertTrue(mWifiVendorHal.startVendorHalSta());
1589         assertNotNull(mIWifiStaIfaceEventCallback);
1590 
1591         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
1592         startBgScan(eventHandler);
1593 
1594         mIWifiStaIfaceEventCallback.onBackgroundScanFailure(mWifiVendorHal.mScan.cmdId + 1);
1595         verify(eventHandler, never()).onScanStatus(WifiNative.WIFI_SCAN_FAILED);
1596     }
1597 
1598     /**
1599      * Test that background scan full results are handled correctly.
1600      */
1601     @Test
testBgScanFullScanResults()1602     public void testBgScanFullScanResults() throws Exception {
1603         assertTrue(mWifiVendorHal.startVendorHalSta());
1604         assertNotNull(mIWifiStaIfaceEventCallback);
1605 
1606         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
1607         startBgScan(eventHandler);
1608 
1609         Pair<StaScanResult, ScanResult> result = createHidlAndFrameworkBgScanResult();
1610         mIWifiStaIfaceEventCallback.onBackgroundFullScanResult(
1611                 mWifiVendorHal.mScan.cmdId, 5, result.first);
1612 
1613         ArgumentCaptor<ScanResult> scanResultCaptor = ArgumentCaptor.forClass(ScanResult.class);
1614         verify(eventHandler).onFullScanResult(scanResultCaptor.capture(), eq(5));
1615 
1616         assertScanResultEqual(result.second, scanResultCaptor.getValue());
1617     }
1618 
1619     /**
1620      * Test that background scan results are handled correctly.
1621      */
1622     @Test
testBgScanScanResults()1623     public void testBgScanScanResults() throws Exception {
1624         assertTrue(mWifiVendorHal.startVendorHalSta());
1625         assertNotNull(mIWifiStaIfaceEventCallback);
1626 
1627         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
1628         startBgScan(eventHandler);
1629 
1630         Pair<ArrayList<StaScanData>, ArrayList<WifiScanner.ScanData>> data =
1631                 createHidlAndFrameworkBgScanDatas();
1632         mIWifiStaIfaceEventCallback.onBackgroundScanResults(
1633                 mWifiVendorHal.mScan.cmdId, data.first);
1634 
1635         verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
1636         assertScanDatasEqual(
1637                 data.second, Arrays.asList(mWifiVendorHal.mScan.latestScanResults));
1638     }
1639 
1640     /**
1641      * Test that starting a new background scan when one is active will stop the previous one.
1642      */
1643     @Test
testBgScanReplacement()1644     public void testBgScanReplacement() throws Exception {
1645         when(mIWifiStaIface.stopBackgroundScan(anyInt())).thenReturn(mWifiStatusSuccess);
1646         assertTrue(mWifiVendorHal.startVendorHalSta());
1647         assertNotNull(mIWifiStaIfaceEventCallback);
1648         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
1649         startBgScan(eventHandler);
1650         int cmdId1 = mWifiVendorHal.mScan.cmdId;
1651         startBgScan(eventHandler);
1652         assertNotEquals(mWifiVendorHal.mScan.cmdId, cmdId1);
1653         verify(mIWifiStaIface, times(2)).startBackgroundScan(anyInt(), any());
1654         verify(mIWifiStaIface).stopBackgroundScan(cmdId1);
1655     }
1656 
1657     /**
1658      * Test stopping a background scan.
1659      */
1660     @Test
testBgScanStop()1661     public void testBgScanStop() throws Exception {
1662         when(mIWifiStaIface.stopBackgroundScan(anyInt())).thenReturn(mWifiStatusSuccess);
1663         assertTrue(mWifiVendorHal.startVendorHalSta());
1664         assertNotNull(mIWifiStaIfaceEventCallback);
1665         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
1666         startBgScan(eventHandler);
1667 
1668         int cmdId = mWifiVendorHal.mScan.cmdId;
1669 
1670         mWifiVendorHal.stopBgScan();
1671         mWifiVendorHal.stopBgScan(); // second call should not do anything
1672         verify(mIWifiStaIface).stopBackgroundScan(cmdId); // Should be called just once
1673     }
1674 
1675     /**
1676      * Test pausing and restarting a background scan.
1677      */
1678     @Test
testBgScanPauseAndRestart()1679     public void testBgScanPauseAndRestart() throws Exception {
1680         when(mIWifiStaIface.stopBackgroundScan(anyInt())).thenReturn(mWifiStatusSuccess);
1681         assertTrue(mWifiVendorHal.startVendorHalSta());
1682         assertNotNull(mIWifiStaIfaceEventCallback);
1683         WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
1684         startBgScan(eventHandler);
1685 
1686         int cmdId = mWifiVendorHal.mScan.cmdId;
1687 
1688         mWifiVendorHal.pauseBgScan();
1689         mWifiVendorHal.restartBgScan();
1690         verify(mIWifiStaIface).stopBackgroundScan(cmdId); // Should be called just once
1691         verify(mIWifiStaIface, times(2)).startBackgroundScan(eq(cmdId), any());
1692     }
1693 
1694     /**
1695      * Test the handling of log handler set.
1696      */
1697     @Test
testSetLogHandler()1698     public void testSetLogHandler() throws Exception {
1699         when(mIWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(mWifiStatusSuccess);
1700 
1701         WifiNative.WifiLoggerEventHandler eventHandler =
1702                 mock(WifiNative.WifiLoggerEventHandler.class);
1703 
1704         assertFalse(mWifiVendorHal.setLoggingEventHandler(eventHandler));
1705         verify(mIWifiChip, never()).enableDebugErrorAlerts(anyBoolean());
1706 
1707         assertTrue(mWifiVendorHal.startVendorHalSta());
1708 
1709         assertTrue(mWifiVendorHal.setLoggingEventHandler(eventHandler));
1710         verify(mIWifiChip).enableDebugErrorAlerts(eq(true));
1711         reset(mIWifiChip);
1712 
1713         // Second call should fail.
1714         assertFalse(mWifiVendorHal.setLoggingEventHandler(eventHandler));
1715         verify(mIWifiChip, never()).enableDebugErrorAlerts(anyBoolean());
1716     }
1717 
1718     /**
1719      * Test the handling of log handler reset.
1720      */
1721     @Test
testResetLogHandler()1722     public void testResetLogHandler() throws Exception {
1723         when(mIWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(mWifiStatusSuccess);
1724         when(mIWifiChip.stopLoggingToDebugRingBuffer()).thenReturn(mWifiStatusSuccess);
1725 
1726         assertFalse(mWifiVendorHal.resetLogHandler());
1727         verify(mIWifiChip, never()).enableDebugErrorAlerts(anyBoolean());
1728         verify(mIWifiChip, never()).stopLoggingToDebugRingBuffer();
1729 
1730         assertTrue(mWifiVendorHal.startVendorHalSta());
1731 
1732         // Not set, so this should fail.
1733         assertFalse(mWifiVendorHal.resetLogHandler());
1734         verify(mIWifiChip, never()).enableDebugErrorAlerts(anyBoolean());
1735         verify(mIWifiChip, never()).stopLoggingToDebugRingBuffer();
1736 
1737         // Now set and then reset.
1738         assertTrue(mWifiVendorHal.setLoggingEventHandler(
1739                 mock(WifiNative.WifiLoggerEventHandler.class)));
1740         assertTrue(mWifiVendorHal.resetLogHandler());
1741         verify(mIWifiChip).enableDebugErrorAlerts(eq(false));
1742         verify(mIWifiChip).stopLoggingToDebugRingBuffer();
1743         reset(mIWifiChip);
1744 
1745         // Second reset should fail.
1746         assertFalse(mWifiVendorHal.resetLogHandler());
1747         verify(mIWifiChip, never()).enableDebugErrorAlerts(anyBoolean());
1748         verify(mIWifiChip, never()).stopLoggingToDebugRingBuffer();
1749     }
1750 
1751     /**
1752      * Test the handling of alert callback.
1753      */
1754     @Test
testAlertCallback()1755     public void testAlertCallback() throws Exception {
1756         when(mIWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(mWifiStatusSuccess);
1757         when(mIWifiChip.stopLoggingToDebugRingBuffer()).thenReturn(mWifiStatusSuccess);
1758 
1759         assertTrue(mWifiVendorHal.startVendorHalSta());
1760         assertNotNull(mIWifiChipEventCallback);
1761 
1762         int errorCode = 5;
1763         byte[] errorData = new byte[45];
1764         new Random().nextBytes(errorData);
1765 
1766         // Randomly raise the HIDL callback before we register for the log callback.
1767         // This should be safely ignored. (Not trigger NPE.)
1768         mIWifiChipEventCallback.onDebugErrorAlert(
1769                 errorCode, NativeUtil.byteArrayToArrayList(errorData));
1770         mLooper.dispatchAll();
1771 
1772         WifiNative.WifiLoggerEventHandler eventHandler =
1773                 mock(WifiNative.WifiLoggerEventHandler.class);
1774         assertTrue(mWifiVendorHal.setLoggingEventHandler(eventHandler));
1775         verify(mIWifiChip).enableDebugErrorAlerts(eq(true));
1776 
1777         // Now raise the HIDL callback, this should be properly handled.
1778         mIWifiChipEventCallback.onDebugErrorAlert(
1779                 errorCode, NativeUtil.byteArrayToArrayList(errorData));
1780         mLooper.dispatchAll();
1781         verify(eventHandler).onWifiAlert(eq(errorCode), eq(errorData));
1782 
1783         // Now stop the logging and invoke the callback. This should be ignored.
1784         reset(eventHandler);
1785         assertTrue(mWifiVendorHal.resetLogHandler());
1786         mIWifiChipEventCallback.onDebugErrorAlert(
1787                 errorCode, NativeUtil.byteArrayToArrayList(errorData));
1788         mLooper.dispatchAll();
1789         verify(eventHandler, never()).onWifiAlert(anyInt(), anyObject());
1790     }
1791 
1792     /**
1793      * Test the handling of ring buffer callback.
1794      */
1795     @Test
testRingBufferDataCallback()1796     public void testRingBufferDataCallback() throws Exception {
1797         when(mIWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(mWifiStatusSuccess);
1798         when(mIWifiChip.stopLoggingToDebugRingBuffer()).thenReturn(mWifiStatusSuccess);
1799 
1800         assertTrue(mWifiVendorHal.startVendorHalSta());
1801         assertNotNull(mIWifiChipEventCallback);
1802 
1803         byte[] errorData = new byte[45];
1804         new Random().nextBytes(errorData);
1805 
1806         // Randomly raise the HIDL callback before we register for the log callback.
1807         // This should be safely ignored. (Not trigger NPE.)
1808         mIWifiChipEventCallback.onDebugRingBufferDataAvailable(
1809                 new WifiDebugRingBufferStatus(), NativeUtil.byteArrayToArrayList(errorData));
1810         mLooper.dispatchAll();
1811 
1812         WifiNative.WifiLoggerEventHandler eventHandler =
1813                 mock(WifiNative.WifiLoggerEventHandler.class);
1814         assertTrue(mWifiVendorHal.setLoggingEventHandler(eventHandler));
1815         verify(mIWifiChip).enableDebugErrorAlerts(eq(true));
1816 
1817         // Now raise the HIDL callback, this should be properly handled.
1818         mIWifiChipEventCallback.onDebugRingBufferDataAvailable(
1819                 new WifiDebugRingBufferStatus(), NativeUtil.byteArrayToArrayList(errorData));
1820         mLooper.dispatchAll();
1821         verify(eventHandler).onRingBufferData(
1822                 any(WifiNative.RingBufferStatus.class), eq(errorData));
1823 
1824         // Now stop the logging and invoke the callback. This should be ignored.
1825         reset(eventHandler);
1826         assertTrue(mWifiVendorHal.resetLogHandler());
1827         mIWifiChipEventCallback.onDebugRingBufferDataAvailable(
1828                 new WifiDebugRingBufferStatus(), NativeUtil.byteArrayToArrayList(errorData));
1829         mLooper.dispatchAll();
1830         verify(eventHandler, never()).onRingBufferData(anyObject(), anyObject());
1831     }
1832 
1833     /**
1834      * Test the handling of Vendor HAL death.
1835      */
1836     @Test
testVendorHalDeath()1837     public void testVendorHalDeath() {
1838         // Invoke the HAL device manager status callback with ready set to false to indicate the
1839         // death of the HAL.
1840         when(mHalDeviceManager.isReady()).thenReturn(false);
1841         mHalDeviceManagerStatusCallbacks.onStatusChanged();
1842 
1843         verify(mVendorHalDeathHandler).onDeath();
1844     }
1845 
1846     /**
1847      * Test the new selectTxPowerScenario HIDL method invocation. This should return failure if the
1848      * HAL service is exposing the 1.0 interface.
1849      */
1850     @Test
testSelectTxPowerScenario()1851     public void testSelectTxPowerScenario() throws RemoteException {
1852         assertTrue(mWifiVendorHal.startVendorHal(true));
1853         // Should fail because we exposed the 1.0 IWifiChip.
1854         assertFalse(
1855                 mWifiVendorHal.selectTxPowerScenario(WifiNative.TX_POWER_SCENARIO_VOICE_CALL));
1856         verify(mIWifiChipV11, never()).selectTxPowerScenario(anyInt());
1857         mWifiVendorHal.stopVendorHal();
1858 
1859         // Now expose the 1.1 IWifiChip.
1860         mWifiVendorHal = new WifiVendorHalSpyV1_1(mHalDeviceManager, mLooper.getLooper());
1861         when(mIWifiChipV11.selectTxPowerScenario(anyInt())).thenReturn(mWifiStatusSuccess);
1862 
1863         assertTrue(mWifiVendorHal.startVendorHal(true));
1864         assertTrue(
1865                 mWifiVendorHal.selectTxPowerScenario(WifiNative.TX_POWER_SCENARIO_VOICE_CALL));
1866         verify(mIWifiChipV11).selectTxPowerScenario(
1867                 eq(android.hardware.wifi.V1_1.IWifiChip.TxPowerScenario.VOICE_CALL));
1868         verify(mIWifiChipV11, never()).resetTxPowerScenario();
1869         mWifiVendorHal.stopVendorHal();
1870     }
1871 
1872     /**
1873      * Test the new resetTxPowerScenario HIDL method invocation. This should return failure if the
1874      * HAL service is exposing the 1.0 interface.
1875      */
1876     @Test
testResetTxPowerScenario()1877     public void testResetTxPowerScenario() throws RemoteException {
1878         assertTrue(mWifiVendorHal.startVendorHal(true));
1879         // Should fail because we exposed the 1.0 IWifiChip.
1880         assertFalse(mWifiVendorHal.selectTxPowerScenario(WifiNative.TX_POWER_SCENARIO_NORMAL));
1881         verify(mIWifiChipV11, never()).resetTxPowerScenario();
1882         mWifiVendorHal.stopVendorHal();
1883 
1884         // Now expose the 1.1 IWifiChip.
1885         mWifiVendorHal = new WifiVendorHalSpyV1_1(mHalDeviceManager, mLooper.getLooper());
1886         when(mIWifiChipV11.resetTxPowerScenario()).thenReturn(mWifiStatusSuccess);
1887 
1888         assertTrue(mWifiVendorHal.startVendorHal(true));
1889         assertTrue(mWifiVendorHal.selectTxPowerScenario(WifiNative.TX_POWER_SCENARIO_NORMAL));
1890         verify(mIWifiChipV11).resetTxPowerScenario();
1891         verify(mIWifiChipV11, never()).selectTxPowerScenario(anyInt());
1892         mWifiVendorHal.stopVendorHal();
1893     }
1894 
1895     /**
1896      * Test the new selectTxPowerScenario HIDL method invocation with a bad scenario index.
1897      */
1898     @Test
testInvalidSelectTxPowerScenario()1899     public void testInvalidSelectTxPowerScenario() throws RemoteException {
1900         // Expose the 1.1 IWifiChip.
1901         mWifiVendorHal = new WifiVendorHalSpyV1_1(mHalDeviceManager, mLooper.getLooper());
1902         when(mIWifiChipV11.selectTxPowerScenario(anyInt())).thenReturn(mWifiStatusSuccess);
1903 
1904         assertTrue(mWifiVendorHal.startVendorHal(true));
1905         assertFalse(mWifiVendorHal.selectTxPowerScenario(-6));
1906         verify(mIWifiChipV11, never()).selectTxPowerScenario(anyInt());
1907         verify(mIWifiChipV11, never()).resetTxPowerScenario();
1908         mWifiVendorHal.stopVendorHal();
1909     }
1910 
startBgScan(WifiNative.ScanEventHandler eventHandler)1911     private void startBgScan(WifiNative.ScanEventHandler eventHandler) throws Exception {
1912         when(mIWifiStaIface.startBackgroundScan(
1913                 anyInt(), any(StaBackgroundScanParameters.class))).thenReturn(mWifiStatusSuccess);
1914         WifiNative.ScanSettings settings = new WifiNative.ScanSettings();
1915         settings.num_buckets = 1;
1916         WifiNative.BucketSettings bucketSettings = new WifiNative.BucketSettings();
1917         bucketSettings.bucket = 0;
1918         bucketSettings.period_ms = 16000;
1919         bucketSettings.report_events = WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN;
1920         settings.buckets = new WifiNative.BucketSettings[] {bucketSettings};
1921         assertTrue(mWifiVendorHal.startBgScan(settings, eventHandler));
1922     }
1923 
1924     // Create a pair of HIDL scan result and its corresponding framework scan result for
1925     // comparison.
createHidlAndFrameworkBgScanResult()1926     private Pair<StaScanResult, ScanResult> createHidlAndFrameworkBgScanResult() {
1927         StaScanResult staScanResult = new StaScanResult();
1928         Random random = new Random();
1929         byte[] ssid = new byte[8];
1930         random.nextBytes(ssid);
1931         staScanResult.ssid.addAll(NativeUtil.byteArrayToArrayList(ssid));
1932         random.nextBytes(staScanResult.bssid);
1933         staScanResult.frequency = 2432;
1934         staScanResult.rssi = -45;
1935         staScanResult.timeStampInUs = 5;
1936         WifiInformationElement ie1 = new WifiInformationElement();
1937         byte[] ie1_data = new byte[56];
1938         random.nextBytes(ie1_data);
1939         ie1.id = 1;
1940         ie1.data.addAll(NativeUtil.byteArrayToArrayList(ie1_data));
1941         staScanResult.informationElements.add(ie1);
1942 
1943         // Now create the corresponding Scan result structure.
1944         ScanResult scanResult = new ScanResult();
1945         scanResult.SSID = NativeUtil.encodeSsid(staScanResult.ssid);
1946         scanResult.BSSID = NativeUtil.macAddressFromByteArray(staScanResult.bssid);
1947         scanResult.wifiSsid = WifiSsid.createFromByteArray(ssid);
1948         scanResult.frequency = staScanResult.frequency;
1949         scanResult.level = staScanResult.rssi;
1950         scanResult.timestamp = staScanResult.timeStampInUs;
1951         scanResult.bytes = new byte[57];
1952         scanResult.bytes[0] = ie1.id;
1953         System.arraycopy(ie1_data, 0, scanResult.bytes, 1, ie1_data.length);
1954 
1955         return Pair.create(staScanResult, scanResult);
1956     }
1957 
1958     // Create a pair of HIDL scan datas and its corresponding framework scan datas for
1959     // comparison.
1960     private Pair<ArrayList<StaScanData>, ArrayList<WifiScanner.ScanData>>
createHidlAndFrameworkBgScanDatas()1961             createHidlAndFrameworkBgScanDatas() {
1962         ArrayList<StaScanData> staScanDatas = new ArrayList<>();
1963         StaScanData staScanData = new StaScanData();
1964 
1965         Pair<StaScanResult, ScanResult> result = createHidlAndFrameworkBgScanResult();
1966         staScanData.results.add(result.first);
1967         staScanData.bucketsScanned = 5;
1968         staScanData.flags = StaScanDataFlagMask.INTERRUPTED;
1969         staScanDatas.add(staScanData);
1970 
1971         ArrayList<WifiScanner.ScanData> scanDatas = new ArrayList<>();
1972         ScanResult[] scanResults = new ScanResult[1];
1973         scanResults[0] = result.second;
1974         WifiScanner.ScanData scanData =
1975                 new WifiScanner.ScanData(mWifiVendorHal.mScan.cmdId, 1,
1976                         staScanData.bucketsScanned, false, scanResults);
1977         scanDatas.add(scanData);
1978         return Pair.create(staScanDatas, scanDatas);
1979     }
1980 
assertScanResultEqual(ScanResult expected, ScanResult actual)1981     private void assertScanResultEqual(ScanResult expected, ScanResult actual) {
1982         assertEquals(expected.SSID, actual.SSID);
1983         assertEquals(expected.wifiSsid.getHexString(), actual.wifiSsid.getHexString());
1984         assertEquals(expected.BSSID, actual.BSSID);
1985         assertEquals(expected.frequency, actual.frequency);
1986         assertEquals(expected.level, actual.level);
1987         assertEquals(expected.timestamp, actual.timestamp);
1988         assertArrayEquals(expected.bytes, actual.bytes);
1989     }
1990 
assertScanResultsEqual(ScanResult[] expected, ScanResult[] actual)1991     private void assertScanResultsEqual(ScanResult[] expected, ScanResult[] actual) {
1992         assertEquals(expected.length, actual.length);
1993         for (int i = 0; i < expected.length; i++) {
1994             assertScanResultEqual(expected[i], actual[i]);
1995         }
1996     }
1997 
assertScanDataEqual(WifiScanner.ScanData expected, WifiScanner.ScanData actual)1998     private void assertScanDataEqual(WifiScanner.ScanData expected, WifiScanner.ScanData actual) {
1999         assertEquals(expected.getId(), actual.getId());
2000         assertEquals(expected.getFlags(), actual.getFlags());
2001         assertEquals(expected.getBucketsScanned(), actual.getBucketsScanned());
2002         assertScanResultsEqual(expected.getResults(), actual.getResults());
2003     }
2004 
assertScanDatasEqual( List<WifiScanner.ScanData> expected, List<WifiScanner.ScanData> actual)2005     private void assertScanDatasEqual(
2006             List<WifiScanner.ScanData> expected, List<WifiScanner.ScanData> actual) {
2007         assertEquals(expected.size(), actual.size());
2008         for (int i = 0; i < expected.size(); i++) {
2009             assertScanDataEqual(expected.get(i), actual.get(i));
2010         }
2011     }
2012 }
2013