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 
     19 import static org.junit.Assert.*;
     20 import static org.mockito.ArgumentMatchers.anyInt;
     21 import static org.mockito.ArgumentMatchers.eq;
     22 import static org.mockito.Matchers.argThat;
     23 import static org.mockito.Mockito.*;
     24 
     25 import android.net.MacAddress;
     26 import android.net.wifi.IApInterface;
     27 import android.net.wifi.IApInterfaceEventCallback;
     28 import android.net.wifi.IClientInterface;
     29 import android.net.wifi.IPnoScanEvent;
     30 import android.net.wifi.IScanEvent;
     31 import android.net.wifi.IWifiScannerImpl;
     32 import android.net.wifi.IWificond;
     33 import android.net.wifi.ScanResult;
     34 import android.net.wifi.WifiConfiguration;
     35 import android.net.wifi.WifiEnterpriseConfig;
     36 import android.net.wifi.WifiScanner;
     37 import android.os.IBinder;
     38 import android.os.RemoteException;
     39 import android.support.test.filters.SmallTest;
     40 
     41 import com.android.server.wifi.util.NativeUtil;
     42 import com.android.server.wifi.wificond.ChannelSettings;
     43 import com.android.server.wifi.wificond.HiddenNetwork;
     44 import com.android.server.wifi.wificond.NativeScanResult;
     45 import com.android.server.wifi.wificond.PnoSettings;
     46 import com.android.server.wifi.wificond.RadioChainInfo;
     47 import com.android.server.wifi.wificond.SingleScanSettings;
     48 
     49 import org.junit.Before;
     50 import org.junit.Test;
     51 import org.mockito.ArgumentCaptor;
     52 import org.mockito.ArgumentMatcher;
     53 import org.mockito.Mock;
     54 import org.mockito.MockitoAnnotations;
     55 
     56 import java.io.ByteArrayOutputStream;
     57 import java.nio.charset.StandardCharsets;
     58 import java.util.ArrayList;
     59 import java.util.BitSet;
     60 import java.util.HashSet;
     61 import java.util.List;
     62 import java.util.Set;
     63 
     64 /**
     65  * Unit tests for {@link com.android.server.wifi.WificondControl}.
     66  */
     67 @SmallTest
     68 public class WificondControlTest {
     69     @Mock private WifiInjector mWifiInjector;
     70     @Mock private WifiMonitor mWifiMonitor;
     71     @Mock private WifiMetrics mWifiMetrics;
     72     @Mock private IWificond mWificond;
     73     @Mock private IBinder mWifiCondBinder;
     74     @Mock private IClientInterface mClientInterface;
     75     @Mock private IWifiScannerImpl mWifiScannerImpl;
     76     @Mock private CarrierNetworkConfig mCarrierNetworkConfig;
     77     @Mock private IApInterface mApInterface;
     78     @Mock private WifiNative.SoftApListener mSoftApListener;
     79     private WificondControl mWificondControl;
     80     private static final String TEST_INTERFACE_NAME = "test_wlan_if";
     81     private static final String TEST_INTERFACE_NAME1 = "test_wlan_if1";
     82     private static final byte[] TEST_SSID =
     83             new byte[] {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'};
     84     private static final byte[] TEST_PSK =
     85             new byte[] {'T', 'e', 's', 't'};
     86     private static final byte[] TEST_BSSID =
     87             new byte[] {(byte) 0x12, (byte) 0xef, (byte) 0xa1,
     88                         (byte) 0x2c, (byte) 0x97, (byte) 0x8b};
     89     // This the IE buffer which is consistent with TEST_SSID.
     90     private static final byte[] TEST_INFO_ELEMENT_SSID =
     91             new byte[] {
     92                     // Element ID for SSID.
     93                     (byte) 0x00,
     94                     // Length of the SSID: 0x0b or 11.
     95                     (byte) 0x0b,
     96                     // This is string "GoogleGuest"
     97                     'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'};
     98     // RSN IE data indicating EAP key management.
     99     private static final byte[] TEST_INFO_ELEMENT_RSN =
    100             new byte[] {
    101                     // Element ID for RSN.
    102                     (byte) 0x30,
    103                     // Length of the element data.
    104                     (byte) 0x18,
    105                     (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x02,
    106                     (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04,
    107                     (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x02, (byte) 0x01, (byte) 0x00,
    108                     (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x01, (byte) 0x00, (byte) 0x00 };
    109 
    110     private static final int TEST_FREQUENCY = 2456;
    111     private static final int TEST_SIGNAL_MBM = -4500;
    112     private static final long TEST_TSF = 34455441;
    113     private static final BitSet TEST_CAPABILITY = new BitSet(16) {{ set(2); set(5); }};
    114     private static final boolean TEST_ASSOCIATED = true;
    115     private static final NativeScanResult MOCK_NATIVE_SCAN_RESULT =
    116             new NativeScanResult() {{
    117                 ssid = TEST_SSID;
    118                 bssid = TEST_BSSID;
    119                 infoElement = TEST_INFO_ELEMENT_SSID;
    120                 frequency = TEST_FREQUENCY;
    121                 signalMbm = TEST_SIGNAL_MBM;
    122                 capability = TEST_CAPABILITY;
    123                 associated = TEST_ASSOCIATED;
    124                 radioChainInfos = new ArrayList<>();
    125             }};
    126     private static final RadioChainInfo MOCK_NATIVE_RADIO_CHAIN_INFO_1 =
    127             new RadioChainInfo() {{
    128                 chainId = 1;
    129                 level = -89;
    130             }};
    131     private static final RadioChainInfo MOCK_NATIVE_RADIO_CHAIN_INFO_2 =
    132             new RadioChainInfo() {{
    133                 chainId = 0;
    134                 level = -78;
    135             }};
    136     private static final Set<Integer> SCAN_FREQ_SET =
    137             new HashSet<Integer>() {{
    138                 add(2410);
    139                 add(2450);
    140                 add(5050);
    141                 add(5200);
    142             }};
    143     private static final String TEST_QUOTED_SSID_1 = "\"testSsid1\"";
    144     private static final String TEST_QUOTED_SSID_2 = "\"testSsid2\"";
    145 
    146     private static final Set<String> SCAN_HIDDEN_NETWORK_SSID_SET =
    147             new HashSet<String>() {{
    148                 add(TEST_QUOTED_SSID_1);
    149                 add(TEST_QUOTED_SSID_2);
    150             }};
    151 
    152 
    153     private static final WifiNative.PnoSettings TEST_PNO_SETTINGS =
    154             new WifiNative.PnoSettings() {{
    155                 isConnected = false;
    156                 periodInMs = 6000;
    157                 networkList = new WifiNative.PnoNetwork[2];
    158                 networkList[0] = new WifiNative.PnoNetwork();
    159                 networkList[1] = new WifiNative.PnoNetwork();
    160                 networkList[0].ssid = TEST_QUOTED_SSID_1;
    161                 networkList[0].flags = WifiScanner.PnoSettings.PnoNetwork.FLAG_DIRECTED_SCAN;
    162                 networkList[1].ssid = TEST_QUOTED_SSID_2;
    163                 networkList[1].flags = 0;
    164             }};
    165     private static final MacAddress TEST_MAC_ADDRESS = MacAddress.fromString("ee:33:a2:94:10:92");
    166 
    167     @Before
    168     public void setUp() throws Exception {
    169         // Setup mocks for successful WificondControl operation. Failure case mocks should be
    170         // created in specific tests
    171         MockitoAnnotations.initMocks(this);
    172         when(mWifiInjector.makeWificond()).thenReturn(mWificond);
    173         when(mWificond.asBinder()).thenReturn(mWifiCondBinder);
    174         when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl);
    175         when(mWificond.createClientInterface(any())).thenReturn(mClientInterface);
    176         when(mWificond.createApInterface(any())).thenReturn(mApInterface);
    177         when(mWificond.tearDownClientInterface(any())).thenReturn(true);
    178         when(mWificond.tearDownApInterface(any())).thenReturn(true);
    179         when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl);
    180         when(mClientInterface.getInterfaceName()).thenReturn(TEST_INTERFACE_NAME);
    181         when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics);
    182         mWificondControl = new WificondControl(mWifiInjector, mWifiMonitor, mCarrierNetworkConfig);
    183         assertEquals(mClientInterface, mWificondControl.setupInterfaceForClientMode(
    184                 TEST_INTERFACE_NAME));
    185         verify(mWifiInjector).makeWificond();
    186         verify(mWifiCondBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
    187     }
    188 
    189     /**
    190      * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) calls Wificond.
    191      */
    192     @Test
    193     public void testSetupInterfaceForClientMode() throws Exception {
    194         when(mWifiInjector.makeWificond()).thenReturn(mWificond);
    195         when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface);
    196         verify(mWificond).createClientInterface(TEST_INTERFACE_NAME);
    197     }
    198 
    199     /**
    200      * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) calls subscribeScanEvents().
    201      */
    202     @Test
    203     public void testSetupInterfaceForClientModeCallsScanEventSubscripiton() throws Exception {
    204         verify(mWifiScannerImpl).subscribeScanEvents(any(IScanEvent.class));
    205     }
    206 
    207     /**
    208      * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) returns null when wificond is
    209      * not started.
    210      */
    211     @Test
    212     public void testSetupInterfaceForClientModeErrorWhenWificondIsNotStarted() throws Exception {
    213         // Invoke wificond death handler to clear the handle.
    214         mWificondControl.binderDied();
    215         when(mWifiInjector.makeWificond()).thenReturn(null);
    216         IClientInterface returnedClientInterface =
    217                 mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME);
    218         assertEquals(null, returnedClientInterface);
    219         verify(mWifiInjector, times(2)).makeWificond();
    220     }
    221 
    222     /**
    223      * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) returns null when wificond
    224      * failed to setup client interface.
    225      */
    226     @Test
    227     public void testSetupInterfaceForClientModeErrorWhenWificondFailedToSetupInterface()
    228             throws Exception {
    229         when(mWifiInjector.makeWificond()).thenReturn(mWificond);
    230         when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(null);
    231 
    232         IClientInterface returnedClientInterface =
    233                 mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME);
    234         assertEquals(null, returnedClientInterface);
    235     }
    236 
    237     /**
    238      * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond.
    239      */
    240     @Test
    241     public void testTeardownClientInterface() throws Exception {
    242         when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(true);
    243 
    244         assertTrue(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME));
    245         verify(mWifiScannerImpl).unsubscribeScanEvents();
    246         verify(mWifiScannerImpl).unsubscribePnoScanEvents();
    247         verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME);
    248     }
    249 
    250     /**
    251      * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond.
    252      */
    253     @Test
    254     public void testTeardownClientInterfaceOnInvalidIface() throws Exception {
    255         when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME1)).thenReturn(true);
    256 
    257         assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME1));
    258         verify(mWifiScannerImpl, never()).unsubscribeScanEvents();
    259         verify(mWifiScannerImpl, never()).unsubscribePnoScanEvents();
    260         verify(mWificond, never()).tearDownClientInterface(any());
    261     }
    262 
    263     /**
    264      * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond.
    265      */
    266     @Test
    267     public void testTeardownClientInterfaceFailDueToExceptionScannerUnsubscribe() throws Exception {
    268         when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(true);
    269         doThrow(new RemoteException()).when(mWifiScannerImpl).unsubscribeScanEvents();
    270 
    271         assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME));
    272         verify(mWifiScannerImpl).unsubscribeScanEvents();
    273         verify(mWifiScannerImpl, never()).unsubscribePnoScanEvents();
    274         verify(mWificond, never()).tearDownClientInterface(TEST_INTERFACE_NAME);
    275     }
    276     /**
    277      * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond.
    278      */
    279     @Test
    280     public void testTeardownClientInterfaceErrorWhenWificondFailed() throws Exception {
    281         when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(false);
    282 
    283         assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME));
    284         verify(mWifiScannerImpl).unsubscribeScanEvents();
    285         verify(mWifiScannerImpl).unsubscribePnoScanEvents();
    286         verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME);
    287     }
    288 
    289     /**
    290      * Verifies that the client handles are cleared after teardown.
    291      */
    292     @Test
    293     public void testTeardownClientInterfaceClearsHandles() throws Exception {
    294         testTeardownClientInterface();
    295 
    296         assertNull(mWificondControl.signalPoll(TEST_INTERFACE_NAME));
    297         verify(mClientInterface, never()).signalPoll();
    298 
    299         assertFalse(mWificondControl.scan(
    300                 TEST_INTERFACE_NAME, WifiNative.SCAN_TYPE_LOW_LATENCY,
    301                 SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_SET));
    302         verify(mWifiScannerImpl, never()).scan(any());
    303     }
    304 
    305     /**
    306      * Verifies that setupInterfaceForSoftApMode(TEST_INTERFACE_NAME) calls wificond.
    307      */
    308     @Test
    309     public void testSetupInterfaceForSoftApMode() throws Exception {
    310         when(mWifiInjector.makeWificond()).thenReturn(mWificond);
    311         when(mWificond.createApInterface(TEST_INTERFACE_NAME)).thenReturn(mApInterface);
    312 
    313         IApInterface returnedApInterface =
    314                 mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME);
    315         assertEquals(mApInterface, returnedApInterface);
    316         verify(mWifiInjector).makeWificond();
    317         verify(mWifiCondBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
    318         verify(mWificond).createApInterface(TEST_INTERFACE_NAME);
    319     }
    320 
    321     /**
    322      * Verifies that setupInterfaceForSoftAp() returns null when wificond is not started.
    323      */
    324     @Test
    325     public void testSetupInterfaceForSoftApModeErrorWhenWificondIsNotStarted() throws Exception {
    326         // Invoke wificond death handler to clear the handle.
    327         mWificondControl.binderDied();
    328         when(mWifiInjector.makeWificond()).thenReturn(null);
    329 
    330         IApInterface returnedApInterface =
    331                 mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME);
    332 
    333         assertEquals(null, returnedApInterface);
    334         verify(mWifiInjector, times(2)).makeWificond();
    335     }
    336 
    337     /**
    338      * Verifies that setupInterfaceForSoftApMode(TEST_INTERFACE_NAME) returns null when wificond
    339      * failed to setup AP interface.
    340      */
    341     @Test
    342     public void testSetupInterfaceForSoftApModeErrorWhenWificondFailedToSetupInterface()
    343             throws Exception {
    344         when(mWifiInjector.makeWificond()).thenReturn(mWificond);
    345         when(mWificond.createApInterface(TEST_INTERFACE_NAME)).thenReturn(null);
    346 
    347         IApInterface returnedApInterface =
    348                 mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME);
    349         assertEquals(null, returnedApInterface);
    350     }
    351 
    352     /**
    353      * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond.
    354      */
    355     @Test
    356     public void testTeardownSoftApInterface() throws Exception {
    357         testSetupInterfaceForSoftApMode();
    358         when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME)).thenReturn(true);
    359 
    360         assertTrue(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME));
    361         verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME);
    362     }
    363 
    364     /**
    365      * Verifies that tearDownSoftapInterface(TEST_INTERFACE_NAME) calls Wificond.
    366      */
    367     @Test
    368     public void testTeardownSoftApInterfaceOnInvalidIface() throws Exception {
    369         testSetupInterfaceForSoftApMode();
    370         when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME1)).thenReturn(true);
    371 
    372         assertFalse(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME1));
    373         verify(mWificond, never()).tearDownApInterface(any());
    374     }
    375 
    376     /**
    377      * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond.
    378      */
    379     @Test
    380     public void testTeardownSoftApInterfaceErrorWhenWificondFailed() throws Exception {
    381         testSetupInterfaceForSoftApMode();
    382         when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME)).thenReturn(false);
    383 
    384         assertFalse(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME));
    385         verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME);
    386     }
    387 
    388     /**
    389      * Verifies that the SoftAp handles are cleared after teardown.
    390      */
    391     @Test
    392     public void testTeardownSoftApInterfaceClearsHandles() throws Exception {
    393         testTeardownSoftApInterface();
    394 
    395         assertFalse(mWificondControl.startHostapd(
    396                 TEST_INTERFACE_NAME, mSoftApListener));
    397         verify(mApInterface, never()).startHostapd(any());
    398     }
    399 
    400     /**
    401      * Verifies that we can setup concurrent interfaces.
    402      */
    403     @Test
    404     public void testSetupMulitpleInterfaces() throws Exception {
    405         when(mWificond.createApInterface(TEST_INTERFACE_NAME1)).thenReturn(mApInterface);
    406 
    407         IApInterface returnedApInterface =
    408                 mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME1);
    409         assertEquals(mApInterface, returnedApInterface);
    410         verify(mWifiInjector).makeWificond();
    411         verify(mWifiCondBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
    412 
    413         verify(mWificond).createClientInterface(TEST_INTERFACE_NAME);
    414         verify(mWificond).createApInterface(TEST_INTERFACE_NAME1);
    415     }
    416 
    417     /**
    418      * Verifies that we can setup concurrent interfaces.
    419      */
    420     @Test
    421     public void testTeardownMulitpleInterfaces() throws Exception {
    422         testSetupMulitpleInterfaces();
    423         assertTrue(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME));
    424         assertTrue(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME1));
    425 
    426         verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME);
    427         verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME1);
    428     }
    429 
    430     /**
    431      * Verifies that enableSupplicant() calls wificond.
    432      */
    433     @Test
    434     public void testEnableSupplicant() throws Exception {
    435         when(mWifiInjector.makeWificond()).thenReturn(mWificond);
    436         when(mWificond.enableSupplicant()).thenReturn(true);
    437 
    438         assertTrue(mWificondControl.enableSupplicant());
    439         verify(mWifiInjector).makeWificond();
    440         verify(mWificond).enableSupplicant();
    441     }
    442 
    443     /**
    444      * Verifies that enableSupplicant() returns false when there is no configured
    445      * client interface.
    446      */
    447     @Test
    448     public void testEnableSupplicantErrorWhenNoClientInterfaceConfigured() throws Exception {
    449         when(mWifiInjector.makeWificond()).thenReturn(mWificond);
    450         when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface);
    451 
    452         // Configure client interface.
    453         IClientInterface returnedClientInterface =
    454                 mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME);
    455         assertEquals(mClientInterface, returnedClientInterface);
    456 
    457         // Tear down interfaces.
    458         assertTrue(mWificondControl.tearDownInterfaces());
    459 
    460         // Enabling supplicant should fail.
    461         assertFalse(mWificondControl.enableSupplicant());
    462     }
    463 
    464     /**
    465      * Verifies that disableSupplicant() calls wificond.
    466      */
    467     @Test
    468     public void testDisableSupplicant() throws Exception {
    469         when(mWifiInjector.makeWificond()).thenReturn(mWificond);
    470         when(mWificond.disableSupplicant()).thenReturn(true);
    471 
    472         assertTrue(mWificondControl.disableSupplicant());
    473         verify(mWifiInjector).makeWificond();
    474         verify(mWificond).disableSupplicant();
    475     }
    476 
    477     /**
    478      * Verifies that disableSupplicant() returns false when there is no configured
    479      * client interface.
    480      */
    481     @Test
    482     public void testDisableSupplicantErrorWhenNoClientInterfaceConfigured() throws Exception {
    483         when(mWifiInjector.makeWificond()).thenReturn(mWificond);
    484         when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface);
    485 
    486         // Configure client interface.
    487         IClientInterface returnedClientInterface =
    488                 mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME);
    489         assertEquals(mClientInterface, returnedClientInterface);
    490 
    491         // Tear down interfaces.
    492         assertTrue(mWificondControl.tearDownInterfaces());
    493 
    494         // Disabling supplicant should fail.
    495         assertFalse(mWificondControl.disableSupplicant());
    496     }
    497 
    498     /**
    499      * Verifies that tearDownInterfaces() calls wificond.
    500      */
    501     @Test
    502     public void testTearDownInterfaces() throws Exception {
    503         when(mWifiInjector.makeWificond()).thenReturn(mWificond);
    504         assertTrue(mWificondControl.tearDownInterfaces());
    505         verify(mWificond).tearDownInterfaces();
    506     }
    507 
    508     /**
    509      * Verifies that tearDownInterfaces() calls unsubscribeScanEvents() when there was
    510      * a configured client interface.
    511      */
    512     @Test
    513     public void testTearDownInterfacesRemovesScanEventSubscription() throws Exception {
    514         assertTrue(mWificondControl.tearDownInterfaces());
    515         verify(mWifiScannerImpl).unsubscribeScanEvents();
    516     }
    517 
    518 
    519     /**
    520      * Verifies that tearDownInterfaces() returns false when wificond is not started.
    521      */
    522     @Test
    523     public void testTearDownInterfacesErrorWhenWificondIsNotStarterd() throws Exception {
    524         // Invoke wificond death handler to clear the handle.
    525         mWificondControl.binderDied();
    526         when(mWifiInjector.makeWificond()).thenReturn(null);
    527         assertFalse(mWificondControl.tearDownInterfaces());
    528     }
    529 
    530     /**
    531      * Verifies that signalPoll() calls wificond.
    532      */
    533     @Test
    534     public void testSignalPoll() throws Exception {
    535         when(mWifiInjector.makeWificond()).thenReturn(mWificond);
    536         when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface);
    537 
    538         mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME);
    539         mWificondControl.signalPoll(TEST_INTERFACE_NAME);
    540         verify(mClientInterface).signalPoll();
    541     }
    542 
    543     /**
    544      * Verifies that signalPoll() returns null when there is no configured client interface.
    545      */
    546     @Test
    547     public void testSignalPollErrorWhenNoClientInterfaceConfigured() throws Exception {
    548         when(mWifiInjector.makeWificond()).thenReturn(mWificond);
    549         when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface);
    550 
    551         // Configure client interface.
    552         IClientInterface returnedClientInterface =
    553                 mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME);
    554         assertEquals(mClientInterface, returnedClientInterface);
    555 
    556         // Tear down interfaces.
    557         assertTrue(mWificondControl.tearDownInterfaces());
    558 
    559         // Signal poll should fail.
    560         assertEquals(null, mWificondControl.signalPoll(TEST_INTERFACE_NAME));
    561     }
    562 
    563     /**
    564      * Verifies that getTxPacketCounters() calls wificond.
    565      */
    566     @Test
    567     public void testGetTxPacketCounters() throws Exception {
    568         when(mWifiInjector.makeWificond()).thenReturn(mWificond);
    569         when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface);
    570 
    571         mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME);
    572         mWificondControl.getTxPacketCounters(TEST_INTERFACE_NAME);
    573         verify(mClientInterface).getPacketCounters();
    574     }
    575 
    576     /**
    577      * Verifies that getTxPacketCounters() returns null when there is no configured client
    578      * interface.
    579      */
    580     @Test
    581     public void testGetTxPacketCountersErrorWhenNoClientInterfaceConfigured() throws Exception {
    582         when(mWifiInjector.makeWificond()).thenReturn(mWificond);
    583         when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface);
    584 
    585         // Configure client interface.
    586         IClientInterface returnedClientInterface =
    587                 mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME);
    588         assertEquals(mClientInterface, returnedClientInterface);
    589 
    590         // Tear down interfaces.
    591         assertTrue(mWificondControl.tearDownInterfaces());
    592 
    593         // Signal poll should fail.
    594         assertEquals(null, mWificondControl.getTxPacketCounters(TEST_INTERFACE_NAME));
    595     }
    596 
    597     /**
    598      * Verifies that getScanResults() returns null when there is no configured client
    599      * interface.
    600      */
    601     @Test
    602     public void testGetScanResultsErrorWhenNoClientInterfaceConfigured() throws Exception {
    603         when(mWifiInjector.makeWificond()).thenReturn(mWificond);
    604         when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface);
    605 
    606         // Configure client interface.
    607         IClientInterface returnedClientInterface =
    608                 mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME);
    609         assertEquals(mClientInterface, returnedClientInterface);
    610 
    611         // Tear down interfaces.
    612         assertTrue(mWificondControl.tearDownInterfaces());
    613 
    614         // getScanResults should fail.
    615         assertEquals(0,
    616                 mWificondControl.getScanResults(TEST_INTERFACE_NAME,
    617                         WificondControl.SCAN_TYPE_SINGLE_SCAN).size());
    618     }
    619 
    620     /**
    621      * Verifies that getScanResults() can parse NativeScanResult from wificond correctly,
    622      */
    623     @Test
    624     public void testGetScanResults() throws Exception {
    625         assertNotNull(mWifiScannerImpl);
    626 
    627         // Mock the returned array of NativeScanResult.
    628         NativeScanResult[] mockScanResults = {MOCK_NATIVE_SCAN_RESULT};
    629         when(mWifiScannerImpl.getScanResults()).thenReturn(mockScanResults);
    630 
    631         ArrayList<ScanDetail> returnedScanResults = mWificondControl.getScanResults(
    632                 TEST_INTERFACE_NAME, WificondControl.SCAN_TYPE_SINGLE_SCAN);
    633         // The test IEs {@link #TEST_INFO_ELEMENT} doesn't contained RSN IE, which means non-EAP
    634         // AP. So verify carrier network is not checked, since EAP is currently required for a
    635         // carrier network.
    636         verify(mCarrierNetworkConfig, never()).isCarrierNetwork(anyString());
    637         assertEquals(mockScanResults.length, returnedScanResults.size());
    638         // Since NativeScanResult is organized differently from ScanResult, this only checks
    639         // a few fields.
    640         for (int i = 0; i < mockScanResults.length; i++) {
    641             assertArrayEquals(mockScanResults[i].ssid,
    642                               returnedScanResults.get(i).getScanResult().SSID.getBytes());
    643             assertEquals(mockScanResults[i].frequency,
    644                          returnedScanResults.get(i).getScanResult().frequency);
    645             assertEquals(mockScanResults[i].tsf,
    646                          returnedScanResults.get(i).getScanResult().timestamp);
    647         }
    648     }
    649 
    650     /**
    651      * Verifies that scan result's carrier network info {@link ScanResult#isCarrierAp} and
    652      * {@link ScanResult#getCarrierApEapType} is set appropriated based on the carrier network
    653      * config.
    654      *
    655      * @throws Exception
    656      */
    657     @Test
    658     public void testGetScanResultsForCarrierAp() throws Exception {
    659         assertNotNull(mWifiScannerImpl);
    660 
    661         // Include RSN IE to indicate EAP key management.
    662         ByteArrayOutputStream out = new ByteArrayOutputStream();
    663         out.write(TEST_INFO_ELEMENT_SSID);
    664         out.write(TEST_INFO_ELEMENT_RSN);
    665         NativeScanResult nativeScanResult = new NativeScanResult(MOCK_NATIVE_SCAN_RESULT);
    666         nativeScanResult.infoElement = out.toByteArray();
    667         when(mWifiScannerImpl.getScanResults()).thenReturn(
    668                 new NativeScanResult[] {nativeScanResult});
    669 
    670         // AP associated with a carrier network.
    671         int eapType = WifiEnterpriseConfig.Eap.SIM;
    672         String carrierName = "Test Carrier";
    673         when(mCarrierNetworkConfig.isCarrierNetwork(new String(nativeScanResult.ssid)))
    674                 .thenReturn(true);
    675         when(mCarrierNetworkConfig.getNetworkEapType(new String(nativeScanResult.ssid)))
    676                 .thenReturn(eapType);
    677         when(mCarrierNetworkConfig.getCarrierName(new String(nativeScanResult.ssid)))
    678                 .thenReturn(carrierName);
    679         ArrayList<ScanDetail> returnedScanResults = mWificondControl.getScanResults(
    680                 TEST_INTERFACE_NAME, WificondControl.SCAN_TYPE_SINGLE_SCAN);
    681         assertEquals(1, returnedScanResults.size());
    682         // Verify returned scan result.
    683         ScanResult scanResult = returnedScanResults.get(0).getScanResult();
    684         assertArrayEquals(nativeScanResult.ssid, scanResult.SSID.getBytes());
    685         assertTrue(scanResult.isCarrierAp);
    686         assertEquals(eapType, scanResult.carrierApEapType);
    687         assertEquals(carrierName, scanResult.carrierName);
    688         reset(mCarrierNetworkConfig);
    689 
    690         // AP not associated with a carrier network.
    691         when(mCarrierNetworkConfig.isCarrierNetwork(new String(nativeScanResult.ssid)))
    692                 .thenReturn(false);
    693         returnedScanResults = mWificondControl.getScanResults(
    694                 TEST_INTERFACE_NAME, WificondControl.SCAN_TYPE_SINGLE_SCAN);
    695         assertEquals(1, returnedScanResults.size());
    696         // Verify returned scan result.
    697         scanResult = returnedScanResults.get(0).getScanResult();
    698         assertArrayEquals(nativeScanResult.ssid, scanResult.SSID.getBytes());
    699         assertFalse(scanResult.isCarrierAp);
    700         assertEquals(ScanResult.UNSPECIFIED, scanResult.carrierApEapType);
    701         assertEquals(null, scanResult.carrierName);
    702     }
    703 
    704     /**
    705      * Verifies that getScanResults() can parse NativeScanResult from wificond correctly,
    706      * when there is radio chain info.
    707      */
    708     @Test
    709     public void testGetScanResultsWithRadioChainInfo() throws Exception {
    710         assertNotNull(mWifiScannerImpl);
    711 
    712         // Mock the returned array of NativeScanResult.
    713         NativeScanResult nativeScanResult = new NativeScanResult(MOCK_NATIVE_SCAN_RESULT);
    714         // Add radio chain info
    715         ArrayList<RadioChainInfo> nativeRadioChainInfos = new ArrayList<RadioChainInfo>() {{
    716                 add(MOCK_NATIVE_RADIO_CHAIN_INFO_1);
    717                 add(MOCK_NATIVE_RADIO_CHAIN_INFO_2);
    718             }};
    719         nativeScanResult.radioChainInfos = nativeRadioChainInfos;
    720         NativeScanResult[] mockScanResults = { nativeScanResult };
    721 
    722         when(mWifiScannerImpl.getScanResults()).thenReturn(mockScanResults);
    723 
    724         ArrayList<ScanDetail> returnedScanResults = mWificondControl.getScanResults(
    725                 TEST_INTERFACE_NAME, WificondControl.SCAN_TYPE_SINGLE_SCAN);
    726         // The test IEs {@link #TEST_INFO_ELEMENT} doesn't contained RSN IE, which means non-EAP
    727         // AP. So verify carrier network is not checked, since EAP is currently required for a
    728         // carrier network.
    729         verify(mCarrierNetworkConfig, never()).isCarrierNetwork(anyString());
    730         assertEquals(mockScanResults.length, returnedScanResults.size());
    731         // Since NativeScanResult is organized differently from ScanResult, this only checks
    732         // a few fields.
    733         for (int i = 0; i < mockScanResults.length; i++) {
    734             assertArrayEquals(mockScanResults[i].ssid,
    735                     returnedScanResults.get(i).getScanResult().SSID.getBytes());
    736             assertEquals(mockScanResults[i].frequency,
    737                     returnedScanResults.get(i).getScanResult().frequency);
    738             assertEquals(mockScanResults[i].tsf,
    739                     returnedScanResults.get(i).getScanResult().timestamp);
    740             assertRadioChainInfosEqual(nativeRadioChainInfos,
    741                     returnedScanResults.get(i).getScanResult().radioChainInfos);
    742         }
    743     }
    744 
    745     /**
    746      * Verifies that Scan() can convert input parameters to SingleScanSettings correctly.
    747      */
    748     @Test
    749     public void testScan() throws Exception {
    750         when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true);
    751         assertTrue(mWificondControl.scan(
    752                 TEST_INTERFACE_NAME, WifiNative.SCAN_TYPE_LOW_POWER,
    753                 SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_SET));
    754         verify(mWifiScannerImpl).scan(argThat(new ScanMatcher(
    755                 IWifiScannerImpl.SCAN_TYPE_LOW_POWER,
    756                 SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_SET)));
    757     }
    758 
    759     /**
    760      * Verifies that Scan() can handle null input parameters correctly.
    761      */
    762     @Test
    763     public void testScanNullParameters() throws Exception {
    764         when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true);
    765         assertTrue(mWificondControl.scan(
    766                 TEST_INTERFACE_NAME, WifiNative.SCAN_TYPE_HIGH_ACCURACY, null, null));
    767         verify(mWifiScannerImpl).scan(argThat(new ScanMatcher(
    768                 IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY, null, null)));
    769     }
    770 
    771     /**
    772      * Verifies that Scan() can handle wificond scan failure.
    773      */
    774     @Test
    775     public void testScanFailure() throws Exception {
    776         when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(false);
    777         assertFalse(mWificondControl.scan(
    778                 TEST_INTERFACE_NAME, WifiNative.SCAN_TYPE_LOW_LATENCY,
    779                 SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_SET));
    780         verify(mWifiScannerImpl).scan(any(SingleScanSettings.class));
    781     }
    782 
    783     /**
    784      * Verifies that Scan() can handle invalid type.
    785      */
    786     @Test
    787     public void testScanFailureDueToInvalidType() throws Exception {
    788         assertFalse(mWificondControl.scan(
    789                 TEST_INTERFACE_NAME, 100,
    790                 SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_SET));
    791         verify(mWifiScannerImpl, never()).scan(any(SingleScanSettings.class));
    792     }
    793 
    794     /**
    795      * Verifies that startPnoScan() can convert input parameters to PnoSettings correctly.
    796      */
    797     @Test
    798     public void testStartPnoScan() throws Exception {
    799         when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(true);
    800         assertTrue(mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS));
    801         verify(mWifiScannerImpl).startPnoScan(argThat(new PnoScanMatcher(TEST_PNO_SETTINGS)));
    802     }
    803 
    804     /**
    805      * Verifies that stopPnoScan() calls underlying wificond.
    806      */
    807     @Test
    808     public void testStopPnoScan() throws Exception {
    809         when(mWifiScannerImpl.stopPnoScan()).thenReturn(true);
    810         assertTrue(mWificondControl.stopPnoScan(TEST_INTERFACE_NAME));
    811         verify(mWifiScannerImpl).stopPnoScan();
    812     }
    813 
    814     /**
    815      * Verifies that stopPnoScan() can handle wificond failure.
    816      */
    817     @Test
    818     public void testStopPnoScanFailure() throws Exception {
    819 
    820         when(mWifiScannerImpl.stopPnoScan()).thenReturn(false);
    821         assertFalse(mWificondControl.stopPnoScan(TEST_INTERFACE_NAME));
    822         verify(mWifiScannerImpl).stopPnoScan();
    823     }
    824 
    825     /**
    826      * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon scan
    827      * reuslt event.
    828      */
    829     @Test
    830     public void testScanResultEvent() throws Exception {
    831         ArgumentCaptor<IScanEvent> messageCaptor = ArgumentCaptor.forClass(IScanEvent.class);
    832         verify(mWifiScannerImpl).subscribeScanEvents(messageCaptor.capture());
    833         IScanEvent scanEvent = messageCaptor.getValue();
    834         assertNotNull(scanEvent);
    835         scanEvent.OnScanResultReady();
    836 
    837         verify(mWifiMonitor).broadcastScanResultEvent(any(String.class));
    838     }
    839 
    840     /**
    841      * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon scan
    842      * failed event.
    843      */
    844     @Test
    845     public void testScanFailedEvent() throws Exception {
    846 
    847         ArgumentCaptor<IScanEvent> messageCaptor = ArgumentCaptor.forClass(IScanEvent.class);
    848         verify(mWifiScannerImpl).subscribeScanEvents(messageCaptor.capture());
    849         IScanEvent scanEvent = messageCaptor.getValue();
    850         assertNotNull(scanEvent);
    851         scanEvent.OnScanFailed();
    852 
    853         verify(mWifiMonitor).broadcastScanFailedEvent(any(String.class));
    854     }
    855 
    856     /**
    857      * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon pno scan
    858      * result event.
    859      */
    860     @Test
    861     public void testPnoScanResultEvent() throws Exception {
    862         ArgumentCaptor<IPnoScanEvent> messageCaptor = ArgumentCaptor.forClass(IPnoScanEvent.class);
    863         verify(mWifiScannerImpl).subscribePnoScanEvents(messageCaptor.capture());
    864         IPnoScanEvent pnoScanEvent = messageCaptor.getValue();
    865         assertNotNull(pnoScanEvent);
    866         pnoScanEvent.OnPnoNetworkFound();
    867         verify(mWifiMonitor).broadcastPnoScanResultEvent(any(String.class));
    868     }
    869 
    870     /**
    871      * Verifies that WificondControl can invoke WifiMetrics pno scan count methods upon pno event.
    872      */
    873     @Test
    874     public void testPnoScanEventsForMetrics() throws Exception {
    875         ArgumentCaptor<IPnoScanEvent> messageCaptor = ArgumentCaptor.forClass(IPnoScanEvent.class);
    876         verify(mWifiScannerImpl).subscribePnoScanEvents(messageCaptor.capture());
    877         IPnoScanEvent pnoScanEvent = messageCaptor.getValue();
    878         assertNotNull(pnoScanEvent);
    879 
    880         pnoScanEvent.OnPnoNetworkFound();
    881         verify(mWifiMetrics).incrementPnoFoundNetworkEventCount();
    882 
    883         pnoScanEvent.OnPnoScanFailed();
    884         verify(mWifiMetrics).incrementPnoScanFailedCount();
    885 
    886         pnoScanEvent.OnPnoScanOverOffloadStarted();
    887         verify(mWifiMetrics).incrementPnoScanStartedOverOffloadCount();
    888 
    889         pnoScanEvent.OnPnoScanOverOffloadFailed(0);
    890         verify(mWifiMetrics).incrementPnoScanFailedOverOffloadCount();
    891     }
    892 
    893     /**
    894      * Verifies that startPnoScan() can invoke WifiMetrics pno scan count methods correctly.
    895      */
    896     @Test
    897     public void testStartPnoScanForMetrics() throws Exception {
    898         when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(false);
    899         assertFalse(mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS));
    900         verify(mWifiMetrics).incrementPnoScanStartAttempCount();
    901         verify(mWifiMetrics).incrementPnoScanFailedCount();
    902     }
    903 
    904     /**
    905      * Verifies that abortScan() calls underlying wificond.
    906      */
    907     @Test
    908     public void testAbortScan() throws Exception {
    909         mWificondControl.abortScan(TEST_INTERFACE_NAME);
    910         verify(mWifiScannerImpl).abortScan();
    911     }
    912 
    913     /**
    914      * Verifies successful soft ap start.
    915      */
    916     @Test
    917     public void testStartHostapdWithPskConfig() throws Exception {
    918         testSetupInterfaceForSoftApMode();
    919         when(mApInterface.startHostapd(any())).thenReturn(true);
    920 
    921         assertTrue(mWificondControl.startHostapd(
    922                 TEST_INTERFACE_NAME, mSoftApListener));
    923         verify(mApInterface).startHostapd(any());
    924     }
    925 
    926     /**
    927      * Ensures that the Ap interface callbacks are forwarded to the
    928      * SoftApListener used for starting soft AP.
    929      */
    930     @Test
    931     public void testSoftApListenerInvocation() throws Exception {
    932         testSetupInterfaceForSoftApMode();
    933 
    934         WifiConfiguration config = new WifiConfiguration();
    935         config.SSID = new String(TEST_SSID, StandardCharsets.UTF_8);
    936 
    937         when(mApInterface.startHostapd(any())).thenReturn(true);
    938 
    939         final ArgumentCaptor<IApInterfaceEventCallback> apInterfaceCallbackCaptor =
    940                 ArgumentCaptor.forClass(IApInterfaceEventCallback.class);
    941 
    942         assertTrue(mWificondControl.startHostapd(
    943                 TEST_INTERFACE_NAME, mSoftApListener));
    944         verify(mApInterface).startHostapd(apInterfaceCallbackCaptor.capture());
    945 
    946         int numStations = 5;
    947         apInterfaceCallbackCaptor.getValue().onNumAssociatedStationsChanged(numStations);
    948         verify(mSoftApListener).onNumAssociatedStationsChanged(eq(numStations));
    949 
    950         int channelFrequency = 2437;
    951         int channelBandwidth = IApInterfaceEventCallback.BANDWIDTH_20;
    952         apInterfaceCallbackCaptor.getValue().onSoftApChannelSwitched(channelFrequency,
    953                 channelBandwidth);
    954         verify(mSoftApListener).onSoftApChannelSwitched(eq(channelFrequency), eq(channelBandwidth));
    955     }
    956 
    957     /**
    958      * Ensure that soft ap start fails when the interface is not setup.
    959      */
    960     @Test
    961     public void testStartHostapdWithoutSetupInterface() throws Exception {
    962         assertFalse(mWificondControl.startHostapd(
    963                 TEST_INTERFACE_NAME, mSoftApListener));
    964         verify(mApInterface, never()).startHostapd(any());
    965     }
    966 
    967     /**
    968      * Verifies soft ap start failure.
    969      */
    970     @Test
    971     public void testStartHostapdFailDueToStartError() throws Exception {
    972         testSetupInterfaceForSoftApMode();
    973         WifiConfiguration config = new WifiConfiguration();
    974         config.SSID = new String(TEST_SSID, StandardCharsets.UTF_8);
    975 
    976         when(mApInterface.startHostapd(any())).thenReturn(false);
    977 
    978         assertFalse(mWificondControl.startHostapd(
    979                 TEST_INTERFACE_NAME, mSoftApListener));
    980         verify(mApInterface).startHostapd(any());
    981     }
    982 
    983     /**
    984      * Verifies soft ap start failure.
    985      */
    986     @Test
    987     public void testStartHostapdFailDueToExceptionInStart() throws Exception {
    988         testSetupInterfaceForSoftApMode();
    989         WifiConfiguration config = new WifiConfiguration();
    990         config.SSID = new String(TEST_SSID, StandardCharsets.UTF_8);
    991 
    992         doThrow(new RemoteException()).when(mApInterface).startHostapd(any());
    993 
    994         assertFalse(mWificondControl.startHostapd(
    995                 TEST_INTERFACE_NAME, mSoftApListener));
    996         verify(mApInterface).startHostapd(any());
    997     }
    998 
    999     /**
   1000      * Verifies soft ap stop success.
   1001      */
   1002     @Test
   1003     public void testStopSoftAp() throws Exception {
   1004         testSetupInterfaceForSoftApMode();
   1005 
   1006         when(mApInterface.stopHostapd()).thenReturn(true);
   1007 
   1008         assertTrue(mWificondControl.stopHostapd(TEST_INTERFACE_NAME));
   1009         verify(mApInterface).stopHostapd();
   1010     }
   1011 
   1012     /**
   1013      * Ensure that soft ap stop fails when the interface is not setup.
   1014      */
   1015     @Test
   1016     public void testStopSoftApWithOutSetupInterface() throws Exception {
   1017         when(mApInterface.stopHostapd()).thenReturn(true);
   1018         assertFalse(mWificondControl.stopHostapd(TEST_INTERFACE_NAME));
   1019         verify(mApInterface, never()).stopHostapd();
   1020     }
   1021 
   1022     /**
   1023      * Verifies soft ap stop failure.
   1024      */
   1025     @Test
   1026     public void testStopSoftApFailDueToStopError() throws Exception {
   1027         testSetupInterfaceForSoftApMode();
   1028 
   1029         when(mApInterface.stopHostapd()).thenReturn(false);
   1030 
   1031         assertFalse(mWificondControl.stopHostapd(TEST_INTERFACE_NAME));
   1032         verify(mApInterface).stopHostapd();
   1033     }
   1034 
   1035     /**
   1036      * Verifies soft ap stop failure.
   1037      */
   1038     @Test
   1039     public void testStopSoftApFailDueToExceptionInStop() throws Exception {
   1040         testSetupInterfaceForSoftApMode();
   1041 
   1042         doThrow(new RemoteException()).when(mApInterface).stopHostapd();
   1043 
   1044         assertFalse(mWificondControl.stopHostapd(TEST_INTERFACE_NAME));
   1045         verify(mApInterface).stopHostapd();
   1046     }
   1047 
   1048     /**
   1049      * Verifies registration and invocation of wificond death handler.
   1050      */
   1051     @Test
   1052     public void testRegisterDeathHandler() throws Exception {
   1053         WifiNative.WificondDeathEventHandler handler =
   1054                 mock(WifiNative.WificondDeathEventHandler.class);
   1055         assertTrue(mWificondControl.initialize(handler));
   1056         verify(mWificond).tearDownInterfaces();
   1057         mWificondControl.binderDied();
   1058         verify(handler).onDeath();
   1059     }
   1060 
   1061     /**
   1062      * Verifies handling of wificond death and ensures that all internal state is cleared and
   1063      * handlers are invoked.
   1064      */
   1065     @Test
   1066     public void testDeathHandling() throws Exception {
   1067         WifiNative.WificondDeathEventHandler handler =
   1068                 mock(WifiNative.WificondDeathEventHandler.class);
   1069         assertTrue(mWificondControl.initialize(handler));
   1070 
   1071         testSetupInterfaceForClientMode();
   1072 
   1073         mWificondControl.binderDied();
   1074         verify(handler).onDeath();
   1075 
   1076         // The handles should be cleared after death, so these should retrieve new handles.
   1077         when(mWificond.enableSupplicant()).thenReturn(true);
   1078         assertTrue(mWificondControl.enableSupplicant());
   1079         verify(mWifiInjector, times(2)).makeWificond();
   1080         verify(mWificond).enableSupplicant();
   1081     }
   1082 
   1083     /**
   1084      * Verifies setMacAddress() success.
   1085      */
   1086     @Test
   1087     public void testSetMacAddressSuccess() throws Exception {
   1088         byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray();
   1089         assertTrue(mWificondControl.setMacAddress(TEST_INTERFACE_NAME, TEST_MAC_ADDRESS));
   1090         verify(mClientInterface).setMacAddress(macByteArray);
   1091     }
   1092 
   1093     /**
   1094      * Verifies setMacAddress() can handle failure.
   1095      */
   1096     @Test
   1097     public void testSetMacAddressFailDueToExceptionInInterface() throws Exception {
   1098         byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray();
   1099         doThrow(new RemoteException()).when(mClientInterface).setMacAddress(macByteArray);
   1100         assertFalse(mWificondControl.setMacAddress(TEST_INTERFACE_NAME, TEST_MAC_ADDRESS));
   1101         verify(mClientInterface).setMacAddress(macByteArray);
   1102     }
   1103 
   1104     private void assertRadioChainInfosEqual(
   1105             List<RadioChainInfo> expected, android.net.wifi.ScanResult.RadioChainInfo[] actual) {
   1106         assertEquals(expected.size(), actual.length);
   1107         for (int i = 0; i < actual.length; i++) {
   1108             RadioChainInfo nativeRadioChainInfo =
   1109                     new RadioChainInfo(actual[i].id, actual[i].level);
   1110             assertTrue(expected.contains(nativeRadioChainInfo));
   1111         }
   1112     }
   1113 
   1114     // Create a ArgumentMatcher which captures a SingleScanSettings parameter and checks if it
   1115     // matches the provided frequency set and ssid set.
   1116     private class ScanMatcher implements ArgumentMatcher<SingleScanSettings> {
   1117         int mExpectedScanType;
   1118         private final Set<Integer> mExpectedFreqs;
   1119         private final Set<String> mExpectedSsids;
   1120         ScanMatcher(int expectedScanType, Set<Integer> expectedFreqs, Set<String> expectedSsids) {
   1121             this.mExpectedScanType = expectedScanType;
   1122             this.mExpectedFreqs = expectedFreqs;
   1123             this.mExpectedSsids = expectedSsids;
   1124         }
   1125 
   1126         @Override
   1127         public boolean matches(SingleScanSettings settings) {
   1128             if (settings.scanType != mExpectedScanType) {
   1129                 return false;
   1130             }
   1131             ArrayList<ChannelSettings> channelSettings = settings.channelSettings;
   1132             ArrayList<HiddenNetwork> hiddenNetworks = settings.hiddenNetworks;
   1133             if (mExpectedFreqs != null) {
   1134                 Set<Integer> freqSet = new HashSet<Integer>();
   1135                 for (ChannelSettings channel : channelSettings) {
   1136                     freqSet.add(channel.frequency);
   1137                 }
   1138                 if (!mExpectedFreqs.equals(freqSet)) {
   1139                     return false;
   1140                 }
   1141             } else {
   1142                 if (channelSettings != null && channelSettings.size() > 0) {
   1143                     return false;
   1144                 }
   1145             }
   1146 
   1147             if (mExpectedSsids != null) {
   1148                 Set<String> ssidSet = new HashSet<String>();
   1149                 for (HiddenNetwork network : hiddenNetworks) {
   1150                     ssidSet.add(NativeUtil.encodeSsid(
   1151                             NativeUtil.byteArrayToArrayList(network.ssid)));
   1152                 }
   1153                 if (!mExpectedSsids.equals(ssidSet)) {
   1154                     return false;
   1155                 }
   1156 
   1157             } else {
   1158                 if (hiddenNetworks != null && hiddenNetworks.size() > 0) {
   1159                     return false;
   1160                 }
   1161             }
   1162             return true;
   1163         }
   1164 
   1165         @Override
   1166         public String toString() {
   1167             return "ScanMatcher{mExpectedFreqs=" + mExpectedFreqs
   1168                     + ", mExpectedSsids=" + mExpectedSsids + '}';
   1169         }
   1170     }
   1171 
   1172     // Create a ArgumentMatcher which captures a PnoSettings parameter and checks if it
   1173     // matches the WifiNative.PnoSettings;
   1174     private class PnoScanMatcher implements ArgumentMatcher<PnoSettings> {
   1175         private final WifiNative.PnoSettings mExpectedPnoSettings;
   1176         PnoScanMatcher(WifiNative.PnoSettings expectedPnoSettings) {
   1177             this.mExpectedPnoSettings = expectedPnoSettings;
   1178         }
   1179         @Override
   1180         public boolean matches(PnoSettings settings) {
   1181             if (mExpectedPnoSettings == null) {
   1182                 return false;
   1183             }
   1184             if (settings.intervalMs != mExpectedPnoSettings.periodInMs
   1185                     || settings.min2gRssi != mExpectedPnoSettings.min24GHzRssi
   1186                     || settings.min5gRssi != mExpectedPnoSettings.min5GHzRssi) {
   1187                 return false;
   1188             }
   1189             if (settings.pnoNetworks == null || mExpectedPnoSettings.networkList == null) {
   1190                 return false;
   1191             }
   1192             if (settings.pnoNetworks.size() != mExpectedPnoSettings.networkList.length) {
   1193                 return false;
   1194             }
   1195 
   1196             for (int i = 0; i < settings.pnoNetworks.size(); i++) {
   1197                 if (!mExpectedPnoSettings.networkList[i].ssid.equals(NativeUtil.encodeSsid(
   1198                          NativeUtil.byteArrayToArrayList(settings.pnoNetworks.get(i).ssid)))) {
   1199                     return false;
   1200                 }
   1201                 boolean isNetworkHidden = (mExpectedPnoSettings.networkList[i].flags
   1202                         & WifiScanner.PnoSettings.PnoNetwork.FLAG_DIRECTED_SCAN) != 0;
   1203                 if (isNetworkHidden != settings.pnoNetworks.get(i).isHidden) {
   1204                     return false;
   1205                 }
   1206 
   1207             }
   1208             return true;
   1209         }
   1210 
   1211         @Override
   1212         public String toString() {
   1213             return "PnoScanMatcher{" + "mExpectedPnoSettings=" + mExpectedPnoSettings + '}';
   1214         }
   1215     }
   1216 }
   1217