Home | History | Annotate | Download | only in wifi
      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 {
    120         WifiVendorHalSpyV1_1(HalDeviceManager halDeviceManager, Looper looper) {
    121             super(halDeviceManager, looper);
    122         }
    123 
    124         @Override
    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      */
    133     static Answer<WifiStatus> answerWifiStatus(Answer<WifiStatus> statusLambda) {
    134         return (statusLambda);
    135     }
    136 
    137     /**
    138      * Sets up for unit test
    139      */
    140     @Before
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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 
    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 
    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
    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
    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
    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
    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
    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
    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
    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
    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 */
    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. */
    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      */
    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      */
    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
    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 {
    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      */
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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 
   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.
   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>>
   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 
   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 
   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 
   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 
   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