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 com.android.server.wifi.HalDeviceManager.START_HAL_RETRY_TIMES;
     20 
     21 import static junit.framework.Assert.assertEquals;
     22 
     23 import static org.hamcrest.core.IsEqual.equalTo;
     24 import static org.junit.Assert.assertFalse;
     25 import static org.junit.Assert.assertTrue;
     26 import static org.mockito.Matchers.any;
     27 import static org.mockito.Matchers.anyInt;
     28 import static org.mockito.Matchers.anyLong;
     29 import static org.mockito.Matchers.anyString;
     30 import static org.mockito.Matchers.eq;
     31 import static org.mockito.Mockito.doAnswer;
     32 import static org.mockito.Mockito.inOrder;
     33 import static org.mockito.Mockito.mock;
     34 import static org.mockito.Mockito.times;
     35 import static org.mockito.Mockito.verify;
     36 import static org.mockito.Mockito.verifyNoMoreInteractions;
     37 import static org.mockito.Mockito.when;
     38 
     39 import android.app.test.MockAnswerUtil;
     40 import android.hardware.wifi.V1_0.IWifi;
     41 import android.hardware.wifi.V1_0.IWifiApIface;
     42 import android.hardware.wifi.V1_0.IWifiChip;
     43 import android.hardware.wifi.V1_0.IWifiChipEventCallback;
     44 import android.hardware.wifi.V1_0.IWifiEventCallback;
     45 import android.hardware.wifi.V1_0.IWifiIface;
     46 import android.hardware.wifi.V1_0.IWifiNanIface;
     47 import android.hardware.wifi.V1_0.IWifiP2pIface;
     48 import android.hardware.wifi.V1_0.IWifiStaIface;
     49 import android.hardware.wifi.V1_0.IfaceType;
     50 import android.hardware.wifi.V1_0.WifiStatus;
     51 import android.hardware.wifi.V1_0.WifiStatusCode;
     52 import android.hidl.manager.V1_0.IServiceManager;
     53 import android.hidl.manager.V1_0.IServiceNotification;
     54 import android.os.IHwBinder;
     55 import android.os.test.TestLooper;
     56 import android.util.Log;
     57 
     58 import org.hamcrest.core.IsNull;
     59 import org.junit.After;
     60 import org.junit.Before;
     61 import org.junit.Rule;
     62 import org.junit.Test;
     63 import org.junit.rules.ErrorCollector;
     64 import org.mockito.ArgumentCaptor;
     65 import org.mockito.InOrder;
     66 import org.mockito.Mock;
     67 import org.mockito.MockitoAnnotations;
     68 
     69 import java.io.PrintWriter;
     70 import java.io.StringWriter;
     71 import java.util.ArrayList;
     72 import java.util.HashMap;
     73 import java.util.HashSet;
     74 import java.util.Map;
     75 import java.util.Set;
     76 
     77 /**
     78  * Unit test harness for HalDeviceManagerTest.
     79  */
     80 public class HalDeviceManagerTest {
     81     private HalDeviceManager mDut;
     82     @Mock IServiceManager mServiceManagerMock;
     83     @Mock IWifi mWifiMock;
     84     @Mock HalDeviceManager.ManagerStatusListener mManagerStatusListenerMock;
     85     private TestLooper mTestLooper;
     86     private ArgumentCaptor<IHwBinder.DeathRecipient> mDeathRecipientCaptor =
     87             ArgumentCaptor.forClass(IHwBinder.DeathRecipient.class);
     88     private ArgumentCaptor<IServiceNotification.Stub> mServiceNotificationCaptor =
     89             ArgumentCaptor.forClass(IServiceNotification.Stub.class);
     90     private ArgumentCaptor<IWifiEventCallback> mWifiEventCallbackCaptor = ArgumentCaptor.forClass(
     91             IWifiEventCallback.class);
     92     private InOrder mInOrder;
     93     @Rule public ErrorCollector collector = new ErrorCollector();
     94     private WifiStatus mStatusOk;
     95     private WifiStatus mStatusFail;
     96 
     97     private class HalDeviceManagerSpy extends HalDeviceManager {
     98         @Override
     99         protected IWifi getWifiServiceMockable() {
    100             return mWifiMock;
    101         }
    102 
    103         @Override
    104         protected IServiceManager getServiceManagerMockable() {
    105             return mServiceManagerMock;
    106         }
    107     }
    108 
    109     @Before
    110     public void before() throws Exception {
    111         MockitoAnnotations.initMocks(this);
    112 
    113         mTestLooper = new TestLooper();
    114 
    115         // initialize dummy status objects
    116         mStatusOk = getStatus(WifiStatusCode.SUCCESS);
    117         mStatusFail = getStatus(WifiStatusCode.ERROR_UNKNOWN);
    118 
    119         when(mServiceManagerMock.linkToDeath(any(IHwBinder.DeathRecipient.class),
    120                 anyLong())).thenReturn(true);
    121         when(mServiceManagerMock.registerForNotifications(anyString(), anyString(),
    122                 any(IServiceNotification.Stub.class))).thenReturn(true);
    123         when(mWifiMock.linkToDeath(any(IHwBinder.DeathRecipient.class), anyLong())).thenReturn(
    124                 true);
    125         when(mWifiMock.registerEventCallback(any(IWifiEventCallback.class))).thenReturn(mStatusOk);
    126         when(mWifiMock.start()).thenReturn(mStatusOk);
    127         when(mWifiMock.stop()).thenReturn(mStatusOk);
    128 
    129         mDut = new HalDeviceManagerSpy();
    130     }
    131 
    132     /**
    133      * Print out the dump of the device manager after each test. Not used in test validation
    134      * (internal state) - but can help in debugging failed tests.
    135      */
    136     @After
    137     public void after() throws Exception {
    138         dumpDut("after: ");
    139     }
    140 
    141     /**
    142      * Test basic startup flow:
    143      * - IServiceManager registrations
    144      * - IWifi registrations
    145      * - IWifi startup delayed
    146      * - Start Wi-Fi -> onStart
    147      * - Stop Wi-Fi -> onStop
    148      */
    149     @Test
    150     public void testStartStopFlow() throws Exception {
    151         mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock);
    152         executeAndValidateInitializationSequence();
    153         executeAndValidateStartupSequence();
    154 
    155         // act: stop Wi-Fi
    156         mDut.stop();
    157         mTestLooper.dispatchAll();
    158 
    159         // verify: onStop called
    160         mInOrder.verify(mWifiMock).stop();
    161         mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
    162 
    163         verifyNoMoreInteractions(mManagerStatusListenerMock);
    164     }
    165 
    166     /**
    167      * Validate that multiple callback registrations are called and that duplicate ones are
    168      * only called once.
    169      */
    170     @Test
    171     public void testMultipleCallbackRegistrations() throws Exception {
    172         mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock);
    173         executeAndValidateInitializationSequence();
    174 
    175         // register another 2 callbacks - one of them twice
    176         HalDeviceManager.ManagerStatusListener callback1 = mock(
    177                 HalDeviceManager.ManagerStatusListener.class);
    178         HalDeviceManager.ManagerStatusListener callback2 = mock(
    179                 HalDeviceManager.ManagerStatusListener.class);
    180         mDut.registerStatusListener(callback2, mTestLooper.getLooper());
    181         mDut.registerStatusListener(callback1, mTestLooper.getLooper());
    182         mDut.registerStatusListener(callback2, mTestLooper.getLooper());
    183 
    184         // startup
    185         executeAndValidateStartupSequence();
    186 
    187         // verify
    188         verify(callback1).onStatusChanged();
    189         verify(callback2).onStatusChanged();
    190 
    191         verifyNoMoreInteractions(mManagerStatusListenerMock, callback1, callback2);
    192     }
    193 
    194     /**
    195      * Validate IWifi death listener and registration flow.
    196      */
    197     @Test
    198     public void testWifiDeathAndRegistration() throws Exception {
    199         mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock);
    200         executeAndValidateInitializationSequence();
    201         executeAndValidateStartupSequence();
    202 
    203         // act: IWifi service death
    204         mDeathRecipientCaptor.getValue().serviceDied(0);
    205         mTestLooper.dispatchAll();
    206 
    207         // verify: getting onStop
    208         mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
    209 
    210         // act: service startup
    211         mServiceNotificationCaptor.getValue().onRegistration(IWifi.kInterfaceName, "", false);
    212 
    213         // verify: initialization of IWifi
    214         mInOrder.verify(mWifiMock).linkToDeath(mDeathRecipientCaptor.capture(), anyLong());
    215         mInOrder.verify(mWifiMock).registerEventCallback(mWifiEventCallbackCaptor.capture());
    216 
    217         // act: start
    218         collector.checkThat(mDut.start(), equalTo(true));
    219         mWifiEventCallbackCaptor.getValue().onStart();
    220         mTestLooper.dispatchAll();
    221 
    222         // verify: service and callback calls
    223         mInOrder.verify(mWifiMock).start();
    224         mInOrder.verify(mManagerStatusListenerMock, times(3)).onStatusChanged();
    225 
    226         verifyNoMoreInteractions(mManagerStatusListenerMock);
    227     }
    228 
    229     /**
    230      * Validate IWifi onFailure causes notification
    231      */
    232     @Test
    233     public void testWifiFail() throws Exception {
    234         mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock);
    235         executeAndValidateInitializationSequence();
    236         executeAndValidateStartupSequence();
    237 
    238         // act: IWifi failure
    239         mWifiEventCallbackCaptor.getValue().onFailure(mStatusFail);
    240         mTestLooper.dispatchAll();
    241 
    242         // verify: getting onStop
    243         mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
    244 
    245         // act: start again
    246         collector.checkThat(mDut.start(), equalTo(true));
    247         mWifiEventCallbackCaptor.getValue().onStart();
    248         mTestLooper.dispatchAll();
    249 
    250         // verify: service and callback calls
    251         mInOrder.verify(mWifiMock).start();
    252         mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
    253 
    254         verifyNoMoreInteractions(mManagerStatusListenerMock);
    255     }
    256 
    257     /**
    258      * Validate creation of STA interface from blank start-up. The remove interface.
    259      */
    260     @Test
    261     public void testCreateStaInterfaceNoInitMode() throws Exception {
    262         final String name = "sta0";
    263 
    264         BaselineChip chipMock = new BaselineChip();
    265         chipMock.initialize();
    266         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
    267                 mManagerStatusListenerMock);
    268         executeAndValidateInitializationSequence();
    269         executeAndValidateStartupSequence();
    270 
    271         HalDeviceManager.InterfaceDestroyedListener idl = mock(
    272                 HalDeviceManager.InterfaceDestroyedListener.class);
    273         HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
    274                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
    275 
    276         IWifiStaIface iface = (IWifiStaIface) validateInterfaceSequence(chipMock,
    277                 false, // chipModeValid
    278                 -1000, // chipModeId (only used if chipModeValid is true)
    279                 IfaceType.STA, // ifaceTypeToCreate
    280                 name, // ifaceName
    281                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
    282                 null, // tearDownList
    283                 idl, // destroyedListener
    284                 iafrl // availableListener
    285         );
    286         collector.checkThat("allocated interface", iface, IsNull.notNullValue());
    287 
    288         // act: remove interface
    289         mDut.removeIface(iface);
    290         mTestLooper.dispatchAll();
    291 
    292         // verify: callback triggered
    293         mInOrder.verify(chipMock.chip).removeStaIface(name);
    294         verify(idl).onDestroyed();
    295         verify(iafrl).onAvailableForRequest();
    296 
    297         verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl);
    298     }
    299 
    300     /**
    301      * Validate creation of AP interface from blank start-up. The remove interface.
    302      */
    303     @Test
    304     public void testCreateApInterfaceNoInitMode() throws Exception {
    305         final String name = "ap0";
    306 
    307         BaselineChip chipMock = new BaselineChip();
    308         chipMock.initialize();
    309         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
    310                 mManagerStatusListenerMock);
    311         executeAndValidateInitializationSequence();
    312         executeAndValidateStartupSequence();
    313 
    314         HalDeviceManager.InterfaceDestroyedListener idl = mock(
    315                 HalDeviceManager.InterfaceDestroyedListener.class);
    316         HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
    317                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
    318 
    319         IWifiApIface iface = (IWifiApIface) validateInterfaceSequence(chipMock,
    320                 false, // chipModeValid
    321                 -1000, // chipModeId (only used if chipModeValid is true)
    322                 IfaceType.AP, // ifaceTypeToCreate
    323                 name, // ifaceName
    324                 BaselineChip.AP_CHIP_MODE_ID, // finalChipMode
    325                 null, // tearDownList
    326                 idl, // destroyedListener
    327                 iafrl // availableListener
    328         );
    329         collector.checkThat("allocated interface", iface, IsNull.notNullValue());
    330 
    331         // act: remove interface
    332         mDut.removeIface(iface);
    333         mTestLooper.dispatchAll();
    334 
    335         // verify: callback triggered
    336         mInOrder.verify(chipMock.chip).removeApIface(name);
    337         verify(idl).onDestroyed();
    338         verify(iafrl).onAvailableForRequest();
    339 
    340         verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl);
    341     }
    342 
    343     /**
    344      * Validate creation of P2P interface from blank start-up. The remove interface.
    345      */
    346     @Test
    347     public void testCreateP2pInterfaceNoInitMode() throws Exception {
    348         final String name = "p2p0";
    349 
    350         BaselineChip chipMock = new BaselineChip();
    351         chipMock.initialize();
    352         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
    353                 mManagerStatusListenerMock);
    354         executeAndValidateInitializationSequence();
    355         executeAndValidateStartupSequence();
    356 
    357         HalDeviceManager.InterfaceDestroyedListener idl = mock(
    358                 HalDeviceManager.InterfaceDestroyedListener.class);
    359         HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
    360                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
    361 
    362         IWifiP2pIface iface = (IWifiP2pIface) validateInterfaceSequence(chipMock,
    363                 false, // chipModeValid
    364                 -1000, // chipModeId (only used if chipModeValid is true)
    365                 IfaceType.P2P, // ifaceTypeToCreate
    366                 name, // ifaceName
    367                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
    368                 null, // tearDownList
    369                 idl, // destroyedListener
    370                 iafrl // availableListener
    371         );
    372         collector.checkThat("allocated interface", iface, IsNull.notNullValue());
    373 
    374         // act: remove interface
    375         mDut.removeIface(iface);
    376         mTestLooper.dispatchAll();
    377 
    378         // verify: callback triggered
    379         mInOrder.verify(chipMock.chip).removeP2pIface(name);
    380         verify(idl).onDestroyed();
    381         verify(iafrl).onAvailableForRequest();
    382 
    383         verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl);
    384     }
    385 
    386     /**
    387      * Validate creation of NAN interface from blank start-up. The remove interface.
    388      */
    389     @Test
    390     public void testCreateNanInterfaceNoInitMode() throws Exception {
    391         final String name = "nan0";
    392 
    393         BaselineChip chipMock = new BaselineChip();
    394         chipMock.initialize();
    395         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
    396                 mManagerStatusListenerMock);
    397         executeAndValidateInitializationSequence();
    398         executeAndValidateStartupSequence();
    399 
    400         HalDeviceManager.InterfaceDestroyedListener idl = mock(
    401                 HalDeviceManager.InterfaceDestroyedListener.class);
    402         HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
    403                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
    404 
    405         IWifiNanIface iface = (IWifiNanIface) validateInterfaceSequence(chipMock,
    406                 false, // chipModeValid
    407                 -1000, // chipModeId (only used if chipModeValid is true)
    408                 IfaceType.NAN, // ifaceTypeToCreate
    409                 name, // ifaceName
    410                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
    411                 null, // tearDownList
    412                 idl, // destroyedListener
    413                 iafrl // availableListener
    414         );
    415         collector.checkThat("allocated interface", iface, IsNull.notNullValue());
    416 
    417         // act: remove interface
    418         mDut.removeIface(iface);
    419         mTestLooper.dispatchAll();
    420 
    421         // verify: callback triggered
    422         mInOrder.verify(chipMock.chip).removeNanIface(name);
    423         verify(idl).onDestroyed();
    424         verify(iafrl).onAvailableForRequest();
    425 
    426         verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl);
    427     }
    428 
    429     /**
    430      * Validate creation of AP interface when in STA mode - but with no interface created. Expect
    431      * a change in chip mode.
    432      */
    433     @Test
    434     public void testCreateApWithStaModeUp() throws Exception {
    435         final String name = "ap0";
    436 
    437         BaselineChip chipMock = new BaselineChip();
    438         chipMock.initialize();
    439         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
    440                 mManagerStatusListenerMock);
    441         executeAndValidateInitializationSequence();
    442         executeAndValidateStartupSequence();
    443 
    444         HalDeviceManager.InterfaceDestroyedListener idl = mock(
    445                 HalDeviceManager.InterfaceDestroyedListener.class);
    446         HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
    447                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
    448 
    449         IWifiApIface iface = (IWifiApIface) validateInterfaceSequence(chipMock,
    450                 true, // chipModeValid
    451                 BaselineChip.STA_CHIP_MODE_ID, // chipModeId
    452                 IfaceType.AP, // ifaceTypeToCreate
    453                 name, // ifaceName
    454                 BaselineChip.AP_CHIP_MODE_ID, // finalChipMode
    455                 null, // tearDownList
    456                 idl, // destroyedListener
    457                 iafrl // availableListener
    458         );
    459         collector.checkThat("allocated interface", iface, IsNull.notNullValue());
    460 
    461         // act: stop Wi-Fi
    462         mDut.stop();
    463         mTestLooper.dispatchAll();
    464 
    465         // verify: callback triggered
    466         verify(idl).onDestroyed();
    467         verify(mManagerStatusListenerMock, times(2)).onStatusChanged();
    468 
    469         verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl);
    470     }
    471 
    472     /**
    473      * Validate creation of AP interface when in AP mode - but with no interface created. Expect
    474      * no change in chip mode.
    475      */
    476     @Test
    477     public void testCreateApWithApModeUp() throws Exception {
    478         final String name = "ap0";
    479 
    480         BaselineChip chipMock = new BaselineChip();
    481         chipMock.initialize();
    482         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
    483                 mManagerStatusListenerMock);
    484         executeAndValidateInitializationSequence();
    485         executeAndValidateStartupSequence();
    486 
    487         HalDeviceManager.InterfaceDestroyedListener idl = mock(
    488                 HalDeviceManager.InterfaceDestroyedListener.class);
    489         HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
    490                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
    491 
    492         IWifiApIface iface = (IWifiApIface) validateInterfaceSequence(chipMock,
    493                 true, // chipModeValid
    494                 BaselineChip.AP_CHIP_MODE_ID, // chipModeId
    495                 IfaceType.AP, // ifaceTypeToCreate
    496                 name, // ifaceName
    497                 BaselineChip.AP_CHIP_MODE_ID, // finalChipMode
    498                 null, // tearDownList
    499                 idl, // destroyedListener
    500                 iafrl // availableListener
    501         );
    502         collector.checkThat("allocated interface", iface, IsNull.notNullValue());
    503 
    504         // act: stop Wi-Fi
    505         mDut.stop();
    506         mTestLooper.dispatchAll();
    507 
    508         // verify: callback triggered
    509         verify(idl).onDestroyed();
    510         verify(mManagerStatusListenerMock, times(2)).onStatusChanged();
    511 
    512         verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl);
    513     }
    514 
    515     /**
    516      * Validate AP up/down creation of AP interface when a STA already created. Expect:
    517      * - STA created
    518      * - P2P created
    519      * - When AP requested:
    520      *   - STA & P2P torn down
    521      *   - AP created
    522      * - P2P creation refused
    523      * - Request STA: will tear down AP
    524      * - When AP destroyed:
    525      *   - Get p2p available listener callback
    526      *   - Can create P2P when requested
    527      * - Create P2P
    528      * - Request NAN: will get refused
    529      * - Tear down P2P:
    530      *    - should get nan available listener callback
    531      *    - Can create NAN when requested
    532      */
    533     @Test
    534     public void testCreateSameAndDiffPriorities() throws Exception {
    535         BaselineChip chipMock = new BaselineChip();
    536         chipMock.initialize();
    537         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
    538                 mManagerStatusListenerMock);
    539         executeAndValidateInitializationSequence();
    540         executeAndValidateStartupSequence();
    541 
    542         HalDeviceManager.InterfaceDestroyedListener staDestroyedListener = mock(
    543                 HalDeviceManager.InterfaceDestroyedListener.class);
    544         HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
    545                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
    546 
    547         HalDeviceManager.InterfaceDestroyedListener staDestroyedListener2 = mock(
    548                 HalDeviceManager.InterfaceDestroyedListener.class);
    549 
    550         HalDeviceManager.InterfaceDestroyedListener apDestroyedListener = mock(
    551                 HalDeviceManager.InterfaceDestroyedListener.class);
    552         HalDeviceManager.InterfaceAvailableForRequestListener apAvailListener = mock(
    553                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
    554 
    555         HalDeviceManager.InterfaceDestroyedListener p2pDestroyedListener = mock(
    556                 HalDeviceManager.InterfaceDestroyedListener.class);
    557         HalDeviceManager.InterfaceAvailableForRequestListener p2pAvailListener = mock(
    558                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
    559 
    560         HalDeviceManager.InterfaceDestroyedListener p2pDestroyedListener2 = mock(
    561                 HalDeviceManager.InterfaceDestroyedListener.class);
    562 
    563         HalDeviceManager.InterfaceDestroyedListener nanDestroyedListener = mock(
    564                 HalDeviceManager.InterfaceDestroyedListener.class);
    565         HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock(
    566                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
    567 
    568         // Request STA
    569         IWifiIface staIface = validateInterfaceSequence(chipMock,
    570                 false, // chipModeValid
    571                 -1000, // chipModeId (only used if chipModeValid is true)
    572                 IfaceType.STA, // ifaceTypeToCreate
    573                 "sta0", // ifaceName
    574                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
    575                 null, // tearDownList
    576                 staDestroyedListener, // destroyedListener
    577                 staAvailListener // availableListener
    578         );
    579         collector.checkThat("allocated STA interface", staIface, IsNull.notNullValue());
    580 
    581         // register additional InterfaceDestroyedListeners - including a duplicate (verify that
    582         // only called once!)
    583         mDut.registerDestroyedListener(staIface, staDestroyedListener2, mTestLooper.getLooper());
    584         mDut.registerDestroyedListener(staIface, staDestroyedListener, mTestLooper.getLooper());
    585 
    586         // Request P2P
    587         IWifiIface p2pIface = validateInterfaceSequence(chipMock,
    588                 true, // chipModeValid
    589                 BaselineChip.STA_CHIP_MODE_ID, // chipModeId
    590                 IfaceType.P2P, // ifaceTypeToCreate
    591                 "p2p0", // ifaceName
    592                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
    593                 null, // tearDownList
    594                 p2pDestroyedListener, // destroyedListener
    595                 p2pAvailListener // availableListener
    596         );
    597         collector.checkThat("allocated P2P interface", p2pIface, IsNull.notNullValue());
    598 
    599         // Request AP
    600         IWifiIface apIface = validateInterfaceSequence(chipMock,
    601                 true, // chipModeValid
    602                 BaselineChip.STA_CHIP_MODE_ID, // chipModeId
    603                 IfaceType.AP, // ifaceTypeToCreate
    604                 "ap0", // ifaceName
    605                 BaselineChip.AP_CHIP_MODE_ID, // finalChipMode
    606                 new IWifiIface[]{staIface, p2pIface}, // tearDownList
    607                 apDestroyedListener, // destroyedListener
    608                 apAvailListener, // availableListener
    609                 // destroyedInterfacesDestroyedListeners...
    610                 staDestroyedListener, staDestroyedListener2, p2pDestroyedListener
    611         );
    612         collector.checkThat("allocated AP interface", apIface, IsNull.notNullValue());
    613 
    614         // Request P2P: expect failure
    615         p2pIface = mDut.createP2pIface(p2pDestroyedListener, mTestLooper.getLooper());
    616         collector.checkThat("P2P can't be created", p2pIface, IsNull.nullValue());
    617 
    618         // Request STA: expect success
    619         staIface = validateInterfaceSequence(chipMock,
    620                 true, // chipModeValid
    621                 BaselineChip.AP_CHIP_MODE_ID, // chipModeId
    622                 IfaceType.STA, // ifaceTypeToCreate
    623                 "sta0", // ifaceName
    624                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
    625                 null, // tearDownList
    626                 staDestroyedListener, // destroyedListener
    627                 staAvailListener, // availableListener
    628                 apDestroyedListener // destroyedInterfacesDestroyedListeners...
    629         );
    630         collector.checkThat("allocated STA interface", staIface, IsNull.notNullValue());
    631 
    632         mTestLooper.dispatchAll();
    633         verify(apDestroyedListener).onDestroyed();
    634 
    635         // Request P2P: expect success now
    636         p2pIface = validateInterfaceSequence(chipMock,
    637                 true, // chipModeValid
    638                 BaselineChip.STA_CHIP_MODE_ID, // chipModeId
    639                 IfaceType.P2P, // ifaceTypeToCreate
    640                 "p2p0", // ifaceName
    641                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
    642                 null, // tearDownList
    643                 p2pDestroyedListener2, // destroyedListener
    644                 p2pAvailListener // availableListener
    645         );
    646 
    647         // Request NAN: should fail
    648         IWifiIface nanIface = mDut.createNanIface(nanDestroyedListener, mTestLooper.getLooper());
    649         mDut.registerInterfaceAvailableForRequestListener(IfaceType.NAN, nanAvailListener,
    650                 mTestLooper.getLooper());
    651         collector.checkThat("NAN can't be created", nanIface, IsNull.nullValue());
    652 
    653         // Tear down P2P
    654         mDut.removeIface(p2pIface);
    655         mTestLooper.dispatchAll();
    656 
    657         verify(chipMock.chip, times(2)).removeP2pIface("p2p0");
    658         verify(p2pDestroyedListener2).onDestroyed();
    659 
    660         // Should now be able to request and get NAN
    661         nanIface = validateInterfaceSequence(chipMock,
    662                 true, // chipModeValid
    663                 BaselineChip.STA_CHIP_MODE_ID, // chipModeId
    664                 IfaceType.NAN, // ifaceTypeToCreate
    665                 "nan0", // ifaceName
    666                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
    667                 null, // tearDownList
    668                 nanDestroyedListener, // destroyedListener
    669                 nanAvailListener // availableListener
    670         );
    671         collector.checkThat("allocated NAN interface", nanIface, IsNull.notNullValue());
    672 
    673         // available callback verification
    674         verify(staAvailListener).onAvailableForRequest();
    675         verify(apAvailListener, times(4)).onAvailableForRequest();
    676         verify(p2pAvailListener, times(3)).onAvailableForRequest();
    677         verify(nanAvailListener).onAvailableForRequest();
    678 
    679         verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener, staAvailListener,
    680                 staDestroyedListener2, apDestroyedListener, apAvailListener, p2pDestroyedListener,
    681                 nanDestroyedListener, nanAvailListener, p2pDestroyedListener2);
    682     }
    683 
    684     /**
    685      * Validate P2P and NAN interactions. Expect:
    686      * - STA created
    687      * - NAN created
    688      * - When P2P requested:
    689      *   - NAN torn down
    690      *   - P2P created
    691      * - NAN creation refused
    692      * - When P2P destroyed:
    693      *   - get nan available listener
    694      *   - Can create NAN when requested
    695      */
    696     @Test
    697     public void testP2pAndNanInteractions() throws Exception {
    698         BaselineChip chipMock = new BaselineChip();
    699         chipMock.initialize();
    700         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
    701                 mManagerStatusListenerMock);
    702         executeAndValidateInitializationSequence();
    703         executeAndValidateStartupSequence();
    704 
    705         HalDeviceManager.InterfaceDestroyedListener staDestroyedListener = mock(
    706                 HalDeviceManager.InterfaceDestroyedListener.class);
    707         HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
    708                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
    709 
    710         HalDeviceManager.InterfaceDestroyedListener nanDestroyedListener = mock(
    711                 HalDeviceManager.InterfaceDestroyedListener.class);
    712         HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock(
    713                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
    714 
    715         HalDeviceManager.InterfaceDestroyedListener p2pDestroyedListener = mock(
    716                 HalDeviceManager.InterfaceDestroyedListener.class);
    717         HalDeviceManager.InterfaceAvailableForRequestListener p2pAvailListener = null;
    718 
    719         // Request STA
    720         IWifiIface staIface = validateInterfaceSequence(chipMock,
    721                 false, // chipModeValid
    722                 -1000, // chipModeId (only used if chipModeValid is true)
    723                 IfaceType.STA, // ifaceTypeToCreate
    724                 "sta0", // ifaceName
    725                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
    726                 null, // tearDownList
    727                 staDestroyedListener, // destroyedListener
    728                 staAvailListener // availableListener
    729         );
    730 
    731         // Request NAN
    732         IWifiIface nanIface = validateInterfaceSequence(chipMock,
    733                 true, // chipModeValid
    734                 BaselineChip.STA_CHIP_MODE_ID, // chipModeId
    735                 IfaceType.NAN, // ifaceTypeToCreate
    736                 "nan0", // ifaceName
    737                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
    738                 null, // tearDownList
    739                 nanDestroyedListener, // destroyedListener
    740                 nanAvailListener // availableListener
    741         );
    742 
    743         // Request P2P
    744         IWifiIface p2pIface = validateInterfaceSequence(chipMock,
    745                 true, // chipModeValid
    746                 BaselineChip.STA_CHIP_MODE_ID, // chipModeId
    747                 IfaceType.P2P, // ifaceTypeToCreate
    748                 "p2p0", // ifaceName
    749                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
    750                 new IWifiIface[]{nanIface}, // tearDownList
    751                 p2pDestroyedListener, // destroyedListener
    752                 p2pAvailListener, // availableListener
    753                 nanDestroyedListener // destroyedInterfacesDestroyedListeners...
    754         );
    755 
    756         // Request NAN: expect failure
    757         nanIface = mDut.createNanIface(nanDestroyedListener, mTestLooper.getLooper());
    758         mDut.registerInterfaceAvailableForRequestListener(IfaceType.NAN, nanAvailListener,
    759                 mTestLooper.getLooper());
    760         collector.checkThat("NAN can't be created", nanIface, IsNull.nullValue());
    761 
    762         // Destroy P2P interface
    763         boolean status = mDut.removeIface(p2pIface);
    764         mInOrder.verify(chipMock.chip).removeP2pIface("p2p0");
    765         collector.checkThat("P2P removal success", status, equalTo(true));
    766 
    767         mTestLooper.dispatchAll();
    768         verify(p2pDestroyedListener).onDestroyed();
    769         verify(nanAvailListener).onAvailableForRequest();
    770 
    771         // Request NAN: expect success now
    772         nanIface = validateInterfaceSequence(chipMock,
    773                 true, // chipModeValid
    774                 BaselineChip.STA_CHIP_MODE_ID, // chipModeId
    775                 IfaceType.NAN, // ifaceTypeToCreate
    776                 "nan0", // ifaceName
    777                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
    778                 null, // tearDownList
    779                 nanDestroyedListener, // destroyedListener
    780                 nanAvailListener // availableListener
    781         );
    782 
    783         verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener, staAvailListener,
    784                 nanDestroyedListener, nanAvailListener, p2pDestroyedListener);
    785     }
    786 
    787     /**
    788      * Validates that when (for some reason) the cache is out-of-sync with the actual chip status
    789      * then Wi-Fi is shut-down.
    790      */
    791     @Test
    792     public void testCacheMismatchError() throws Exception {
    793         BaselineChip chipMock = new BaselineChip();
    794         chipMock.initialize();
    795         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
    796                 mManagerStatusListenerMock);
    797         executeAndValidateInitializationSequence();
    798         executeAndValidateStartupSequence();
    799 
    800         HalDeviceManager.InterfaceDestroyedListener staDestroyedListener = mock(
    801                 HalDeviceManager.InterfaceDestroyedListener.class);
    802         HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
    803                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
    804 
    805         HalDeviceManager.InterfaceDestroyedListener nanDestroyedListener = mock(
    806                 HalDeviceManager.InterfaceDestroyedListener.class);
    807         HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock(
    808                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
    809 
    810         // Request STA
    811         IWifiIface staIface = validateInterfaceSequence(chipMock,
    812                 false, // chipModeValid
    813                 -1000, // chipModeId (only used if chipModeValid is true)
    814                 IfaceType.STA, // ifaceTypeToCreate
    815                 "sta0", // ifaceName
    816                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
    817                 null, // tearDownList
    818                 staDestroyedListener, // destroyedListener
    819                 staAvailListener // availableListener
    820         );
    821 
    822         // Request NAN
    823         IWifiIface nanIface = validateInterfaceSequence(chipMock,
    824                 true, // chipModeValid
    825                 BaselineChip.STA_CHIP_MODE_ID, // chipModeId
    826                 IfaceType.NAN, // ifaceTypeToCreate
    827                 "nan0", // ifaceName
    828                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
    829                 null, // tearDownList
    830                 nanDestroyedListener, // destroyedListener
    831                 nanAvailListener // availableListener
    832         );
    833 
    834         // fiddle with the "chip" by removing the STA
    835         chipMock.interfaceNames.get(IfaceType.STA).remove("sta0");
    836 
    837         // now try to request another NAN
    838         nanIface = mDut.createNanIface(nanDestroyedListener, mTestLooper.getLooper());
    839         mDut.registerInterfaceAvailableForRequestListener(IfaceType.NAN, nanAvailListener,
    840                 mTestLooper.getLooper());
    841         collector.checkThat("NAN can't be created", nanIface, IsNull.nullValue());
    842 
    843         // verify that Wi-Fi is shut-down: should also get all onDestroyed messages that are
    844         // registered (even if they seem out-of-sync to chip)
    845         mTestLooper.dispatchAll();
    846         verify(mWifiMock, times(2)).stop();
    847         verify(mManagerStatusListenerMock, times(2)).onStatusChanged();
    848         verify(staDestroyedListener).onDestroyed();
    849         verify(nanDestroyedListener).onDestroyed();
    850 
    851         verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener, staAvailListener,
    852                 nanDestroyedListener, nanAvailListener);
    853     }
    854 
    855     /**
    856      * Validates that trying to allocate a STA and then another STA fails. Only one STA at a time
    857      * is permitted (by baseline chip).
    858      */
    859     @Test
    860     public void testDuplicateStaRequests() throws Exception {
    861         BaselineChip chipMock = new BaselineChip();
    862         chipMock.initialize();
    863         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
    864                 mManagerStatusListenerMock);
    865         executeAndValidateInitializationSequence();
    866         executeAndValidateStartupSequence();
    867 
    868         HalDeviceManager.InterfaceDestroyedListener staDestroyedListener1 = mock(
    869                 HalDeviceManager.InterfaceDestroyedListener.class);
    870         HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener1 = mock(
    871                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
    872 
    873         HalDeviceManager.InterfaceDestroyedListener staDestroyedListener2 = mock(
    874                 HalDeviceManager.InterfaceDestroyedListener.class);
    875 
    876         // get STA interface
    877         IWifiIface staIface1 = validateInterfaceSequence(chipMock,
    878                 false, // chipModeValid
    879                 -1000, // chipModeId (only used if chipModeValid is true)
    880                 IfaceType.STA, // ifaceTypeToCreate
    881                 "sta0", // ifaceName
    882                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
    883                 null, // tearDownList
    884                 staDestroyedListener1, // destroyedListener
    885                 staAvailListener1 // availableListener
    886         );
    887         collector.checkThat("STA created", staIface1, IsNull.notNullValue());
    888 
    889         // get STA interface again
    890         IWifiIface staIface2 = mDut.createStaIface(staDestroyedListener2, mTestLooper.getLooper());
    891         collector.checkThat("STA created", staIface2, IsNull.nullValue());
    892 
    893         verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener1,
    894                 staAvailListener1, staDestroyedListener2);
    895     }
    896 
    897     /**
    898      * Validates that a duplicate registration of the same InterfaceAvailableForRequestListener
    899      * listener will result in a single callback.
    900      *
    901      * Also validates that get an immediate call on registration if available.
    902      */
    903     @Test
    904     public void testDuplicateAvailableRegistrations() throws Exception {
    905         BaselineChip chipMock = new BaselineChip();
    906         chipMock.initialize();
    907         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
    908                 mManagerStatusListenerMock);
    909         executeAndValidateInitializationSequence();
    910         executeAndValidateStartupSequence();
    911 
    912         HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
    913                 HalDeviceManager.InterfaceAvailableForRequestListener.class);
    914 
    915         // get STA interface
    916         IWifiIface staIface = validateInterfaceSequence(chipMock,
    917                 false, // chipModeValid
    918                 -1000, // chipModeId (only used if chipModeValid is true)
    919                 IfaceType.STA, // ifaceTypeToCreate
    920                 "sta0", // ifaceName
    921                 BaselineChip.STA_CHIP_MODE_ID, // finalChipMode
    922                 null, // tearDownList
    923                 null, // destroyedListener
    924                 null // availableListener
    925         );
    926         collector.checkThat("STA created", staIface, IsNull.notNullValue());
    927 
    928         // act: register the same listener twice
    929         mDut.registerInterfaceAvailableForRequestListener(IfaceType.STA, staAvailListener,
    930                 mTestLooper.getLooper());
    931         mDut.registerInterfaceAvailableForRequestListener(IfaceType.STA, staAvailListener,
    932                 mTestLooper.getLooper());
    933         mTestLooper.dispatchAll();
    934 
    935         // remove STA interface -> should trigger callbacks
    936         mDut.removeIface(staIface);
    937         mTestLooper.dispatchAll();
    938 
    939         // verify: only a single trigger
    940         verify(staAvailListener).onAvailableForRequest();
    941 
    942         verifyNoMoreInteractions(staAvailListener);
    943     }
    944 
    945     /**
    946      * Validate that the getSupportedIfaceTypes API works when requesting for all chips.
    947      */
    948     @Test
    949     public void testGetSupportedIfaceTypesAll() throws Exception {
    950         BaselineChip chipMock = new BaselineChip();
    951         chipMock.initialize();
    952         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
    953                 mManagerStatusListenerMock);
    954         executeAndValidateInitializationSequence();
    955         executeAndValidateStartupSequence();
    956 
    957         // try API
    958         Set<Integer> results = mDut.getSupportedIfaceTypes();
    959 
    960         // verify results
    961         Set<Integer> correctResults = new HashSet<>();
    962         correctResults.add(IfaceType.AP);
    963         correctResults.add(IfaceType.STA);
    964         correctResults.add(IfaceType.P2P);
    965         correctResults.add(IfaceType.NAN);
    966 
    967         assertEquals(correctResults, results);
    968     }
    969 
    970     /**
    971      * Validate that the getSupportedIfaceTypes API works when requesting for a specific chip.
    972      */
    973     @Test
    974     public void testGetSupportedIfaceTypesOneChip() throws Exception {
    975         BaselineChip chipMock = new BaselineChip();
    976         chipMock.initialize();
    977         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
    978                 mManagerStatusListenerMock);
    979         executeAndValidateInitializationSequence();
    980         executeAndValidateStartupSequence();
    981 
    982         // try API
    983         Set<Integer> results = mDut.getSupportedIfaceTypes(chipMock.chip);
    984 
    985         // verify results
    986         Set<Integer> correctResults = new HashSet<>();
    987         correctResults.add(IfaceType.AP);
    988         correctResults.add(IfaceType.STA);
    989         correctResults.add(IfaceType.P2P);
    990         correctResults.add(IfaceType.NAN);
    991 
    992         assertEquals(correctResults, results);
    993     }
    994 
    995     /**
    996      * Validate that when no chip info is found an empty list is returned.
    997      */
    998     @Test
    999     public void testGetSupportedIfaceTypesError() throws Exception {
   1000         // try API
   1001         Set<Integer> results = mDut.getSupportedIfaceTypes();
   1002 
   1003         // verify results
   1004         assertEquals(0, results.size());
   1005     }
   1006 
   1007     /**
   1008      * Test start HAL can retry upon failure.
   1009      */
   1010     @Test
   1011     public void testStartHalRetryUponNotAvailableFailure() throws Exception {
   1012         // Override the stubbing for mWifiMock in before().
   1013         when(mWifiMock.start())
   1014             .thenReturn(getStatus(WifiStatusCode.ERROR_NOT_AVAILABLE))
   1015             .thenReturn(mStatusOk);
   1016 
   1017         BaselineChip chipMock = new BaselineChip();
   1018         chipMock.initialize();
   1019         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
   1020                 mManagerStatusListenerMock);
   1021         executeAndValidateInitializationSequence();
   1022         executeAndValidateStartupSequence(2, true);
   1023     }
   1024 
   1025     /**
   1026      * Test start HAL fails after multiple retry failures.
   1027      */
   1028     @Test
   1029     public void testStartHalRetryFailUponMultipleNotAvailableFailures() throws Exception {
   1030         // Override the stubbing for mWifiMock in before().
   1031         when(mWifiMock.start()).thenReturn(getStatus(WifiStatusCode.ERROR_NOT_AVAILABLE));
   1032 
   1033         BaselineChip chipMock = new BaselineChip();
   1034         chipMock.initialize();
   1035         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip);
   1036         executeAndValidateInitializationSequence();
   1037         executeAndValidateStartupSequence(START_HAL_RETRY_TIMES + 1, false);
   1038     }
   1039 
   1040     /**
   1041      * Test start HAL fails after multiple retry failures.
   1042      */
   1043     @Test
   1044     public void testStartHalRetryFailUponTrueFailure() throws Exception {
   1045         // Override the stubbing for mWifiMock in before().
   1046         when(mWifiMock.start()).thenReturn(getStatus(WifiStatusCode.ERROR_UNKNOWN));
   1047 
   1048         BaselineChip chipMock = new BaselineChip();
   1049         chipMock.initialize();
   1050         mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip);
   1051         executeAndValidateInitializationSequence();
   1052         executeAndValidateStartupSequence(1, false);
   1053     }
   1054 
   1055     /**
   1056      * Validate that isSupported() returns true when IServiceManager finds the vendor HAL daemon in
   1057      * the VINTF.
   1058      */
   1059     @Test
   1060     public void testIsSupportedTrue() throws Exception {
   1061         when(mServiceManagerMock.getTransport(
   1062                 eq(IWifi.kInterfaceName), eq(HalDeviceManager.HAL_INSTANCE_NAME)))
   1063                 .thenReturn(IServiceManager.Transport.HWBINDER);
   1064         mInOrder = inOrder(mServiceManagerMock, mWifiMock);
   1065         executeAndValidateInitializationSequence();
   1066         assertTrue(mDut.isSupported());
   1067     }
   1068 
   1069     /**
   1070      * Validate that isSupported() returns true when IServiceManager finds the vendor HAL daemon in
   1071      * the VINTF.
   1072      */
   1073     @Test
   1074     public void testIsSupportedFalse() throws Exception {
   1075         when(mServiceManagerMock.getTransport(
   1076                 eq(IWifi.kInterfaceName), eq(HalDeviceManager.HAL_INSTANCE_NAME)))
   1077                 .thenReturn(IServiceManager.Transport.EMPTY);
   1078         mInOrder = inOrder(mServiceManagerMock, mWifiMock);
   1079         executeAndValidateInitializationSequence();
   1080         assertFalse(mDut.isSupported());
   1081     }
   1082 
   1083     // utilities
   1084     private void dumpDut(String prefix) {
   1085         StringWriter sw = new StringWriter();
   1086         mDut.dump(null, new PrintWriter(sw), null);
   1087         Log.e("HalDeviceManager", prefix + sw.toString());
   1088     }
   1089 
   1090     private void executeAndValidateInitializationSequence() throws Exception {
   1091         // act:
   1092         mDut.initialize();
   1093 
   1094         // verify: service manager initialization sequence
   1095         mInOrder.verify(mServiceManagerMock).linkToDeath(any(IHwBinder.DeathRecipient.class),
   1096                 anyLong());
   1097         mInOrder.verify(mServiceManagerMock).registerForNotifications(eq(IWifi.kInterfaceName),
   1098                 eq(""), mServiceNotificationCaptor.capture());
   1099 
   1100         // act: get the service started (which happens even when service was already up)
   1101         mServiceNotificationCaptor.getValue().onRegistration(IWifi.kInterfaceName, "", true);
   1102 
   1103         // verify: wifi initialization sequence
   1104         mInOrder.verify(mWifiMock).linkToDeath(mDeathRecipientCaptor.capture(), anyLong());
   1105         mInOrder.verify(mWifiMock).registerEventCallback(mWifiEventCallbackCaptor.capture());
   1106         collector.checkThat("isReady is true", mDut.isReady(), equalTo(true));
   1107     }
   1108 
   1109     private void executeAndValidateStartupSequence()throws Exception {
   1110         executeAndValidateStartupSequence(1, true);
   1111     }
   1112 
   1113     private void executeAndValidateStartupSequence(int numAttempts, boolean success)
   1114             throws Exception {
   1115         // act: register listener & start Wi-Fi
   1116         mDut.registerStatusListener(mManagerStatusListenerMock, mTestLooper.getLooper());
   1117         collector.checkThat(mDut.start(), equalTo(success));
   1118 
   1119         // verify
   1120         mInOrder.verify(mWifiMock, times(numAttempts)).start();
   1121 
   1122         if (success) {
   1123             // act: trigger onStart callback of IWifiEventCallback
   1124             mWifiEventCallbackCaptor.getValue().onStart();
   1125             mTestLooper.dispatchAll();
   1126 
   1127             // verify: onStart called on registered listener
   1128             mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
   1129         }
   1130     }
   1131 
   1132     private IWifiIface validateInterfaceSequence(ChipMockBase chipMock,
   1133             boolean chipModeValid, int chipModeId,
   1134             int ifaceTypeToCreate, String ifaceName, int finalChipMode, IWifiIface[] tearDownList,
   1135             HalDeviceManager.InterfaceDestroyedListener destroyedListener,
   1136             HalDeviceManager.InterfaceAvailableForRequestListener availableListener,
   1137             HalDeviceManager.InterfaceDestroyedListener... destroyedInterfacesDestroyedListeners)
   1138             throws Exception {
   1139         // configure chip mode response
   1140         chipMock.chipModeValid = chipModeValid;
   1141         chipMock.chipModeId = chipModeId;
   1142 
   1143         IWifiIface iface = null;
   1144 
   1145         // configure: interface to be created
   1146         // act: request the interface
   1147         switch (ifaceTypeToCreate) {
   1148             case IfaceType.STA:
   1149                 iface = mock(IWifiStaIface.class);
   1150                 doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
   1151                         any(IWifiIface.getNameCallback.class));
   1152                 doAnswer(new GetTypeAnswer(IfaceType.STA)).when(iface).getType(
   1153                         any(IWifiIface.getTypeCallback.class));
   1154                 doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
   1155                         chipMock.chip).createStaIface(any(IWifiChip.createStaIfaceCallback.class));
   1156 
   1157                 mDut.createStaIface(destroyedListener, mTestLooper.getLooper());
   1158                 break;
   1159             case IfaceType.AP:
   1160                 iface = mock(IWifiApIface.class);
   1161                 doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
   1162                         any(IWifiIface.getNameCallback.class));
   1163                 doAnswer(new GetTypeAnswer(IfaceType.AP)).when(iface).getType(
   1164                         any(IWifiIface.getTypeCallback.class));
   1165                 doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
   1166                         chipMock.chip).createApIface(any(IWifiChip.createApIfaceCallback.class));
   1167 
   1168                 mDut.createApIface(destroyedListener, mTestLooper.getLooper());
   1169                 break;
   1170             case IfaceType.P2P:
   1171                 iface = mock(IWifiP2pIface.class);
   1172                 doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
   1173                         any(IWifiIface.getNameCallback.class));
   1174                 doAnswer(new GetTypeAnswer(IfaceType.P2P)).when(iface).getType(
   1175                         any(IWifiIface.getTypeCallback.class));
   1176                 doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
   1177                         chipMock.chip).createP2pIface(any(IWifiChip.createP2pIfaceCallback.class));
   1178 
   1179                 mDut.createP2pIface(destroyedListener, mTestLooper.getLooper());
   1180                 break;
   1181             case IfaceType.NAN:
   1182                 iface = mock(IWifiNanIface.class);
   1183                 doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
   1184                         any(IWifiIface.getNameCallback.class));
   1185                 doAnswer(new GetTypeAnswer(IfaceType.NAN)).when(iface).getType(
   1186                         any(IWifiIface.getTypeCallback.class));
   1187                 doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
   1188                         chipMock.chip).createNanIface(any(IWifiChip.createNanIfaceCallback.class));
   1189 
   1190                 mDut.createNanIface(destroyedListener, mTestLooper.getLooper());
   1191                 break;
   1192         }
   1193         if (availableListener != null) {
   1194             mDut.registerInterfaceAvailableForRequestListener(ifaceTypeToCreate, availableListener,
   1195                     mTestLooper.getLooper());
   1196         }
   1197 
   1198         // validate: optional tear down of interfaces
   1199         if (tearDownList != null) {
   1200             for (IWifiIface tearDownIface: tearDownList) {
   1201                 switch (getType(tearDownIface)) {
   1202                     case IfaceType.STA:
   1203                         mInOrder.verify(chipMock.chip).removeStaIface(getName(tearDownIface));
   1204                         break;
   1205                     case IfaceType.AP:
   1206                         mInOrder.verify(chipMock.chip).removeApIface(getName(tearDownIface));
   1207                         break;
   1208                     case IfaceType.P2P:
   1209                         mInOrder.verify(chipMock.chip).removeP2pIface(getName(tearDownIface));
   1210                         break;
   1211                     case IfaceType.NAN:
   1212                         mInOrder.verify(chipMock.chip).removeNanIface(getName(tearDownIface));
   1213                         break;
   1214                 }
   1215             }
   1216         }
   1217 
   1218         // validate: optional switch to the requested mode
   1219         if (!chipModeValid || chipModeId != finalChipMode) {
   1220             mInOrder.verify(chipMock.chip).configureChip(finalChipMode);
   1221         } else {
   1222             mInOrder.verify(chipMock.chip, times(0)).configureChip(anyInt());
   1223         }
   1224 
   1225         // validate: create interface
   1226         switch (ifaceTypeToCreate) {
   1227             case IfaceType.STA:
   1228                 mInOrder.verify(chipMock.chip).createStaIface(
   1229                         any(IWifiChip.createStaIfaceCallback.class));
   1230                 break;
   1231             case IfaceType.AP:
   1232                 mInOrder.verify(chipMock.chip).createApIface(
   1233                         any(IWifiChip.createApIfaceCallback.class));
   1234                 break;
   1235             case IfaceType.P2P:
   1236                 mInOrder.verify(chipMock.chip).createP2pIface(
   1237                         any(IWifiChip.createP2pIfaceCallback.class));
   1238                 break;
   1239             case IfaceType.NAN:
   1240                 mInOrder.verify(chipMock.chip).createNanIface(
   1241                         any(IWifiChip.createNanIfaceCallback.class));
   1242                 break;
   1243         }
   1244 
   1245         // verify: callbacks on deleted interfaces
   1246         mTestLooper.dispatchAll();
   1247         for (int i = 0; i < destroyedInterfacesDestroyedListeners.length; ++i) {
   1248             verify(destroyedInterfacesDestroyedListeners[i]).onDestroyed();
   1249         }
   1250 
   1251         return iface;
   1252     }
   1253 
   1254     private int getType(IWifiIface iface) throws Exception {
   1255         Mutable<Integer> typeResp = new Mutable<>();
   1256         iface.getType((WifiStatus status, int type) -> {
   1257             typeResp.value = type;
   1258         });
   1259         return typeResp.value;
   1260     }
   1261 
   1262     private String getName(IWifiIface iface) throws Exception {
   1263         Mutable<String> nameResp = new Mutable<>();
   1264         iface.getName((WifiStatus status, String name) -> {
   1265             nameResp.value = name;
   1266         });
   1267         return nameResp.value;
   1268     }
   1269 
   1270     private WifiStatus getStatus(int code) {
   1271         WifiStatus status = new WifiStatus();
   1272         status.code = code;
   1273         return status;
   1274     }
   1275 
   1276     private static class Mutable<E> {
   1277         public E value;
   1278 
   1279         Mutable() {
   1280             value = null;
   1281         }
   1282 
   1283         Mutable(E value) {
   1284             this.value = value;
   1285         }
   1286     }
   1287 
   1288     // Answer objects
   1289     private class GetChipIdsAnswer extends MockAnswerUtil.AnswerWithArguments {
   1290         private WifiStatus mStatus;
   1291         private ArrayList<Integer> mChipIds;
   1292 
   1293         GetChipIdsAnswer(WifiStatus status, ArrayList<Integer> chipIds) {
   1294             mStatus = status;
   1295             mChipIds = chipIds;
   1296         }
   1297 
   1298         public void answer(IWifi.getChipIdsCallback cb) {
   1299             cb.onValues(mStatus, mChipIds);
   1300         }
   1301     }
   1302 
   1303     private class GetChipAnswer extends MockAnswerUtil.AnswerWithArguments {
   1304         private WifiStatus mStatus;
   1305         private IWifiChip mChip;
   1306 
   1307         GetChipAnswer(WifiStatus status, IWifiChip chip) {
   1308             mStatus = status;
   1309             mChip = chip;
   1310         }
   1311 
   1312         public void answer(int chipId, IWifi.getChipCallback cb) {
   1313             cb.onValues(mStatus, mChip);
   1314         }
   1315     }
   1316 
   1317     private class GetIdAnswer extends MockAnswerUtil.AnswerWithArguments {
   1318         private ChipMockBase mChipMockBase;
   1319 
   1320         GetIdAnswer(ChipMockBase chipMockBase) {
   1321             mChipMockBase = chipMockBase;
   1322         }
   1323 
   1324         public void answer(IWifiChip.getIdCallback cb) {
   1325             cb.onValues(mStatusOk, mChipMockBase.chipId);
   1326         }
   1327     }
   1328 
   1329     private class GetAvailableModesAnswer extends MockAnswerUtil.AnswerWithArguments {
   1330         private ChipMockBase mChipMockBase;
   1331 
   1332         GetAvailableModesAnswer(ChipMockBase chipMockBase) {
   1333             mChipMockBase = chipMockBase;
   1334         }
   1335 
   1336         public void answer(IWifiChip.getAvailableModesCallback cb) {
   1337             cb.onValues(mStatusOk, mChipMockBase.availableModes);
   1338         }
   1339     }
   1340 
   1341     private class GetModeAnswer extends MockAnswerUtil.AnswerWithArguments {
   1342         private ChipMockBase mChipMockBase;
   1343 
   1344         GetModeAnswer(ChipMockBase chipMockBase) {
   1345             mChipMockBase = chipMockBase;
   1346         }
   1347 
   1348         public void answer(IWifiChip.getModeCallback cb) {
   1349             cb.onValues(mChipMockBase.chipModeValid ? mStatusOk
   1350                     : getStatus(WifiStatusCode.ERROR_NOT_AVAILABLE), mChipMockBase.chipModeId);
   1351         }
   1352     }
   1353 
   1354     private class ConfigureChipAnswer extends MockAnswerUtil.AnswerWithArguments {
   1355         private ChipMockBase mChipMockBase;
   1356 
   1357         ConfigureChipAnswer(ChipMockBase chipMockBase) {
   1358             mChipMockBase = chipMockBase;
   1359         }
   1360 
   1361         public WifiStatus answer(int chipMode) {
   1362             mChipMockBase.chipModeId = chipMode;
   1363             return mStatusOk;
   1364         }
   1365     }
   1366 
   1367     private class GetXxxIfaceNamesAnswer extends MockAnswerUtil.AnswerWithArguments {
   1368         private ChipMockBase mChipMockBase;
   1369 
   1370         GetXxxIfaceNamesAnswer(ChipMockBase chipMockBase) {
   1371             mChipMockBase = chipMockBase;
   1372         }
   1373 
   1374         public void answer(IWifiChip.getStaIfaceNamesCallback cb) {
   1375             cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.STA));
   1376         }
   1377 
   1378         public void answer(IWifiChip.getApIfaceNamesCallback cb) {
   1379             cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.AP));
   1380         }
   1381 
   1382         public void answer(IWifiChip.getP2pIfaceNamesCallback cb) {
   1383             cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.P2P));
   1384         }
   1385 
   1386         public void answer(IWifiChip.getNanIfaceNamesCallback cb) {
   1387             cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.NAN));
   1388         }
   1389     }
   1390 
   1391     private class GetXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
   1392         private ChipMockBase mChipMockBase;
   1393 
   1394         GetXxxIfaceAnswer(ChipMockBase chipMockBase) {
   1395             mChipMockBase = chipMockBase;
   1396         }
   1397 
   1398         public void answer(String name, IWifiChip.getStaIfaceCallback cb) {
   1399             IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.STA).get(name);
   1400             cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiStaIface) iface);
   1401         }
   1402 
   1403         public void answer(String name, IWifiChip.getApIfaceCallback cb) {
   1404             IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.AP).get(name);
   1405             cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiApIface) iface);
   1406         }
   1407 
   1408         public void answer(String name, IWifiChip.getP2pIfaceCallback cb) {
   1409             IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.P2P).get(name);
   1410             cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiP2pIface) iface);
   1411         }
   1412 
   1413         public void answer(String name, IWifiChip.getNanIfaceCallback cb) {
   1414             IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.NAN).get(name);
   1415             cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiNanIface) iface);
   1416         }
   1417     }
   1418 
   1419     private class CreateXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
   1420         private ChipMockBase mChipMockBase;
   1421         private WifiStatus mStatus;
   1422         private IWifiIface mWifiIface;
   1423 
   1424         CreateXxxIfaceAnswer(ChipMockBase chipMockBase, WifiStatus status, IWifiIface wifiIface) {
   1425             mChipMockBase = chipMockBase;
   1426             mStatus = status;
   1427             mWifiIface = wifiIface;
   1428         }
   1429 
   1430         private void addInterfaceInfo(int type) {
   1431             if (mStatus.code == WifiStatusCode.SUCCESS) {
   1432                 try {
   1433                     mChipMockBase.interfaceNames.get(type).add(getName(mWifiIface));
   1434                     mChipMockBase.interfacesByName.get(type).put(getName(mWifiIface), mWifiIface);
   1435                 } catch (Exception e) {
   1436                     // do nothing
   1437                 }
   1438             }
   1439         }
   1440 
   1441         public void answer(IWifiChip.createStaIfaceCallback cb) {
   1442             cb.onValues(mStatus, (IWifiStaIface) mWifiIface);
   1443             addInterfaceInfo(IfaceType.STA);
   1444         }
   1445 
   1446         public void answer(IWifiChip.createApIfaceCallback cb) {
   1447             cb.onValues(mStatus, (IWifiApIface) mWifiIface);
   1448             addInterfaceInfo(IfaceType.AP);
   1449         }
   1450 
   1451         public void answer(IWifiChip.createP2pIfaceCallback cb) {
   1452             cb.onValues(mStatus, (IWifiP2pIface) mWifiIface);
   1453             addInterfaceInfo(IfaceType.P2P);
   1454         }
   1455 
   1456         public void answer(IWifiChip.createNanIfaceCallback cb) {
   1457             cb.onValues(mStatus, (IWifiNanIface) mWifiIface);
   1458             addInterfaceInfo(IfaceType.NAN);
   1459         }
   1460     }
   1461 
   1462     private class RemoveXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
   1463         private ChipMockBase mChipMockBase;
   1464         private int mType;
   1465 
   1466         RemoveXxxIfaceAnswer(ChipMockBase chipMockBase, int type) {
   1467             mChipMockBase = chipMockBase;
   1468             mType = type;
   1469         }
   1470 
   1471         private WifiStatus removeIface(int type, String ifname) {
   1472             try {
   1473                 if (!mChipMockBase.interfaceNames.get(type).remove(ifname)) {
   1474                     return mStatusFail;
   1475                 }
   1476                 if (mChipMockBase.interfacesByName.get(type).remove(ifname) == null) {
   1477                     return mStatusFail;
   1478                 }
   1479             } catch (Exception e) {
   1480                 return mStatusFail;
   1481             }
   1482             return mStatusOk;
   1483         }
   1484 
   1485         public WifiStatus answer(String ifname) {
   1486             return removeIface(mType, ifname);
   1487         }
   1488     }
   1489 
   1490     private class GetNameAnswer extends MockAnswerUtil.AnswerWithArguments {
   1491         private String mName;
   1492 
   1493         GetNameAnswer(String name) {
   1494             mName = name;
   1495         }
   1496 
   1497         public void answer(IWifiIface.getNameCallback cb) {
   1498             cb.onValues(mStatusOk, mName);
   1499         }
   1500     }
   1501 
   1502     private class GetTypeAnswer extends MockAnswerUtil.AnswerWithArguments {
   1503         private int mType;
   1504 
   1505         GetTypeAnswer(int type) {
   1506             mType = type;
   1507         }
   1508 
   1509         public void answer(IWifiIface.getTypeCallback cb) {
   1510             cb.onValues(mStatusOk, mType);
   1511         }
   1512     }
   1513 
   1514     // chip configuration
   1515 
   1516     private class ChipMockBase {
   1517         public IWifiChip chip;
   1518         public int chipId;
   1519         public boolean chipModeValid = false;
   1520         public int chipModeId = -1000;
   1521         public Map<Integer, ArrayList<String>> interfaceNames = new HashMap<>();
   1522         public Map<Integer, Map<String, IWifiIface>> interfacesByName = new HashMap<>();
   1523 
   1524         public ArrayList<IWifiChip.ChipMode> availableModes;
   1525 
   1526         void initialize() throws Exception {
   1527             chip = mock(IWifiChip.class);
   1528 
   1529             interfaceNames.put(IfaceType.STA, new ArrayList<>());
   1530             interfaceNames.put(IfaceType.AP, new ArrayList<>());
   1531             interfaceNames.put(IfaceType.P2P, new ArrayList<>());
   1532             interfaceNames.put(IfaceType.NAN, new ArrayList<>());
   1533 
   1534             interfacesByName.put(IfaceType.STA, new HashMap<>());
   1535             interfacesByName.put(IfaceType.AP, new HashMap<>());
   1536             interfacesByName.put(IfaceType.P2P, new HashMap<>());
   1537             interfacesByName.put(IfaceType.NAN, new HashMap<>());
   1538 
   1539             when(chip.registerEventCallback(any(IWifiChipEventCallback.class))).thenReturn(
   1540                     mStatusOk);
   1541             when(chip.configureChip(anyInt())).thenAnswer(new ConfigureChipAnswer(this));
   1542             doAnswer(new GetIdAnswer(this)).when(chip).getId(any(IWifiChip.getIdCallback.class));
   1543             doAnswer(new GetModeAnswer(this)).when(chip).getMode(
   1544                     any(IWifiChip.getModeCallback.class));
   1545             GetXxxIfaceNamesAnswer getXxxIfaceNamesAnswer = new GetXxxIfaceNamesAnswer(this);
   1546             doAnswer(getXxxIfaceNamesAnswer).when(chip).getStaIfaceNames(
   1547                     any(IWifiChip.getStaIfaceNamesCallback.class));
   1548             doAnswer(getXxxIfaceNamesAnswer).when(chip).getApIfaceNames(
   1549                     any(IWifiChip.getApIfaceNamesCallback.class));
   1550             doAnswer(getXxxIfaceNamesAnswer).when(chip).getP2pIfaceNames(
   1551                     any(IWifiChip.getP2pIfaceNamesCallback.class));
   1552             doAnswer(getXxxIfaceNamesAnswer).when(chip).getNanIfaceNames(
   1553                     any(IWifiChip.getNanIfaceNamesCallback.class));
   1554             GetXxxIfaceAnswer getXxxIfaceAnswer = new GetXxxIfaceAnswer(this);
   1555             doAnswer(getXxxIfaceAnswer).when(chip).getStaIface(anyString(),
   1556                     any(IWifiChip.getStaIfaceCallback.class));
   1557             doAnswer(getXxxIfaceAnswer).when(chip).getApIface(anyString(),
   1558                     any(IWifiChip.getApIfaceCallback.class));
   1559             doAnswer(getXxxIfaceAnswer).when(chip).getP2pIface(anyString(),
   1560                     any(IWifiChip.getP2pIfaceCallback.class));
   1561             doAnswer(getXxxIfaceAnswer).when(chip).getNanIface(anyString(),
   1562                     any(IWifiChip.getNanIfaceCallback.class));
   1563             doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.STA)).when(chip).removeStaIface(
   1564                     anyString());
   1565             doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.AP)).when(chip).removeApIface(
   1566                     anyString());
   1567             doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.P2P)).when(chip).removeP2pIface(
   1568                     anyString());
   1569             doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.NAN)).when(chip).removeNanIface(
   1570                     anyString());
   1571         }
   1572     }
   1573 
   1574     // emulate baseline/legacy config:
   1575     // mode: STA + NAN || P2P
   1576     // mode: NAN
   1577     private class BaselineChip extends ChipMockBase {
   1578         static final int STA_CHIP_MODE_ID = 0;
   1579         static final int AP_CHIP_MODE_ID = 1;
   1580 
   1581         void initialize() throws Exception {
   1582             super.initialize();
   1583 
   1584             // chip Id configuration
   1585             ArrayList<Integer> chipIds;
   1586             chipId = 10;
   1587             chipIds = new ArrayList<>();
   1588             chipIds.add(chipId);
   1589             doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds(
   1590                     any(IWifi.getChipIdsCallback.class));
   1591 
   1592             doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(10),
   1593                     any(IWifi.getChipCallback.class));
   1594 
   1595             // initialize dummy chip modes
   1596             IWifiChip.ChipMode cm;
   1597             IWifiChip.ChipIfaceCombination cic;
   1598             IWifiChip.ChipIfaceCombinationLimit cicl;
   1599 
   1600             //   Mode 0: 1xSTA + 1x{P2P,NAN}
   1601             //   Mode 1: 1xAP
   1602             availableModes = new ArrayList<>();
   1603             cm = new IWifiChip.ChipMode();
   1604             cm.id = STA_CHIP_MODE_ID;
   1605 
   1606             cic = new IWifiChip.ChipIfaceCombination();
   1607 
   1608             cicl = new IWifiChip.ChipIfaceCombinationLimit();
   1609             cicl.maxIfaces = 1;
   1610             cicl.types.add(IfaceType.STA);
   1611             cic.limits.add(cicl);
   1612 
   1613             cicl = new IWifiChip.ChipIfaceCombinationLimit();
   1614             cicl.maxIfaces = 1;
   1615             cicl.types.add(IfaceType.P2P);
   1616             cicl.types.add(IfaceType.NAN);
   1617             cic.limits.add(cicl);
   1618             cm.availableCombinations.add(cic);
   1619             availableModes.add(cm);
   1620 
   1621             cm = new IWifiChip.ChipMode();
   1622             cm.id = AP_CHIP_MODE_ID;
   1623             cic = new IWifiChip.ChipIfaceCombination();
   1624             cicl = new IWifiChip.ChipIfaceCombinationLimit();
   1625             cicl.maxIfaces = 1;
   1626             cicl.types.add(IfaceType.AP);
   1627             cic.limits.add(cicl);
   1628             cm.availableCombinations.add(cic);
   1629             availableModes.add(cm);
   1630 
   1631             doAnswer(new GetAvailableModesAnswer(this)).when(chip)
   1632                     .getAvailableModes(any(IWifiChip.getAvailableModesCallback.class));
   1633         }
   1634     }
   1635 }
   1636