blob: bd9a1691a3377f057aad8a8c3e4cc7d1dc138226 [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.wifi;
import static com.android.server.wifi.HalDeviceManager.START_HAL_RETRY_TIMES;
import static junit.framework.Assert.assertEquals;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import android.app.test.MockAnswerUtil;
import android.hardware.wifi.V1_0.IWifi;
import android.hardware.wifi.V1_0.IWifiApIface;
import android.hardware.wifi.V1_0.IWifiChip;
import android.hardware.wifi.V1_0.IWifiChipEventCallback;
import android.hardware.wifi.V1_0.IWifiEventCallback;
import android.hardware.wifi.V1_0.IWifiIface;
import android.hardware.wifi.V1_0.IWifiNanIface;
import android.hardware.wifi.V1_0.IWifiP2pIface;
import android.hardware.wifi.V1_0.IWifiRttController;
import android.hardware.wifi.V1_0.IWifiStaIface;
import android.hardware.wifi.V1_0.IfaceType;
import android.hardware.wifi.V1_0.WifiStatus;
import android.hardware.wifi.V1_0.WifiStatusCode;
import android.hidl.manager.V1_0.IServiceNotification;
import android.hidl.manager.V1_2.IServiceManager;
import android.os.Handler;
import android.os.IHwBinder;
import android.os.test.TestLooper;
import android.util.Log;
import android.util.SparseArray;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.HalDeviceManager.InterfaceDestroyedListener;
import org.hamcrest.core.IsNull;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ErrorCollector;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Unit test harness for HalDeviceManagerTest.
*/
@SmallTest
public class HalDeviceManagerTest extends WifiBaseTest {
private HalDeviceManager mDut;
@Mock IServiceManager mServiceManagerMock;
@Mock IWifi mWifiMock;
@Mock IWifiRttController mRttControllerMock;
@Mock HalDeviceManager.ManagerStatusListener mManagerStatusListenerMock;
@Mock private Clock mClock;
private TestLooper mTestLooper;
private Handler mHandler;
private ArgumentCaptor<IHwBinder.DeathRecipient> mDeathRecipientCaptor =
ArgumentCaptor.forClass(IHwBinder.DeathRecipient.class);
private ArgumentCaptor<IServiceNotification.Stub> mServiceNotificationCaptor =
ArgumentCaptor.forClass(IServiceNotification.Stub.class);
private ArgumentCaptor<IWifiEventCallback> mWifiEventCallbackCaptor = ArgumentCaptor.forClass(
IWifiEventCallback.class);
private InOrder mInOrder;
@Rule public ErrorCollector collector = new ErrorCollector();
private WifiStatus mStatusOk;
private WifiStatus mStatusFail;
private class HalDeviceManagerSpy extends HalDeviceManager {
HalDeviceManagerSpy() {
super(mClock, mHandler);
}
@Override
protected IWifi getWifiServiceMockable() {
return mWifiMock;
}
@Override
protected IServiceManager getServiceManagerMockable() {
return mServiceManagerMock;
}
}
@Before
public void before() throws Exception {
MockitoAnnotations.initMocks(this);
mTestLooper = new TestLooper();
mHandler = new Handler(mTestLooper.getLooper());
// initialize dummy status objects
mStatusOk = getStatus(WifiStatusCode.SUCCESS);
mStatusFail = getStatus(WifiStatusCode.ERROR_UNKNOWN);
when(mServiceManagerMock.linkToDeath(any(IHwBinder.DeathRecipient.class),
anyLong())).thenReturn(true);
when(mServiceManagerMock.registerForNotifications(anyString(), anyString(),
any(IServiceNotification.Stub.class))).thenReturn(true);
when(mServiceManagerMock.listManifestByInterface(eq(IWifi.kInterfaceName)))
.thenReturn(new ArrayList(Arrays.asList("default")));
when(mWifiMock.linkToDeath(any(IHwBinder.DeathRecipient.class), anyLong())).thenReturn(
true);
when(mWifiMock.registerEventCallback(any(IWifiEventCallback.class))).thenReturn(mStatusOk);
when(mWifiMock.start()).thenReturn(mStatusOk);
when(mWifiMock.stop()).thenReturn(mStatusOk);
when(mWifiMock.isStarted()).thenReturn(true);
mDut = new HalDeviceManagerSpy();
}
/**
* Print out the dump of the device manager after each test. Not used in test validation
* (internal state) - but can help in debugging failed tests.
*/
@After
public void after() throws Exception {
dumpDut("after: ");
}
//////////////////////////////////////////////////////////////////////////////////////
// Chip Independent Tests
//////////////////////////////////////////////////////////////////////////////////////
/**
* Test basic startup flow:
* - IServiceManager registrations
* - IWifi registrations
* - IWifi startup delayed
* - Start Wi-Fi -> onStart
* - Stop Wi-Fi -> onStop
*/
@Test
public void testStartStopFlow() throws Exception {
mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
// act: stop Wi-Fi
mDut.stop();
mTestLooper.dispatchAll();
// verify: onStop called
mInOrder.verify(mWifiMock).stop();
mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
verifyNoMoreInteractions(mManagerStatusListenerMock);
}
/**
* Test the service manager notification coming in after
* {@link HalDeviceManager#initIWifiIfNecessary()} is already invoked as a part of
* {@link HalDeviceManager#initialize()}.
*/
@Test
public void testServiceRegisterationAfterInitialize() throws Exception {
mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
// This should now be ignored since IWifi is already non-null.
mServiceNotificationCaptor.getValue().onRegistration(IWifi.kInterfaceName, "", true);
verifyNoMoreInteractions(mManagerStatusListenerMock, mWifiMock, mServiceManagerMock);
}
/**
* Validate that multiple callback registrations are called and that duplicate ones are
* only called once.
*/
@Test
public void testMultipleCallbackRegistrations() throws Exception {
mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
// register another 2 callbacks - one of them twice
HalDeviceManager.ManagerStatusListener callback1 = mock(
HalDeviceManager.ManagerStatusListener.class);
HalDeviceManager.ManagerStatusListener callback2 = mock(
HalDeviceManager.ManagerStatusListener.class);
mDut.registerStatusListener(callback2, mHandler);
mDut.registerStatusListener(callback1, mHandler);
mDut.registerStatusListener(callback2, mHandler);
// startup
executeAndValidateStartupSequence();
// verify
verify(callback1).onStatusChanged();
verify(callback2).onStatusChanged();
verifyNoMoreInteractions(mManagerStatusListenerMock, callback1, callback2);
}
/**
* Validate IWifi death listener and registration flow.
*/
@Test
public void testWifiDeathAndRegistration() throws Exception {
mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
// act: IWifi service death
mDeathRecipientCaptor.getValue().serviceDied(0);
mTestLooper.dispatchAll();
// verify: getting onStop
mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
// act: service startup
mServiceNotificationCaptor.getValue().onRegistration(IWifi.kInterfaceName, "", false);
// verify: initialization of IWifi
mInOrder.verify(mWifiMock).linkToDeath(mDeathRecipientCaptor.capture(), anyLong());
mInOrder.verify(mWifiMock).registerEventCallback(mWifiEventCallbackCaptor.capture());
// act: start
collector.checkThat(mDut.start(), equalTo(true));
mWifiEventCallbackCaptor.getValue().onStart();
mTestLooper.dispatchAll();
// verify: service and callback calls
mInOrder.verify(mWifiMock).start();
mInOrder.verify(mManagerStatusListenerMock, times(2)).onStatusChanged();
verifyNoMoreInteractions(mManagerStatusListenerMock);
}
/**
* Validate IWifi onFailure causes notification
*/
@Test
public void testWifiFail() throws Exception {
mInOrder = inOrder(mServiceManagerMock, mWifiMock, mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
// act: IWifi failure
mWifiEventCallbackCaptor.getValue().onFailure(mStatusFail);
mTestLooper.dispatchAll();
// verify: getting onStop
mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
// act: start again
collector.checkThat(mDut.start(), equalTo(true));
mWifiEventCallbackCaptor.getValue().onStart();
mTestLooper.dispatchAll();
// verify: service and callback calls
mInOrder.verify(mWifiMock).start();
mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
verifyNoMoreInteractions(mManagerStatusListenerMock);
}
/**
* Validates that when (for some reason) the cache is out-of-sync with the actual chip status
* then Wi-Fi is shut-down.
*
* Uses TestChipV1 - but nothing specific to its configuration. The test validates internal
* HDM behavior.
*/
@Test
public void testCacheMismatchError() throws Exception {
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
InterfaceDestroyedListener staDestroyedListener = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InterfaceDestroyedListener nanDestroyedListener = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InOrder availInOrder = inOrder(staAvailListener, nanAvailListener);
// Request STA
IWifiIface staIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
IfaceType.STA, // ifaceTypeToCreate
"wlan0", // ifaceName
TestChipV1.STA_CHIP_MODE_ID, // finalChipMode
null, // tearDownList
staDestroyedListener, // destroyedListener
staAvailListener // availableListener
);
availInOrder.verify(staAvailListener).onAvailabilityChanged(false);
// Request NAN
IWifiIface nanIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV1.STA_CHIP_MODE_ID, // chipModeId
IfaceType.NAN, // ifaceTypeToCreate
"wlan0", // ifaceName
TestChipV1.STA_CHIP_MODE_ID, // finalChipMode
null, // tearDownList
nanDestroyedListener, // destroyedListener
nanAvailListener // availableListener
);
availInOrder.verify(nanAvailListener).onAvailabilityChanged(false);
// fiddle with the "chip" by removing the STA
chipMock.interfaceNames.get(IfaceType.STA).remove("wlan0");
// now try to request another NAN
IWifiIface nanIface2 = mDut.createNanIface(nanDestroyedListener, mHandler);
collector.checkThat("NAN can't be created", nanIface2, IsNull.nullValue());
mDut.registerInterfaceAvailableForRequestListener(IfaceType.NAN, nanAvailListener,
mHandler);
mTestLooper.dispatchAll();
// extra (apparently duplicate) call since everything was cleaned-up once a cache mismatch
// was detected - so this is a call on a new registration
availInOrder.verify(nanAvailListener).onAvailabilityChanged(false);
// verify that Wi-Fi is shut-down: should also get all onDestroyed messages that are
// registered (even if they seem out-of-sync to chip)
verify(mWifiMock, times(2)).stop();
verify(mManagerStatusListenerMock, times(2)).onStatusChanged();
verify(staDestroyedListener).onDestroyed(getName(staIface));
verify(nanDestroyedListener).onDestroyed(getName(nanIface));
verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener, staAvailListener,
nanDestroyedListener, nanAvailListener);
}
/**
* Validates that a duplicate registration of the same InterfaceAvailableForRequestListener
* listener will result in a single callback.
*
* Also validates that get an immediate call on registration if available.
*
* Uses TestChipV1 - but nothing specific to its configuration. The test validates internal
* HDM behavior.
*/
@Test
public void testDuplicateAvailableRegistrations() throws Exception {
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
// get STA interface
IWifiIface staIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
IfaceType.STA, // ifaceTypeToCreate
"wlan0", // ifaceName
TestChipV1.STA_CHIP_MODE_ID, // finalChipMode
null, // tearDownList
null, // destroyedListener
null // availableListener
);
collector.checkThat("STA created", staIface, IsNull.notNullValue());
// act: register the same listener twice
mDut.registerInterfaceAvailableForRequestListener(IfaceType.STA, staAvailListener,
mHandler);
mDut.registerInterfaceAvailableForRequestListener(IfaceType.STA, staAvailListener,
mHandler);
mTestLooper.dispatchAll();
verify(staAvailListener).onAvailabilityChanged(false);
// remove STA interface -> should trigger callbacks
mDut.removeIface(staIface);
mTestLooper.dispatchAll();
// verify: only a single trigger
verify(staAvailListener).onAvailabilityChanged(true);
verifyNoMoreInteractions(staAvailListener);
}
/**
* Validate that when no chip info is found an empty list is returned.
*/
@Test
public void testGetSupportedIfaceTypesError() throws Exception {
// try API
Set<Integer> results = mDut.getSupportedIfaceTypes();
// verify results
assertEquals(0, results.size());
}
/**
* Test start HAL can retry upon failure.
*
* Uses TestChipV1 - but nothing specific to its configuration. The test validates internal
* HDM behavior.
*/
@Test
public void testStartHalRetryUponNotAvailableFailure() throws Exception {
// Override the stubbing for mWifiMock in before().
when(mWifiMock.start())
.thenReturn(getStatus(WifiStatusCode.ERROR_NOT_AVAILABLE))
.thenReturn(mStatusOk);
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence(2, true);
}
/**
* Test start HAL fails after multiple retry failures.
*
* Uses TestChipV1 - but nothing specific to its configuration. The test validates internal
* HDM behavior.
*/
@Test
public void testStartHalRetryFailUponMultipleNotAvailableFailures() throws Exception {
// Override the stubbing for mWifiMock in before().
when(mWifiMock.start()).thenReturn(getStatus(WifiStatusCode.ERROR_NOT_AVAILABLE));
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence(START_HAL_RETRY_TIMES + 1, false);
}
/**
* Test start HAL fails after multiple retry failures.
*
* Uses TestChipV1 - but nothing specific to its configuration. The test validates internal
* HDM behavior.
*/
@Test
public void testStartHalRetryFailUponTrueFailure() throws Exception {
// Override the stubbing for mWifiMock in before().
when(mWifiMock.start()).thenReturn(getStatus(WifiStatusCode.ERROR_UNKNOWN));
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence(1, false);
}
/**
* Validate that isSupported() returns true when IServiceManager finds the vendor HAL daemon in
* the VINTF.
*/
@Test
public void testIsSupportedTrue() throws Exception {
mInOrder = inOrder(mServiceManagerMock, mWifiMock);
executeAndValidateInitializationSequence();
assertTrue(mDut.isSupported());
}
/**
* Validate that isSupported() returns false when IServiceManager does not find the vendor HAL
* daemon in the VINTF.
*/
@Test
public void testIsSupportedFalse() throws Exception {
when(mServiceManagerMock.listManifestByInterface(eq(IWifi.kInterfaceName)))
.thenReturn(new ArrayList());
mInOrder = inOrder(mServiceManagerMock, mWifiMock);
executeAndValidateInitializationSequence(false);
assertFalse(mDut.isSupported());
}
/**
* Validate RTT configuration when the callback is registered first and the chip is
* configured later - i.e. RTT isn't available immediately.
*/
@Test
public void testAndTriggerRttLifecycleCallbacksRegBeforeChipConfig() throws Exception {
HalDeviceManager.InterfaceRttControllerLifecycleCallback cb = mock(
HalDeviceManager.InterfaceRttControllerLifecycleCallback.class);
InOrder io = inOrder(cb);
// initialize a test chip (V1 is fine since we're not testing any specifics of
// concurrency in this test).
ChipMockBase chipMock = new TestChipV1();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
// register initial cb: don't expect RTT since chip isn't configured
mDut.registerRttControllerLifecycleCallback(cb, mHandler);
mTestLooper.dispatchAll();
io.verify(cb, times(0)).onNewRttController(any());
// create a STA - that will get the chip configured and get us an RTT controller
validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
IfaceType.STA,
"wlan0",
TestChipV1.STA_CHIP_MODE_ID,
null, // tearDownList
null, // destroyedListener
null // availableListener
);
verify(chipMock.chip).createRttController(any(), any());
io.verify(cb).onNewRttController(any());
verifyNoMoreInteractions(cb);
}
/**
* Validate the RTT Controller lifecycle using a multi-mode chip (i.e. a chip which can
* switch modes, during which RTT is destroyed).
*
* 1. Validate that an RTT is created as soon as the callback is registered - if the chip
* is already configured (i.e. it is possible to create the RTT controller).
*
* 2. Validate that only the registered callback is triggered, not previously registered ones
* and not duplicate ones.
*
* 3. Validate that onDestroy callbacks are triggered on mode change.
*/
@Test
public void testAndTriggerRttLifecycleCallbacksMultiModeChip() throws Exception {
HalDeviceManager.InterfaceRttControllerLifecycleCallback cb1 = mock(
HalDeviceManager.InterfaceRttControllerLifecycleCallback.class);
HalDeviceManager.InterfaceRttControllerLifecycleCallback cb2 = mock(
HalDeviceManager.InterfaceRttControllerLifecycleCallback.class);
InOrder io1 = inOrder(cb1);
InOrder io2 = inOrder(cb2);
// initialize a test chip (V1 is a must since we're testing a multi-mode chip) & create a
// STA (which will configure the chip).
ChipMockBase chipMock = new TestChipV1();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
IfaceType.STA,
"wlan0",
TestChipV1.STA_CHIP_MODE_ID,
null, // tearDownList
null, // destroyedListener
null // availableListener
);
mInOrder.verify(chipMock.chip, times(0)).createRttController(any(), any());
// register initial cb - expect the cb right away
mDut.registerRttControllerLifecycleCallback(cb1, mHandler);
mTestLooper.dispatchAll();
verify(chipMock.chip).createRttController(any(), any());
io1.verify(cb1).onNewRttController(mRttControllerMock);
// register a second callback and the first one again
mDut.registerRttControllerLifecycleCallback(cb2, mHandler);
mDut.registerRttControllerLifecycleCallback(cb1, mHandler);
mTestLooper.dispatchAll();
io2.verify(cb2).onNewRttController(mRttControllerMock);
// change to AP mode (which for TestChipV1 doesn't allow RTT): trigger onDestroyed for all
validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV1.STA_CHIP_MODE_ID, // chipModeId (only used if chipModeValid is true)
IfaceType.AP,
"wlan0",
TestChipV1.AP_CHIP_MODE_ID,
null, // tearDownList
null, // destroyedListener
null // availableListener
);
mTestLooper.dispatchAll();
verify(chipMock.chip, times(2)).createRttController(any(), any()); // but returns a null!
io1.verify(cb1).onRttControllerDestroyed();
io2.verify(cb2).onRttControllerDestroyed();
// change back to STA mode (which for TestChipV1 will re-allow RTT): trigger onNew for all
validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV1.AP_CHIP_MODE_ID, // chipModeId (only used if chipModeValid is true)
IfaceType.STA,
"wlan0",
TestChipV1.STA_CHIP_MODE_ID,
null, // tearDownList
null, // destroyedListener
null // availableListener
);
mTestLooper.dispatchAll();
verify(chipMock.chip, times(3)).createRttController(any(), any());
io1.verify(cb1).onNewRttController(mRttControllerMock);
io2.verify(cb2).onNewRttController(mRttControllerMock);
verifyNoMoreInteractions(cb1, cb2);
}
/**
* Validate the RTT Controller lifecycle using a single-mode chip. Specifically validate
* that RTT isn't impacted during STA -> AP change.
*/
@Test
public void testAndTriggerRttLifecycleCallbacksSingleModeChip() throws Exception {
HalDeviceManager.InterfaceRttControllerLifecycleCallback cb = mock(
HalDeviceManager.InterfaceRttControllerLifecycleCallback.class);
InOrder io = inOrder(cb);
// initialize a test chip (V2 is a must since we need a single mode chip)
// & create a STA (which will configure the chip).
ChipMockBase chipMock = new TestChipV2();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
IfaceType.STA,
"wlan0",
TestChipV2.CHIP_MODE_ID,
null, // tearDownList
null, // destroyedListener
null // availableListener
);
mInOrder.verify(chipMock.chip, times(0)).createRttController(any(), any());
// register initial cb - expect the cb right away
mDut.registerRttControllerLifecycleCallback(cb, mHandler);
mTestLooper.dispatchAll();
verify(chipMock.chip).createRttController(any(), any());
io.verify(cb).onNewRttController(mRttControllerMock);
// create an AP: no mode change for TestChipV2 -> expect no impact on RTT
validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV2.CHIP_MODE_ID, // chipModeId (only used if chipModeValid is true)
IfaceType.AP,
"wlan0",
TestChipV2.CHIP_MODE_ID,
null, // tearDownList
null, // destroyedListener
null // availableListener
);
mTestLooper.dispatchAll();
verifyNoMoreInteractions(cb);
}
//////////////////////////////////////////////////////////////////////////////////////
// Chip Specific Tests - but should work on all chips!
// (i.e. add copies for each test chip)
//////////////////////////////////////////////////////////////////////////////////////
// TestChipV1
/**
* Validate creation of STA interface from blank start-up. The remove interface.
*/
@Test
public void testCreateStaInterfaceNoInitModeTestChipV1() throws Exception {
runCreateSingleXxxInterfaceNoInitMode(new TestChipV1(), IfaceType.STA, "wlan0",
TestChipV1.STA_CHIP_MODE_ID, false);
}
/**
* Validate creation of AP interface from blank start-up. The remove interface.
*/
@Test
public void testCreateApInterfaceNoInitModeTestChipV1() throws Exception {
runCreateSingleXxxInterfaceNoInitMode(new TestChipV1(), IfaceType.AP, "wlan0",
TestChipV1.AP_CHIP_MODE_ID, false);
}
/**
* Validate creation of P2P interface from blank start-up. The remove interface.
*/
@Test
public void testCreateP2pInterfaceNoInitModeTestChipV1() throws Exception {
runCreateSingleXxxInterfaceNoInitMode(new TestChipV1(), IfaceType.P2P, "p2p0",
TestChipV1.STA_CHIP_MODE_ID, false);
}
/**
* Validate creation of NAN interface from blank start-up. The remove interface.
*/
@Test
public void testCreateNanInterfaceNoInitModeTestChipV1() throws Exception {
runCreateSingleXxxInterfaceNoInitMode(new TestChipV1(), IfaceType.NAN, "wlan0",
TestChipV1.STA_CHIP_MODE_ID, false);
}
// TestChipV2
/**
* Validate creation of STA interface from blank start-up. The remove interface.
*/
@Test
public void testCreateStaInterfaceNoInitModeTestChipV2() throws Exception {
// Note: we expected 2 available callbacks since we now have 2 STAs possible. So
// we get callback 1 after creating the first STA (since we can create another STA),
// and we get callback 2 after destroying the first STA (since we can create another STA -
// as expected).
runCreateSingleXxxInterfaceNoInitMode(new TestChipV2(), IfaceType.STA, "wlan0",
TestChipV2.CHIP_MODE_ID, true);
}
/**
* Validate creation of AP interface from blank start-up. The remove interface.
*/
@Test
public void testCreateApInterfaceNoInitModeTestChipV2() throws Exception {
runCreateSingleXxxInterfaceNoInitMode(new TestChipV2(), IfaceType.AP, "wlan0",
TestChipV2.CHIP_MODE_ID, false);
}
/**
* Validate creation of P2P interface from blank start-up. The remove interface.
*/
@Test
public void testCreateP2pInterfaceNoInitModeTestChipV2() throws Exception {
runCreateSingleXxxInterfaceNoInitMode(new TestChipV2(), IfaceType.P2P, "p2p0",
TestChipV2.CHIP_MODE_ID, false);
}
/**
* Validate creation of NAN interface from blank start-up. The remove interface.
*/
@Test
public void testCreateNanInterfaceNoInitModeTestChipV2() throws Exception {
runCreateSingleXxxInterfaceNoInitMode(new TestChipV2(), IfaceType.NAN, "wlan0",
TestChipV2.CHIP_MODE_ID, false);
}
// TestChipV3
/**
* Validate creation of STA interface from blank start-up. The remove interface.
*/
@Test
public void testCreateStaInterfaceNoInitModeTestChipV3() throws Exception {
// Note: we expected 2 available callbacks since we now have 2 STAs possible. So
// we get callback 1 after creating the first STA (since we can create another STA),
// and we get callback 2 after destroying the first STA (since we can create another STA -
// as expected).
runCreateSingleXxxInterfaceNoInitMode(new TestChipV3(), IfaceType.STA, "wlan0",
TestChipV3.CHIP_MODE_ID, true);
}
/**
* Validate creation of AP interface from blank start-up. The remove interface.
*/
@Test
public void testCreateApInterfaceNoInitModeTestChipV3() throws Exception {
runCreateSingleXxxInterfaceNoInitMode(new TestChipV3(), IfaceType.AP, "wlan0",
TestChipV3.CHIP_MODE_ID, false);
}
/**
* Validate creation of P2P interface from blank start-up. The remove interface.
*/
@Test
public void testCreateP2pInterfaceNoInitModeTestChipV3() throws Exception {
runCreateSingleXxxInterfaceNoInitMode(new TestChipV3(), IfaceType.P2P, "p2p0",
TestChipV3.CHIP_MODE_ID, false);
}
/**
* Validate creation of NAN interface from blank start-up. The remove interface.
*/
@Test
public void testCreateNanInterfaceNoInitModeTestChipV3() throws Exception {
runCreateSingleXxxInterfaceNoInitMode(new TestChipV3(), IfaceType.NAN, "wlan0",
TestChipV3.CHIP_MODE_ID, false);
}
// TestChipV4
/**
* Validate creation of STA interface from blank start-up. The remove interface.
*/
@Test
public void testCreateStaInterfaceNoInitModeTestChipV4() throws Exception {
runCreateSingleXxxInterfaceNoInitMode(new TestChipV4(), IfaceType.STA, "wlan0",
TestChipV4.CHIP_MODE_ID, false);
}
/**
* Validate creation of AP interface from blank start-up. The remove interface.
*/
@Test
public void testCreateApInterfaceNoInitModeTestChipV4() throws Exception {
runCreateSingleXxxInterfaceNoInitMode(new TestChipV4(), IfaceType.AP, "wlan0",
TestChipV4.CHIP_MODE_ID, false);
}
/**
* Validate creation of P2P interface from blank start-up. The remove interface.
*/
@Test
public void testCreateP2pInterfaceNoInitModeTestChipV4() throws Exception {
runCreateSingleXxxInterfaceNoInitMode(new TestChipV4(), IfaceType.P2P, "p2p0",
TestChipV4.CHIP_MODE_ID, false);
}
/**
* Validate creation of NAN interface from blank start-up. The remove interface.
*/
@Test
public void testCreateNanInterfaceNoInitModeTestChipV4() throws Exception {
runCreateSingleXxxInterfaceNoInitMode(new TestChipV4(), IfaceType.NAN, "wlan0",
TestChipV4.CHIP_MODE_ID, false);
}
//////////////////////////////////////////////////////////////////////////////////////
// TestChipV1 Specific Tests
//////////////////////////////////////////////////////////////////////////////////////
/**
* Validate creation of AP interface when in STA mode - but with no interface created. Expect
* a change in chip mode.
*/
@Test
public void testCreateApWithStaModeUpTestChipV1() throws Exception {
final String name = "wlan0";
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
InterfaceDestroyedListener idl = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
IWifiApIface iface = (IWifiApIface) validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV1.STA_CHIP_MODE_ID, // chipModeId
IfaceType.AP, // ifaceTypeToCreate
name, // ifaceName
TestChipV1.AP_CHIP_MODE_ID, // finalChipMode
null, // tearDownList
idl, // destroyedListener
iafrl // availableListener
);
collector.checkThat("allocated interface", iface, IsNull.notNullValue());
verify(iafrl).onAvailabilityChanged(false);
// act: stop Wi-Fi
mDut.stop();
mTestLooper.dispatchAll();
// verify: callback triggered
verify(idl).onDestroyed(getName(iface));
verify(mManagerStatusListenerMock, times(2)).onStatusChanged();
verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl);
}
/**
* Validate creation of AP interface when in STA mode with a single STA iface created.
* Expect a change in chip mode.
*/
@Test
public void testCreateApWithStIfaceUpTestChipV1UsingNoHandlerListeners() throws Exception {
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
InterfaceDestroyedListener staIdl = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener staIafrl = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InterfaceDestroyedListener apIdl = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener apIafrl = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock, staIdl, staIafrl, apIdl, apIafrl);
executeAndValidateInitializationSequence();
// Register listener & start Wi-Fi
mDut.registerStatusListener(mManagerStatusListenerMock, null);
assertTrue(mDut.start());
mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
mDut.registerInterfaceAvailableForRequestListener(IfaceType.STA, staIafrl, null);
mDut.registerInterfaceAvailableForRequestListener(IfaceType.AP, apIafrl, null);
mInOrder.verify(staIafrl).onAvailabilityChanged(true);
mInOrder.verify(apIafrl).onAvailabilityChanged(true);
// Create STA Iface first.
IWifiStaIface staIface = mock(IWifiStaIface.class);
doAnswer(new GetNameAnswer("wlan0")).when(staIface).getName(
any(IWifiIface.getNameCallback.class));
doAnswer(new GetTypeAnswer(IfaceType.STA)).when(staIface).getType(
any(IWifiIface.getTypeCallback.class));
doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, staIface)).when(
chipMock.chip).createStaIface(any(IWifiChip.createStaIfaceCallback.class));
assertEquals(staIface, mDut.createStaIface(staIdl, null));
mInOrder.verify(chipMock.chip).configureChip(TestChipV1.STA_CHIP_MODE_ID);
mInOrder.verify(staIafrl).onAvailabilityChanged(false);
// Now Create AP Iface.
IWifiApIface apIface = mock(IWifiApIface.class);
doAnswer(new GetNameAnswer("wlan0")).when(apIface).getName(
any(IWifiIface.getNameCallback.class));
doAnswer(new GetTypeAnswer(IfaceType.AP)).when(apIface).getType(
any(IWifiIface.getTypeCallback.class));
doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, apIface)).when(
chipMock.chip).createApIface(any(IWifiChip.createApIfaceCallback.class));
assertEquals(apIface, mDut.createApIface(apIdl, null));
mInOrder.verify(chipMock.chip).removeStaIface(getName(staIface));
mInOrder.verify(staIdl).onDestroyed(getName(staIface));
mInOrder.verify(chipMock.chip).configureChip(TestChipV1.AP_CHIP_MODE_ID);
mInOrder.verify(apIafrl).onAvailabilityChanged(false);
mInOrder.verify(staIafrl).onAvailabilityChanged(true);
// Stop Wi-Fi
mDut.stop();
mInOrder.verify(mWifiMock).stop();
mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
mInOrder.verify(apIdl).onDestroyed(getName(apIface));
verifyNoMoreInteractions(mManagerStatusListenerMock, staIdl, staIafrl, apIdl, apIafrl);
}
/**
* Validate creation of AP interface when in AP mode - but with no interface created. Expect
* no change in chip mode.
*/
@Test
public void testCreateApWithApModeUpTestChipV1() throws Exception {
final String name = "wlan0";
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
InterfaceDestroyedListener idl = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
IWifiApIface iface = (IWifiApIface) validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV1.AP_CHIP_MODE_ID, // chipModeId
IfaceType.AP, // ifaceTypeToCreate
name, // ifaceName
TestChipV1.AP_CHIP_MODE_ID, // finalChipMode
null, // tearDownList
idl, // destroyedListener
iafrl // availableListener
);
collector.checkThat("allocated interface", iface, IsNull.notNullValue());
verify(iafrl).onAvailabilityChanged(false);
// act: stop Wi-Fi
mDut.stop();
mTestLooper.dispatchAll();
// verify: callback triggered
verify(idl).onDestroyed(getName(iface));
verify(mManagerStatusListenerMock, times(2)).onStatusChanged();
verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl);
}
/**
* Validate AP up/down creation of AP interface when a STA already created. Expect:
* - STA created
* - P2P created
* - When AP requested:
* - STA & P2P torn down
* - AP created
* - P2P creation refused
* - Request STA: will tear down AP
* - When AP destroyed:
* - Get p2p available listener callback
* - Can create P2P when requested
* - Create P2P
* - Request NAN: will get refused
* - Tear down P2P:
* - should get nan available listener callback
* - Can create NAN when requested
*/
@Test
public void testCreateSameAndDiffPrioritiesTestChipV1() throws Exception {
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
InterfaceDestroyedListener staDestroyedListener = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InterfaceDestroyedListener staDestroyedListener2 = mock(
InterfaceDestroyedListener.class);
InterfaceDestroyedListener apDestroyedListener = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener apAvailListener = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InterfaceDestroyedListener p2pDestroyedListener = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener p2pAvailListener = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InterfaceDestroyedListener p2pDestroyedListener2 = mock(
InterfaceDestroyedListener.class);
InterfaceDestroyedListener nanDestroyedListener = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InOrder inOrderAvail = inOrder(staAvailListener, apAvailListener, p2pAvailListener,
nanAvailListener);
// register listeners for interface availability
mDut.registerInterfaceAvailableForRequestListener(IfaceType.STA, staAvailListener,
mHandler);
mDut.registerInterfaceAvailableForRequestListener(IfaceType.AP, apAvailListener, mHandler);
mDut.registerInterfaceAvailableForRequestListener(IfaceType.P2P, p2pAvailListener,
mHandler);
mDut.registerInterfaceAvailableForRequestListener(IfaceType.NAN, nanAvailListener,
mHandler);
mTestLooper.dispatchAll();
inOrderAvail.verify(staAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(apAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(true);
// Request STA
IWifiIface staIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
IfaceType.STA, // ifaceTypeToCreate
"wlan0", // ifaceName
TestChipV1.STA_CHIP_MODE_ID, // finalChipMode
null, // tearDownList
staDestroyedListener, // destroyedListener
null // availableListener
);
collector.checkThat("allocated STA interface", staIface, IsNull.notNullValue());
inOrderAvail.verify(staAvailListener).onAvailabilityChanged(false);
// request STA2: should fail
IWifiIface staIface2 = mDut.createStaIface(null, null);
collector.checkThat("STA2 should not be created", staIface2, IsNull.nullValue());
// register additional InterfaceDestroyedListeners - including a duplicate (verify that
// only called once!)
mDut.registerDestroyedListener(staIface, staDestroyedListener2, mHandler);
mDut.registerDestroyedListener(staIface, staDestroyedListener, mHandler);
// Request P2P
IWifiIface p2pIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV1.STA_CHIP_MODE_ID, // chipModeId
IfaceType.P2P, // ifaceTypeToCreate
"p2p0", // ifaceName
TestChipV1.STA_CHIP_MODE_ID, // finalChipMode
null, // tearDownList
p2pDestroyedListener, // destroyedListener
null // availableListener
);
collector.checkThat("allocated P2P interface", p2pIface, IsNull.notNullValue());
inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(false);
// Request AP
IWifiIface apIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV1.STA_CHIP_MODE_ID, // chipModeId
IfaceType.AP, // ifaceTypeToCreate
"wlan0", // ifaceName
TestChipV1.AP_CHIP_MODE_ID, // finalChipMode
new IWifiIface[]{staIface, p2pIface}, // tearDownList
apDestroyedListener, // destroyedListener
null, // availableListener
// destroyedInterfacesDestroyedListeners...
new InterfaceDestroyedListenerWithIfaceName(
getName(staIface), staDestroyedListener),
new InterfaceDestroyedListenerWithIfaceName(
getName(staIface), staDestroyedListener2),
new InterfaceDestroyedListenerWithIfaceName(
getName(p2pIface), p2pDestroyedListener)
);
collector.checkThat("allocated AP interface", apIface, IsNull.notNullValue());
inOrderAvail.verify(apAvailListener).onAvailabilityChanged(false);
inOrderAvail.verify(staAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(false);
// request AP2: should fail
IWifiIface apIface2 = mDut.createApIface(null, null);
collector.checkThat("AP2 should not be created", apIface2, IsNull.nullValue());
// Request P2P: expect failure
p2pIface = mDut.createP2pIface(p2pDestroyedListener, mHandler);
collector.checkThat("P2P can't be created", p2pIface, IsNull.nullValue());
// Request STA: expect success
staIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV1.AP_CHIP_MODE_ID, // chipModeId
IfaceType.STA, // ifaceTypeToCreate
"wlan0", // ifaceName
TestChipV1.STA_CHIP_MODE_ID, // finalChipMode
null, // tearDownList
staDestroyedListener, // destroyedListener
null, // availableListener
// destroyedInterfacesDestroyedListeners...
new InterfaceDestroyedListenerWithIfaceName(
getName(apIface), apDestroyedListener)
);
collector.checkThat("allocated STA interface", staIface, IsNull.notNullValue());
inOrderAvail.verify(apAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(staAvailListener).onAvailabilityChanged(false);
inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(true);
mTestLooper.dispatchAll();
verify(apDestroyedListener).onDestroyed(getName(apIface));
// Request P2P: expect success now
p2pIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV1.STA_CHIP_MODE_ID, // chipModeId
IfaceType.P2P, // ifaceTypeToCreate
"p2p0", // ifaceName
TestChipV1.STA_CHIP_MODE_ID, // finalChipMode
null, // tearDownList
p2pDestroyedListener2, // destroyedListener
null // availableListener
);
collector.checkThat("allocated P2P interface", p2pIface, IsNull.notNullValue());
inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(false);
// create NAN: will destroy P2P
IWifiIface nanIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV1.STA_CHIP_MODE_ID, // chipModeId
IfaceType.NAN, // ifaceTypeToCreate
"wlan0", // ifaceName
TestChipV1.STA_CHIP_MODE_ID, // finalChipMode
null, // tearDownList
nanDestroyedListener, // destroyedListener
nanAvailListener, // availableListener
new InterfaceDestroyedListenerWithIfaceName("p2p0", p2pDestroyedListener2)
);
collector.checkThat("allocated NAN interface", nanIface, IsNull.notNullValue());
inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(false);
// Tear down NAN
mDut.removeIface(nanIface);
mTestLooper.dispatchAll();
inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(true);
verify(chipMock.chip, times(1)).removeNanIface("wlan0");
verify(nanDestroyedListener).onDestroyed(getName(nanIface));
verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener, staAvailListener,
staDestroyedListener2, apDestroyedListener, apAvailListener, p2pDestroyedListener,
nanDestroyedListener, nanAvailListener, p2pDestroyedListener2);
}
/**
* Validate P2P and NAN interactions. Expect:
* - STA created
* - NAN created
* - When P2P requested:
* - NAN torn down
* - P2P created
* - NAN creation refused
* - When P2P destroyed:
* - get nan available listener
* - Can create NAN when requested
*/
@Test
public void testP2pAndNanInteractionsTestChipV1() throws Exception {
runP2pAndNanExclusiveInteractionsTestChip(new TestChipV1(), TestChipV1.STA_CHIP_MODE_ID);
}
/**
* Validates that trying to allocate a STA and then another STA fails. Only one STA at a time
* is permitted (by TestChipV1 chip).
*/
@Test
public void testDuplicateStaRequestsTestChipV1() throws Exception {
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
InterfaceDestroyedListener staDestroyedListener1 = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener1 = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InterfaceDestroyedListener staDestroyedListener2 = mock(
InterfaceDestroyedListener.class);
// get STA interface
IWifiIface staIface1 = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
IfaceType.STA, // ifaceTypeToCreate
"wlan0", // ifaceName
TestChipV1.STA_CHIP_MODE_ID, // finalChipMode
null, // tearDownList
staDestroyedListener1, // destroyedListener
staAvailListener1 // availableListener
);
collector.checkThat("STA created", staIface1, IsNull.notNullValue());
verify(staAvailListener1).onAvailabilityChanged(false);
// get STA interface again
IWifiIface staIface2 = mDut.createStaIface(staDestroyedListener2, mHandler);
collector.checkThat("STA created", staIface2, IsNull.nullValue());
verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener1,
staAvailListener1, staDestroyedListener2);
}
/**
* Validate that the getSupportedIfaceTypes API works when requesting for all chips.
*/
@Test
public void testGetSupportedIfaceTypesAllTestChipV1() throws Exception {
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
// try API
Set<Integer> results = mDut.getSupportedIfaceTypes();
// verify results
Set<Integer> correctResults = new HashSet<>();
correctResults.add(IfaceType.AP);
correctResults.add(IfaceType.STA);
correctResults.add(IfaceType.P2P);
correctResults.add(IfaceType.NAN);
assertEquals(correctResults, results);
}
/**
* Validate that the getSupportedIfaceTypes API works when requesting for a specific chip.
*/
@Test
public void testGetSupportedIfaceTypesOneChipTestChipV1() throws Exception {
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
// try API
Set<Integer> results = mDut.getSupportedIfaceTypes(chipMock.chip);
// verify results
Set<Integer> correctResults = new HashSet<>();
correctResults.add(IfaceType.AP);
correctResults.add(IfaceType.STA);
correctResults.add(IfaceType.P2P);
correctResults.add(IfaceType.NAN);
assertEquals(correctResults, results);
}
/**
* Validate {@link HalDeviceManager#canSupportIfaceCombo(SparseArray)}
*/
@Test
public void testCanSupportIfaceComboTestChipV1() throws Exception {
final String name = "wlan0";
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
assertTrue(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.STA, 1);
}}
));
assertTrue(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.AP, 1);
}}
));
assertTrue(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.P2P, 1);
}}
));
assertTrue(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.NAN, 1);
}}
));
assertTrue(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.STA, 1);
put(IfaceType.P2P, 1);
}}
));
assertTrue(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.STA, 1);
put(IfaceType.NAN, 1);
}}
));
assertFalse(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.STA, 1);
put(IfaceType.AP, 1);
}}
));
assertFalse(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.STA, 2);
}}
));
assertFalse(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.P2P, 1);
put(IfaceType.NAN, 1);
}}
));
verifyNoMoreInteractions(mManagerStatusListenerMock);
}
//////////////////////////////////////////////////////////////////////////////////////
// TestChipV2 Specific Tests
//////////////////////////////////////////////////////////////////////////////////////
/**
* Validate a flow sequence for test chip 2:
* - create STA
* - create P2P
* - request NAN: failure
* - create AP
* - create STA: will get refused
* - create AP: will get refused
* - tear down AP
* - create STA
* - create STA: will get refused
* - create AP: should get created and the last created STA should get destroyed
* - tear down P2P
* - create NAN
*/
@Test
public void testInterfaceCreationFlowTestChipV2() throws Exception {
TestChipV2 chipMock = new TestChipV2();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
InterfaceDestroyedListener staDestroyedListener = mock(
InterfaceDestroyedListener.class);
InterfaceDestroyedListener staDestroyedListener2 = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InterfaceDestroyedListener apDestroyedListener = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener apAvailListener = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InterfaceDestroyedListener p2pDestroyedListener = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener p2pAvailListener = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InterfaceDestroyedListener nanDestroyedListener = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InOrder inOrderAvail = inOrder(staAvailListener, apAvailListener, p2pAvailListener,
nanAvailListener);
// register listeners for interface availability
mDut.registerInterfaceAvailableForRequestListener(IfaceType.STA, staAvailListener,
mHandler);
mDut.registerInterfaceAvailableForRequestListener(IfaceType.AP, apAvailListener, mHandler);
mDut.registerInterfaceAvailableForRequestListener(IfaceType.P2P, p2pAvailListener,
mHandler);
mDut.registerInterfaceAvailableForRequestListener(IfaceType.NAN, nanAvailListener,
mHandler);
mTestLooper.dispatchAll();
inOrderAvail.verify(staAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(apAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(true);
// create STA
when(mClock.getUptimeSinceBootMillis()).thenReturn(15L);
IWifiIface staIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
IfaceType.STA, // ifaceTypeToCreate
"wlan0", // ifaceName
TestChipV2.CHIP_MODE_ID, // finalChipMode
null, // tearDownList
staDestroyedListener, // destroyedListener
null // availableListener (already registered)
);
collector.checkThat("STA interface wasn't created", staIface, IsNull.notNullValue());
// create P2P
IWifiIface p2pIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV2.CHIP_MODE_ID, // chipModeId
IfaceType.P2P, // ifaceTypeToCreate
"p2p0", // ifaceName
TestChipV2.CHIP_MODE_ID, // finalChipMode
null, // tearDownList
p2pDestroyedListener, // destroyedListener
null // availableListener (already registered)
);
collector.checkThat("P2P interface wasn't created", p2pIface, IsNull.notNullValue());
inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(false);
// create NAN
IWifiIface nanIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV2.CHIP_MODE_ID, // chipModeId
IfaceType.NAN, // ifaceTypeToCreate
"wlan0", // ifaceName
TestChipV2.CHIP_MODE_ID, // finalChipMode
null, // tearDownList
nanDestroyedListener, // destroyedListener
null, // availableListener (already registered)
new InterfaceDestroyedListenerWithIfaceName(
getName(p2pIface), p2pDestroyedListener)
);
collector.checkThat("NAN interface wasn't created", nanIface, IsNull.notNullValue());
inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(false);
// create AP
IWifiIface apIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV2.CHIP_MODE_ID, // chipModeId
IfaceType.AP, // ifaceTypeToCreate
"wlan1", // ifaceName
TestChipV2.CHIP_MODE_ID, // finalChipMode
null, // tearDownList
apDestroyedListener, // destroyedListener
null // availableListener (already registered)
);
collector.checkThat("AP interface wasn't created", apIface, IsNull.notNullValue());
inOrderAvail.verify(apAvailListener).onAvailabilityChanged(false);
inOrderAvail.verify(staAvailListener).onAvailabilityChanged(false);
// request STA2: should fail
IWifiIface staIface2 = mDut.createStaIface(null, null);
collector.checkThat("STA2 should not be created", staIface2, IsNull.nullValue());
// request AP2: should fail
IWifiIface apIface2 = mDut.createApIface(null, null);
collector.checkThat("AP2 should not be created", apIface2, IsNull.nullValue());
// tear down AP
mDut.removeIface(apIface);
mTestLooper.dispatchAll();
inOrderAvail.verify(apAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(staAvailListener).onAvailabilityChanged(true);
verify(chipMock.chip).removeApIface("wlan1");
verify(apDestroyedListener).onDestroyed(getName(apIface));
// create STA2: using a later clock
when(mClock.getUptimeSinceBootMillis()).thenReturn(20L);
staIface2 = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV2.CHIP_MODE_ID, // chipModeId
IfaceType.STA, // ifaceTypeToCreate
"wlan1", // ifaceName
TestChipV2.CHIP_MODE_ID, // finalChipMode
null, // tearDownList
staDestroyedListener2, // destroyedListener
null // availableListener (already registered)
);
collector.checkThat("STA 2 interface wasn't created", staIface2, IsNull.notNullValue());
inOrderAvail.verify(staAvailListener).onAvailabilityChanged(false);
// request STA3: should fail
IWifiIface staIface3 = mDut.createStaIface(null, null);
collector.checkThat("STA3 should not be created", staIface3, IsNull.nullValue());
// create AP - this will destroy the last STA created, i.e. STA2
apIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV2.CHIP_MODE_ID, // chipModeId
IfaceType.AP, // ifaceTypeToCreate
"wlan1", // ifaceName
TestChipV2.CHIP_MODE_ID, // finalChipMode
null, // tearDownList
apDestroyedListener, // destroyedListener
null, // availableListener (already registered),
// destroyedInterfacesDestroyedListeners...
new InterfaceDestroyedListenerWithIfaceName(
getName(staIface2), staDestroyedListener2)
);
collector.checkThat("AP interface wasn't created", apIface, IsNull.notNullValue());
inOrderAvail.verify(apAvailListener).onAvailabilityChanged(false);
// tear down NAN
mDut.removeIface(nanIface);
mTestLooper.dispatchAll();
inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(true);
verify(chipMock.chip).removeNanIface("wlan0");
verify(nanDestroyedListener).onDestroyed(getName(nanIface));
// create NAN
nanIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV2.CHIP_MODE_ID, // chipModeId
IfaceType.NAN, // ifaceTypeToCreate
"wlan0", // ifaceName
TestChipV2.CHIP_MODE_ID, // finalChipMode
null, // tearDownList
nanDestroyedListener, // destroyedListener
null // availableListener (already registered)
);
collector.checkThat("NAN interface wasn't created", nanIface, IsNull.notNullValue());
inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(false);
verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener,
staDestroyedListener2, apDestroyedListener, p2pDestroyedListener,
nanDestroyedListener, staAvailListener, apAvailListener, p2pAvailListener,
nanAvailListener, staAvailListener, apAvailListener, p2pAvailListener,
nanAvailListener);
}
/**
* Validate P2P and NAN interactions. Expect:
* - STA created
* - NAN created
* - When P2P requested:
* - NAN torn down
* - P2P created
* - NAN creation refused
* - When P2P destroyed:
* - get nan available listener
* - Can create NAN when requested
*/
@Test
public void testP2pAndNanInteractionsTestChipV2() throws Exception {
runP2pAndNanExclusiveInteractionsTestChip(new TestChipV2(), TestChipV2.CHIP_MODE_ID);
}
/**
* Validate that the getSupportedIfaceTypes API works when requesting for all chips.
*/
@Test
public void testGetSupportedIfaceTypesAllTestChipV2() throws Exception {
TestChipV2 chipMock = new TestChipV2();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
// try API
Set<Integer> results = mDut.getSupportedIfaceTypes();
// verify results
Set<Integer> correctResults = new HashSet<>();
correctResults.add(IfaceType.AP);
correctResults.add(IfaceType.STA);
correctResults.add(IfaceType.P2P);
correctResults.add(IfaceType.NAN);
assertEquals(correctResults, results);
}
/**
* Validate that the getSupportedIfaceTypes API works when requesting for a specific chip.
*/
@Test
public void testGetSupportedIfaceTypesOneChipTestChipV2() throws Exception {
TestChipV2 chipMock = new TestChipV2();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
// try API
Set<Integer> results = mDut.getSupportedIfaceTypes(chipMock.chip);
// verify results
Set<Integer> correctResults = new HashSet<>();
correctResults.add(IfaceType.AP);
correctResults.add(IfaceType.STA);
correctResults.add(IfaceType.P2P);
correctResults.add(IfaceType.NAN);
assertEquals(correctResults, results);
}
/**
* Validate {@link HalDeviceManager#canSupportIfaceCombo(SparseArray)}
*/
@Test
public void testCanSupportIfaceComboTestChipV2() throws Exception {
final String name = "wlan0";
TestChipV2 chipMock = new TestChipV2();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
assertTrue(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.STA, 1);
}}
));
assertTrue(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.AP, 1);
}}
));
assertTrue(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.P2P, 1);
}}
));
assertTrue(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.NAN, 1);
}}
));
assertTrue(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.STA, 1);
put(IfaceType.P2P, 1);
}}
));
assertTrue(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.STA, 1);
put(IfaceType.NAN, 1);
}}
));
assertTrue(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.STA, 1);
put(IfaceType.AP, 1);
}}
));
assertTrue(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.STA, 2);
}}
));
assertTrue(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.P2P, 1);
put(IfaceType.AP, 1);
}}
));
assertTrue(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.STA, 1);
put(IfaceType.P2P, 1);
put(IfaceType.AP, 1);
}}
));
assertTrue(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.STA, 1);
put(IfaceType.AP, 1);
put(IfaceType.NAN, 1);
}}
));
assertFalse(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.P2P, 1);
put(IfaceType.NAN, 1);
}}
));
assertFalse(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.AP, 2);
}}
));
assertFalse(mDut.canSupportIfaceCombo(new SparseArray<Integer>() {{
put(IfaceType.STA, 2);
put(IfaceType.AP, 1);
}}
));
verifyNoMoreInteractions(mManagerStatusListenerMock);
}
//////////////////////////////////////////////////////////////////////////////////////
// TestChipV3 Specific Tests
//////////////////////////////////////////////////////////////////////////////////////
/**
* Validate a flow sequence for test chip 3:
* - create STA
* - create P2P
* - request NAN: failure
* - create AP: should tear down P2P first
* - create STA: will get refused
* - create AP: will get refused
* - request P2P: failure
* - tear down AP
* - create STA
* - create STA: will get refused
* - create NAN: should tear down last created STA
* - create STA: will get refused
*/
@Test
public void testInterfaceCreationFlowTestChipV3() throws Exception {
TestChipV3 chipMock = new TestChipV3();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
InterfaceDestroyedListener staDestroyedListener = mock(
InterfaceDestroyedListener.class);
InterfaceDestroyedListener staDestroyedListener2 = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InterfaceDestroyedListener apDestroyedListener = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener apAvailListener = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InterfaceDestroyedListener p2pDestroyedListener = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener p2pAvailListener = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InterfaceDestroyedListener nanDestroyedListener = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InOrder inOrderAvail = inOrder(staAvailListener, apAvailListener, p2pAvailListener,
nanAvailListener);
// register listeners for interface availability
mDut.registerInterfaceAvailableForRequestListener(IfaceType.STA, staAvailListener,
mHandler);
mDut.registerInterfaceAvailableForRequestListener(IfaceType.AP, apAvailListener, mHandler);
mDut.registerInterfaceAvailableForRequestListener(IfaceType.P2P, p2pAvailListener,
mHandler);
mDut.registerInterfaceAvailableForRequestListener(IfaceType.NAN, nanAvailListener,
mHandler);
mTestLooper.dispatchAll();
inOrderAvail.verify(staAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(apAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(true);
// create STA
when(mClock.getUptimeSinceBootMillis()).thenReturn(15L);
IWifiIface staIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
IfaceType.STA, // ifaceTypeToCreate
"wlan0", // ifaceName
TestChipV3.CHIP_MODE_ID, // finalChipMode
null, // tearDownList
staDestroyedListener, // destroyedListener
null // availableListener (already registered)
);
collector.checkThat("STA interface wasn't created", staIface, IsNull.notNullValue());
// create P2P
IWifiIface p2pIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV3.CHIP_MODE_ID, // chipModeId
IfaceType.P2P, // ifaceTypeToCreate
"p2p0", // ifaceName
TestChipV3.CHIP_MODE_ID, // finalChipMode
null, // tearDownList
p2pDestroyedListener, // destroyedListener
null // availableListener (already registered)
);
collector.checkThat("P2P interface wasn't created", p2pIface, IsNull.notNullValue());
inOrderAvail.verify(staAvailListener).onAvailabilityChanged(false);
inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(false);
// create NAN
IWifiIface nanIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV3.CHIP_MODE_ID, // chipModeId
IfaceType.NAN, // ifaceTypeToCreate
"wlan0", // ifaceName
TestChipV3.CHIP_MODE_ID, // finalChipMode
null, // tearDownList
nanDestroyedListener, // destroyedListener
null, // availableListener (already registered)
new InterfaceDestroyedListenerWithIfaceName("p2p0", p2pDestroyedListener)
);
collector.checkThat("NAN interface wasn't created", nanIface, IsNull.notNullValue());
inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(false);
// create AP: will destroy P2P
IWifiIface apIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV3.CHIP_MODE_ID, // chipModeId
IfaceType.AP, // ifaceTypeToCreate
"wlan1", // ifaceName
TestChipV3.CHIP_MODE_ID, // finalChipMode
null, // tearDownList
apDestroyedListener, // destroyedListener
null, // availableListener (already registered)
new InterfaceDestroyedListenerWithIfaceName("wlan0", nanDestroyedListener)
);
collector.checkThat("AP interface wasn't created", apIface, IsNull.notNullValue());
verify(chipMock.chip).removeP2pIface("p2p0");
inOrderAvail.verify(apAvailListener).onAvailabilityChanged(false);
inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(false);
// request STA2: should fail
IWifiIface staIface2 = mDut.createStaIface(null, null);
collector.checkThat("STA2 should not be created", staIface2, IsNull.nullValue());
// request AP2: should fail
IWifiIface apIface2 = mDut.createApIface(null, null);
collector.checkThat("AP2 should not be created", apIface2, IsNull.nullValue());
// request P2P: should fail
p2pIface = mDut.createP2pIface(null, null);
collector.checkThat("P2P should not be created", p2pIface, IsNull.nullValue());
// tear down AP
mDut.removeIface(apIface);
mTestLooper.dispatchAll();
inOrderAvail.verify(apAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(staAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(true);
verify(chipMock.chip).removeApIface("wlan1");
verify(apDestroyedListener).onDestroyed(getName(apIface));
// create STA2: using a later clock
when(mClock.getUptimeSinceBootMillis()).thenReturn(20L);
staIface2 = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV3.CHIP_MODE_ID, // chipModeId
IfaceType.STA, // ifaceTypeToCreate
"wlan1", // ifaceName
TestChipV3.CHIP_MODE_ID, // finalChipMode
null, // tearDownList
staDestroyedListener2, // destroyedListener
null // availableListener (already registered)
);
collector.checkThat("STA 2 interface wasn't created", staIface2, IsNull.notNullValue());
inOrderAvail.verify(staAvailListener).onAvailabilityChanged(false);
// request STA3: should fail
IWifiIface staIface3 = mDut.createStaIface(null, null);
collector.checkThat("STA3 should not be created", staIface3, IsNull.nullValue());
// create NAN: should destroy the last created STA (STA2)
nanIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV3.CHIP_MODE_ID, // chipModeId
IfaceType.NAN, // ifaceTypeToCreate
"wlan0", // ifaceName
TestChipV3.CHIP_MODE_ID, // finalChipMode
null, // tearDownList
nanDestroyedListener, // destroyedListener
null, // availableListener (already registered)
new InterfaceDestroyedListenerWithIfaceName(
getName(staIface2), staDestroyedListener2)
);
collector.checkThat("NAN interface wasn't created", nanIface, IsNull.notNullValue());
inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(false);
verify(chipMock.chip).removeStaIface("wlan1");
verify(staDestroyedListener2).onDestroyed(getName(staIface2));
// request STA2: should fail
staIface2 = mDut.createStaIface(null, null);
collector.checkThat("STA2 should not be created", staIface2, IsNull.nullValue());
verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener,
staDestroyedListener2, apDestroyedListener, p2pDestroyedListener,
nanDestroyedListener, staAvailListener, apAvailListener, p2pAvailListener,
nanAvailListener, staAvailListener, apAvailListener, p2pAvailListener,
nanAvailListener);
}
/**
* Validate P2P and NAN interactions. Expect:
* - STA created
* - NAN created
* - When P2P requested:
* - NAN torn down
* - P2P created
* - NAN creation refused
* - When P2P destroyed:
* - get nan available listener
* - Can create NAN when requested
*/
@Test
public void testP2pAndNanInteractionsTestChipV3() throws Exception {
runP2pAndNanExclusiveInteractionsTestChip(new TestChipV3(), TestChipV3.CHIP_MODE_ID);
}
/**
* Validate that the getSupportedIfaceTypes API works when requesting for all chips.
*/
@Test
public void testGetSupportedIfaceTypesAllTestChipV3() throws Exception {
TestChipV3 chipMock = new TestChipV3();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
// try API
Set<Integer> results = mDut.getSupportedIfaceTypes();
// verify results
Set<Integer> correctResults = new HashSet<>();
correctResults.add(IfaceType.AP);
correctResults.add(IfaceType.STA);
correctResults.add(IfaceType.P2P);
correctResults.add(IfaceType.NAN);
assertEquals(correctResults, results);
}
/**
* Validate that the getSupportedIfaceTypes API works when requesting for a specific chip.
*/
@Test
public void testGetSupportedIfaceTypesOneChipTestChipV3() throws Exception {
TestChipV3 chipMock = new TestChipV3();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
// try API
Set<Integer> results = mDut.getSupportedIfaceTypes(chipMock.chip);
// verify results
Set<Integer> correctResults = new HashSet<>();
correctResults.add(IfaceType.AP);
correctResults.add(IfaceType.STA);
correctResults.add(IfaceType.P2P);
correctResults.add(IfaceType.NAN);
assertEquals(correctResults, results);
}
//////////////////////////////////////////////////////////////////////////////////////
// TestChipV4 Specific Tests
//////////////////////////////////////////////////////////////////////////////////////
/**
* Validate a flow sequence for test chip 4:
* - create STA
* - create P2P
* - request NAN: failure
* - create AP: should tear down P2P first
* - create STA: will get refused
* - create AP: will get refused
* - request P2P: failure
* - tear down AP
* - create STA: will get refused
* - create NAN
* - create STA: will get refused
*/
@Test
public void testInterfaceCreationFlowTestChipV4() throws Exception {
TestChipV4 chipMock = new TestChipV4();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
InterfaceDestroyedListener staDestroyedListener = mock(
InterfaceDestroyedListener.class);
InterfaceDestroyedListener staDestroyedListener2 = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InterfaceDestroyedListener apDestroyedListener = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener apAvailListener = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InterfaceDestroyedListener p2pDestroyedListener = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener p2pAvailListener = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InterfaceDestroyedListener nanDestroyedListener = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InOrder inOrderAvail = inOrder(staAvailListener, apAvailListener, p2pAvailListener,
nanAvailListener);
// register listeners for interface availability
mDut.registerInterfaceAvailableForRequestListener(IfaceType.STA, staAvailListener,
mHandler);
mDut.registerInterfaceAvailableForRequestListener(IfaceType.AP, apAvailListener, mHandler);
mDut.registerInterfaceAvailableForRequestListener(IfaceType.P2P, p2pAvailListener,
mHandler);
mDut.registerInterfaceAvailableForRequestListener(IfaceType.NAN, nanAvailListener,
mHandler);
mTestLooper.dispatchAll();
inOrderAvail.verify(staAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(apAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(true);
// create STA
when(mClock.getUptimeSinceBootMillis()).thenReturn(15L);
IWifiIface staIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
IfaceType.STA, // ifaceTypeToCreate
"wlan0", // ifaceName
TestChipV4.CHIP_MODE_ID, // finalChipMode
null, // tearDownList
staDestroyedListener, // destroyedListener
null // availableListener (already registered)
);
collector.checkThat("STA interface wasn't created", staIface, IsNull.notNullValue());
inOrderAvail.verify(staAvailListener).onAvailabilityChanged(false);
// create P2P
IWifiIface p2pIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV4.CHIP_MODE_ID, // chipModeId
IfaceType.P2P, // ifaceTypeToCreate
"p2p0", // ifaceName
TestChipV4.CHIP_MODE_ID, // finalChipMode
null, // tearDownList
p2pDestroyedListener, // destroyedListener
null // availableListener (already registered)
);
collector.checkThat("P2P interface wasn't created", p2pIface, IsNull.notNullValue());
inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(false);
// create NAN: will destroy P2P
IWifiIface nanIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV4.CHIP_MODE_ID, // chipModeId
IfaceType.NAN, // ifaceTypeToCreate
"wlan0", // ifaceName
TestChipV4.CHIP_MODE_ID, // finalChipMode
null, // tearDownList
nanDestroyedListener, // destroyedListener
nanAvailListener, // availableListener
new InterfaceDestroyedListenerWithIfaceName("p2p0", p2pDestroyedListener)
);
collector.checkThat("allocated NAN interface", nanIface, IsNull.notNullValue());
inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(false);
// create AP: will destroy NAN
IWifiIface apIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV4.CHIP_MODE_ID, // chipModeId
IfaceType.AP, // ifaceTypeToCreate
"wlan1", // ifaceName
TestChipV4.CHIP_MODE_ID, // finalChipMode
null, // tearDownList
apDestroyedListener, // destroyedListener
null, // availableListener (already registered)
new InterfaceDestroyedListenerWithIfaceName("wlan0", nanDestroyedListener)
);
collector.checkThat("AP interface wasn't created", apIface, IsNull.notNullValue());
verify(chipMock.chip).removeP2pIface("p2p0");
inOrderAvail.verify(apAvailListener).onAvailabilityChanged(false);
inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(false);
// request STA2: should fail
IWifiIface staIface2 = mDut.createStaIface(null, null);
collector.checkThat("STA2 should not be created", staIface2, IsNull.nullValue());
// request AP2: should fail
IWifiIface apIface2 = mDut.createApIface(null, null);
collector.checkThat("AP2 should not be created", apIface2, IsNull.nullValue());
// request P2P: should fail
p2pIface = mDut.createP2pIface(null, null);
collector.checkThat("P2P should not be created", p2pIface, IsNull.nullValue());
// tear down AP
mDut.removeIface(apIface);
mTestLooper.dispatchAll();
inOrderAvail.verify(apAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(p2pAvailListener).onAvailabilityChanged(true);
inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(true);
verify(chipMock.chip).removeApIface("wlan1");
verify(apDestroyedListener).onDestroyed(getName(apIface));
// request STA2: should fail
staIface2 = mDut.createStaIface(null, null);
collector.checkThat("STA2 should not be created", staIface2, IsNull.nullValue());
// create NAN
nanIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV4.CHIP_MODE_ID, // chipModeId
IfaceType.NAN, // ifaceTypeToCreate
"wlan0", // ifaceName
TestChipV4.CHIP_MODE_ID, // finalChipMode
null, // tearDownList
nanDestroyedListener, // destroyedListener
null // availableListener (already registered)
);
collector.checkThat("NAN interface wasn't created", nanIface, IsNull.notNullValue());
inOrderAvail.verify(nanAvailListener).onAvailabilityChanged(false);
// request STA2: should fail
staIface2 = mDut.createStaIface(null, null);
collector.checkThat("STA2 should not be created", staIface2, IsNull.nullValue());
// tear down STA
mDut.removeIface(staIface);
mTestLooper.dispatchAll();
inOrderAvail.verify(staAvailListener).onAvailabilityChanged(true);
verify(chipMock.chip).removeStaIface("wlan0");
verify(staDestroyedListener).onDestroyed(getName(staIface));
verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener,
staDestroyedListener2, apDestroyedListener, p2pDestroyedListener,
nanDestroyedListener, staAvailListener, apAvailListener, p2pAvailListener,
nanAvailListener, staAvailListener, apAvailListener, p2pAvailListener,
nanAvailListener);
}
/**
* Validate P2P and NAN interactions. Expect:
* - STA created
* - NAN created
* - When P2P requested:
* - NAN torn down
* - P2P created
* - NAN creation refused
* - When P2P destroyed:
* - get nan available listener
* - Can create NAN when requested
*/
@Test
public void testP2pAndNanInteractionsTestChipV4() throws Exception {
runP2pAndNanExclusiveInteractionsTestChip(new TestChipV4(), TestChipV4.CHIP_MODE_ID);
}
/**
* Validate that the getSupportedIfaceTypes API works when requesting for all chips.
*/
@Test
public void testGetSupportedIfaceTypesAllTestChipV4() throws Exception {
TestChipV4 chipMock = new TestChipV4();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
// try API
Set<Integer> results = mDut.getSupportedIfaceTypes();
// verify results
Set<Integer> correctResults = new HashSet<>();
correctResults.add(IfaceType.AP);
correctResults.add(IfaceType.STA);
correctResults.add(IfaceType.P2P);
correctResults.add(IfaceType.NAN);
assertEquals(correctResults, results);
}
/**
* Validate that the getSupportedIfaceTypes API works when requesting for a specific chip.
*/
@Test
public void testGetSupportedIfaceTypesOneChipTestChipV4() throws Exception {
TestChipV4 chipMock = new TestChipV4();
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
// try API
Set<Integer> results = mDut.getSupportedIfaceTypes(chipMock.chip);
// verify results
Set<Integer> correctResults = new HashSet<>();
correctResults.add(IfaceType.AP);
correctResults.add(IfaceType.STA);
correctResults.add(IfaceType.P2P);
correctResults.add(IfaceType.NAN);
assertEquals(correctResults, results);
}
///////////////////////////////////////////////////////////////////////////////////////
// utilities
///////////////////////////////////////////////////////////////////////////////////////
private void dumpDut(String prefix) {
StringWriter sw = new StringWriter();
mDut.dump(null, new PrintWriter(sw), null);
Log.e("HalDeviceManager", prefix + sw.toString());
}
private void executeAndValidateInitializationSequence() throws Exception {
executeAndValidateInitializationSequence(true);
}
private void executeAndValidateInitializationSequence(boolean isSupported) throws Exception {
// act:
mDut.initialize();
// verify: service manager initialization sequence
mInOrder.verify(mServiceManagerMock).linkToDeath(any(IHwBinder.DeathRecipient.class),
anyLong());
mInOrder.verify(mServiceManagerMock).registerForNotifications(eq(IWifi.kInterfaceName),
eq(""), mServiceNotificationCaptor.capture());
// If not using the lazy version of the IWifi service, the process should already be up at
// this point.
mInOrder.verify(mServiceManagerMock).listManifestByInterface(eq(IWifi.kInterfaceName));
// verify: wifi initialization sequence if vendor HAL is supported.
if (isSupported) {
mInOrder.verify(mWifiMock).linkToDeath(mDeathRecipientCaptor.capture(), anyLong());
mInOrder.verify(mWifiMock).registerEventCallback(mWifiEventCallbackCaptor.capture());
// verify: onStop called as a part of initialize.
mInOrder.verify(mWifiMock).stop();
collector.checkThat("isReady is true", mDut.isReady(), equalTo(true));
} else {
collector.checkThat("isReady is false", mDut.isReady(), equalTo(false));
}
}
private void executeAndValidateStartupSequence() throws Exception {
executeAndValidateStartupSequence(1, true);
}
private void executeAndValidateStartupSequence(int numAttempts, boolean success)
throws Exception {
// act: register listener & start Wi-Fi
mDut.registerStatusListener(mManagerStatusListenerMock, mHandler);
collector.checkThat(mDut.start(), equalTo(success));
// verify
mInOrder.verify(mWifiMock, times(numAttempts)).start();
if (success) {
// act: trigger onStart callback of IWifiEventCallback
mWifiEventCallbackCaptor.getValue().onStart();
mTestLooper.dispatchAll();
// verify: onStart called on registered listener
mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
}
}
private void runCreateSingleXxxInterfaceNoInitMode(ChipMockBase chipMock, int ifaceTypeToCreate,
String ifaceName, int finalChipMode, boolean multipleIfaceSupport) throws Exception {
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
InterfaceDestroyedListener idl = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener iafrl = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InOrder availInOrder = inOrder(iafrl);
IWifiIface iface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
ifaceTypeToCreate,
ifaceName,
finalChipMode,
null, // tearDownList
idl, // destroyedListener
iafrl // availableListener
);
collector.checkThat("allocated interface", iface, IsNull.notNullValue());
availInOrder.verify(iafrl).onAvailabilityChanged(multipleIfaceSupport);
// act: remove interface
mDut.removeIface(iface);
mTestLooper.dispatchAll();
// verify: callback triggered
switch (ifaceTypeToCreate) {
case IfaceType.STA:
mInOrder.verify(chipMock.chip).removeStaIface(ifaceName);
break;
case IfaceType.AP:
mInOrder.verify(chipMock.chip).removeApIface(ifaceName);
break;
case IfaceType.P2P:
mInOrder.verify(chipMock.chip).removeP2pIface(ifaceName);
break;
case IfaceType.NAN:
mInOrder.verify(chipMock.chip).removeNanIface(ifaceName);
break;
}
verify(idl).onDestroyed(ifaceName);
if (!multipleIfaceSupport) {
availInOrder.verify(iafrl).onAvailabilityChanged(true);
}
verifyNoMoreInteractions(mManagerStatusListenerMock, idl, iafrl);
}
/**
* Validate P2P and NAN interactions. Expect:
* - STA created
* - NAN created
* - When P2P requested:
* - NAN torn down
* - P2P created
* - NAN creation refused
* - When P2P destroyed:
* - get nan available listener
* - Can create NAN when requested
*
* Relevant for any chip which supports STA + NAN || P2P (or a richer combination - but bottom
* line of NAN and P2P being exclusive).
*/
public void runP2pAndNanExclusiveInteractionsTestChip(ChipMockBase chipMock,
int onlyChipMode) throws Exception {
chipMock.initialize();
mInOrder = inOrder(mServiceManagerMock, mWifiMock, chipMock.chip,
mManagerStatusListenerMock);
executeAndValidateInitializationSequence();
executeAndValidateStartupSequence();
InterfaceDestroyedListener staDestroyedListener = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener staAvailListener = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InterfaceDestroyedListener nanDestroyedListener = mock(
InterfaceDestroyedListener.class);
HalDeviceManager.InterfaceAvailableForRequestListener nanAvailListener = mock(
HalDeviceManager.InterfaceAvailableForRequestListener.class);
InterfaceDestroyedListener p2pDestroyedListener = mock(
InterfaceDestroyedListener.class);
InOrder availInOrder = inOrder(staAvailListener, nanAvailListener);
// Request STA
IWifiIface staIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
IfaceType.STA, // ifaceTypeToCreate
"wlan0", // ifaceName
onlyChipMode, // finalChipMode
null, // tearDownList
staDestroyedListener, // destroyedListener
staAvailListener // availableListener
);
collector.checkThat("STA can't be created", staIface, IsNull.notNullValue());
availInOrder.verify(staAvailListener).onAvailabilityChanged(
chipMock.chipMockId == CHIP_MOCK_V2 || chipMock.chipMockId == CHIP_MOCK_V3);
// Request NAN
IWifiIface nanIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
onlyChipMode, // chipModeId
IfaceType.NAN, // ifaceTypeToCreate
"wlan0", // ifaceName
onlyChipMode, // finalChipMode
null, // tearDownList
nanDestroyedListener, // destroyedListener
nanAvailListener // availableListener
);
if (chipMock.chipMockId == CHIP_MOCK_V3) {
availInOrder.verify(staAvailListener).onAvailabilityChanged(false);
}
availInOrder.verify(nanAvailListener).onAvailabilityChanged(false);
// Request P2P
IWifiIface p2pIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
onlyChipMode, // chipModeId
IfaceType.P2P, // ifaceTypeToCreate
"p2p0", // ifaceName
onlyChipMode, // finalChipMode
new IWifiIface[]{nanIface}, // tearDownList
p2pDestroyedListener, // destroyedListener
null, // availableListener
// destroyedInterfacesDestroyedListeners...
new InterfaceDestroyedListenerWithIfaceName(
getName(nanIface), nanDestroyedListener)
);
collector.checkThat("P2P can't be created", p2pIface, IsNull.notNullValue());
availInOrder.verify(nanAvailListener).onAvailabilityChanged(true);
mTestLooper.dispatchAll();
verify(nanDestroyedListener).onDestroyed(getName(nanIface));
// Request NAN
nanIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
onlyChipMode, // chipModeId
IfaceType.NAN, // ifaceTypeToCreate
"wlan0", // ifaceName
onlyChipMode, // finalChipMode
new IWifiIface[]{p2pIface}, // tearDownList
nanDestroyedListener, // destroyedListener
nanAvailListener // availableListener
);
collector.checkThat("NAN can't be created", nanIface, IsNull.notNullValue());
availInOrder.verify(nanAvailListener).onAvailabilityChanged(false);
mTestLooper.dispatchAll();
verify(p2pDestroyedListener).onDestroyed(getName(p2pIface));
verifyNoMoreInteractions(mManagerStatusListenerMock, staDestroyedListener, staAvailListener,
nanDestroyedListener, nanAvailListener, p2pDestroyedListener);
}
private IWifiIface validateInterfaceSequence(ChipMockBase chipMock,
boolean chipModeValid, int chipModeId,
int ifaceTypeToCreate, String ifaceName, int finalChipMode,
IWifiIface[] tearDownList,
InterfaceDestroyedListener destroyedListener,
HalDeviceManager.InterfaceAvailableForRequestListener availableListener,
InterfaceDestroyedListenerWithIfaceName...destroyedInterfacesDestroyedListeners)
throws Exception {
// configure chip mode response
chipMock.chipModeValid = chipModeValid;
chipMock.chipModeId = chipModeId;
IWifiIface iface = null;
// configure: interface to be created
// act: request the interface
switch (ifaceTypeToCreate) {
case IfaceType.STA:
iface = mock(IWifiStaIface.class);
doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
any(IWifiIface.getNameCallback.class));
doAnswer(new GetTypeAnswer(IfaceType.STA)).when(iface).getType(
any(IWifiIface.getTypeCallback.class));
doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
chipMock.chip).createStaIface(any(IWifiChip.createStaIfaceCallback.class));
mDut.createStaIface(destroyedListener, mHandler);
break;
case IfaceType.AP:
iface = mock(IWifiApIface.class);
doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
any(IWifiIface.getNameCallback.class));
doAnswer(new GetTypeAnswer(IfaceType.AP)).when(iface).getType(
any(IWifiIface.getTypeCallback.class));
doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
chipMock.chip).createApIface(any(IWifiChip.createApIfaceCallback.class));
mDut.createApIface(destroyedListener, mHandler);
break;
case IfaceType.P2P:
iface = mock(IWifiP2pIface.class);
doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
any(IWifiIface.getNameCallback.class));
doAnswer(new GetTypeAnswer(IfaceType.P2P)).when(iface).getType(
any(IWifiIface.getTypeCallback.class));
doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
chipMock.chip).createP2pIface(any(IWifiChip.createP2pIfaceCallback.class));
mDut.createP2pIface(destroyedListener, mHandler);
break;
case IfaceType.NAN:
iface = mock(IWifiNanIface.class);
doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
any(IWifiIface.getNameCallback.class));
doAnswer(new GetTypeAnswer(IfaceType.NAN)).when(iface).getType(
any(IWifiIface.getTypeCallback.class));
doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
chipMock.chip).createNanIface(any(IWifiChip.createNanIfaceCallback.class));
mDut.createNanIface(destroyedListener, mHandler);
break;
}
if (availableListener != null) {
mDut.registerInterfaceAvailableForRequestListener(ifaceTypeToCreate, availableListener,
mHandler);
}
// validate: optional tear down of interfaces
if (tearDownList != null) {
for (IWifiIface tearDownIface: tearDownList) {
switch (getType(tearDownIface)) {
case IfaceType.STA:
mInOrder.verify(chipMock.chip).removeStaIface(getName(tearDownIface));
break;
case IfaceType.AP:
mInOrder.verify(chipMock.chip).removeApIface(getName(tearDownIface));
break;
case IfaceType.P2P:
mInOrder.verify(chipMock.chip).removeP2pIface(getName(tearDownIface));
break;
case IfaceType.NAN:
mInOrder.verify(chipMock.chip).removeNanIface(getName(tearDownIface));
break;
}
}
}
// validate: optional switch to the requested mode
if (!chipModeValid || chipModeId != finalChipMode) {
mInOrder.verify(chipMock.chip).configureChip(finalChipMode);
} else {
mInOrder.verify(chipMock.chip, times(0)).configureChip(anyInt());
}
// validate: create interface
switch (ifaceTypeToCreate) {
case IfaceType.STA:
mInOrder.verify(chipMock.chip).createStaIface(
any(IWifiChip.createStaIfaceCallback.class));
break;
case IfaceType.AP:
mInOrder.verify(chipMock.chip).createApIface(
any(IWifiChip.createApIfaceCallback.class));
break;
case IfaceType.P2P:
mInOrder.verify(chipMock.chip).createP2pIface(
any(IWifiChip.createP2pIfaceCallback.class));
break;
case IfaceType.NAN:
mInOrder.verify(chipMock.chip).createNanIface(
any(IWifiChip.createNanIfaceCallback.class));
break;
}
// verify: callbacks on deleted interfaces
mTestLooper.dispatchAll();
for (int i = 0; i < destroyedInterfacesDestroyedListeners.length; ++i) {
destroyedInterfacesDestroyedListeners[i].validate();
}
return iface;
}
private int getType(IWifiIface iface) throws Exception {
Mutable<Integer> typeResp = new Mutable<>();
iface.getType((WifiStatus status, int type) -> {
typeResp.value = type;
});
return typeResp.value;
}
private String getName(IWifiIface iface) throws Exception {
Mutable<String> nameResp = new Mutable<>();
iface.getName((WifiStatus status, String name) -> {
nameResp.value = name;
});
return nameResp.value;
}
private WifiStatus getStatus(int code) {
WifiStatus status = new WifiStatus();
status.code = code;
return status;
}
private static class InterfaceDestroyedListenerWithIfaceName {
private final String mIfaceName;
@Mock private final InterfaceDestroyedListener mListener;
InterfaceDestroyedListenerWithIfaceName(
String ifaceName, InterfaceDestroyedListener listener) {
mIfaceName = ifaceName;
mListener = listener;
}
public void validate() {
verify(mListener).onDestroyed(mIfaceName);
}
}
private static class Mutable<E> {
public E value;
Mutable() {
value = null;
}
Mutable(E value) {
this.value = value;
}
}
// Answer objects
private class GetChipIdsAnswer extends MockAnswerUtil.AnswerWithArguments {
private WifiStatus mStatus;
private ArrayList<Integer> mChipIds;
GetChipIdsAnswer(WifiStatus status, ArrayList<Integer> chipIds) {
mStatus = status;
mChipIds = chipIds;
}
public void answer(IWifi.getChipIdsCallback cb) {
cb.onValues(mStatus, mChipIds);
}
}
private class GetChipAnswer extends MockAnswerUtil.AnswerWithArguments {
private WifiStatus mStatus;
private IWifiChip mChip;
GetChipAnswer(WifiStatus status, IWifiChip chip) {
mStatus = status;
mChip = chip;
}
public void answer(int chipId, IWifi.getChipCallback cb) {
cb.onValues(mStatus, mChip);
}
}
private class GetIdAnswer extends MockAnswerUtil.AnswerWithArguments {
private ChipMockBase mChipMockBase;
GetIdAnswer(ChipMockBase chipMockBase) {
mChipMockBase = chipMockBase;
}
public void answer(IWifiChip.getIdCallback cb) {
cb.onValues(mStatusOk, mChipMockBase.chipId);
}
}
private class GetAvailableModesAnswer extends MockAnswerUtil.AnswerWithArguments {
private ChipMockBase mChipMockBase;
GetAvailableModesAnswer(ChipMockBase chipMockBase) {
mChipMockBase = chipMockBase;
}
public void answer(IWifiChip.getAvailableModesCallback cb) {
cb.onValues(mStatusOk, mChipMockBase.availableModes);
}
}
private class GetModeAnswer extends MockAnswerUtil.AnswerWithArguments {
private ChipMockBase mChipMockBase;
GetModeAnswer(ChipMockBase chipMockBase) {
mChipMockBase = chipMockBase;
}
public void answer(IWifiChip.getModeCallback cb) {
cb.onValues(mChipMockBase.chipModeValid ? mStatusOk
: getStatus(WifiStatusCode.ERROR_NOT_AVAILABLE), mChipMockBase.chipModeId);
}
}
private class ConfigureChipAnswer extends MockAnswerUtil.AnswerWithArguments {
private ChipMockBase mChipMockBase;
ConfigureChipAnswer(ChipMockBase chipMockBase) {
mChipMockBase = chipMockBase;
}
public WifiStatus answer(int chipMode) {
mChipMockBase.chipModeValid = true;
mChipMockBase.chipModeId = chipMode;
return mStatusOk;
}
}
private class GetXxxIfaceNamesAnswer extends MockAnswerUtil.AnswerWithArguments {
private ChipMockBase mChipMockBase;
GetXxxIfaceNamesAnswer(ChipMockBase chipMockBase) {
mChipMockBase = chipMockBase;
}
public void answer(IWifiChip.getStaIfaceNamesCallback cb) {
cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.STA));
}
public void answer(IWifiChip.getApIfaceNamesCallback cb) {
cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.AP));
}
public void answer(IWifiChip.getP2pIfaceNamesCallback cb) {
cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.P2P));
}
public void answer(IWifiChip.getNanIfaceNamesCallback cb) {
cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.NAN));
}
}
private class GetXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
private ChipMockBase mChipMockBase;
GetXxxIfaceAnswer(ChipMockBase chipMockBase) {
mChipMockBase = chipMockBase;
}
public void answer(String name, IWifiChip.getStaIfaceCallback cb) {
IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.STA).get(name);
cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiStaIface) iface);
}
public void answer(String name, IWifiChip.getApIfaceCallback cb) {
IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.AP).get(name);
cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiApIface) iface);
}
public void answer(String name, IWifiChip.getP2pIfaceCallback cb) {
IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.P2P).get(name);
cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiP2pIface) iface);
}
public void answer(String name, IWifiChip.getNanIfaceCallback cb) {
IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.NAN).get(name);
cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiNanIface) iface);
}
}
private class CreateXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
private ChipMockBase mChipMockBase;
private WifiStatus mStatus;
private IWifiIface mWifiIface;
CreateXxxIfaceAnswer(ChipMockBase chipMockBase, WifiStatus status, IWifiIface wifiIface) {
mChipMockBase = chipMockBase;
mStatus = status;
mWifiIface = wifiIface;
}
private void addInterfaceInfo(int type) {
if (mStatus.code == WifiStatusCode.SUCCESS) {
try {
mChipMockBase.interfaceNames.get(type).add(getName(mWifiIface));
mChipMockBase.interfacesByName.get(type).put(getName(mWifiIface), mWifiIface);
} catch (Exception e) {
// do nothing
}
}
}
public void answer(IWifiChip.createStaIfaceCallback cb) {
cb.onValues(mStatus, (IWifiStaIface) mWifiIface);
addInterfaceInfo(IfaceType.STA);
}
public void answer(IWifiChip.createApIfaceCallback cb) {
cb.onValues(mStatus, (IWifiApIface) mWifiIface);
addInterfaceInfo(IfaceType.AP);
}
public void answer(IWifiChip.createP2pIfaceCallback cb) {
cb.onValues(mStatus, (IWifiP2pIface) mWifiIface);
addInterfaceInfo(IfaceType.P2P);
}
public void answer(IWifiChip.createNanIfaceCallback cb) {
cb.onValues(mStatus, (IWifiNanIface) mWifiIface);
addInterfaceInfo(IfaceType.NAN);
}
}
private class CreateRttControllerAnswer extends MockAnswerUtil.AnswerWithArguments {
private final ChipMockBase mChipMockBase;
private final IWifiRttController mRttController;
CreateRttControllerAnswer(ChipMockBase chipMockBase, IWifiRttController rttController) {
mChipMockBase = chipMockBase;
mRttController = rttController;
}
public void answer(IWifiIface boundIface, IWifiChip.createRttControllerCallback cb) {
if (mChipMockBase.chipModeIdValidForRtt == mChipMockBase.chipModeId) {
cb.onValues(mStatusOk, mRttController);
} else {
cb.onValues(mStatusFail, null);
}
}
}
private class RemoveXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
private ChipMockBase mChipMockBase;
private int mType;
RemoveXxxIfaceAnswer(ChipMockBase chipMockBase, int type) {
mChipMockBase = chipMockBase;
mType = type;
}
private WifiStatus removeIface(int type, String ifname) {
try {
if (!mChipMockBase.interfaceNames.get(type).remove(ifname)) {
return mStatusFail;
}
if (mChipMockBase.interfacesByName.get(type).remove(ifname) == null) {
return mStatusFail;
}
} catch (Exception e) {
return mStatusFail;
}
return mStatusOk;
}
public WifiStatus answer(String ifname) {
return removeIface(mType, ifname);
}
}
private class GetNameAnswer extends MockAnswerUtil.AnswerWithArguments {
private String mName;
GetNameAnswer(String name) {
mName = name;
}
public void answer(IWifiIface.getNameCallback cb) {
cb.onValues(mStatusOk, mName);
}
}
private class GetTypeAnswer extends MockAnswerUtil.AnswerWithArguments {
private int mType;
GetTypeAnswer(int type) {
mType = type;
}
public void answer(IWifiIface.getTypeCallback cb) {
cb.onValues(mStatusOk, mType);
}
}
// chip configuration
private static final int CHIP_MOCK_V1 = 0;
private static final int CHIP_MOCK_V2 = 1;
private static final int CHIP_MOCK_V3 = 2;
private static final int CHIP_MOCK_V4 = 3;
private class ChipMockBase {
public int chipMockId;
public IWifiChip chip;
public int chipId;
public boolean chipModeValid = false;
public int chipModeId = -1000;
public int chipModeIdValidForRtt = -1; // single chip mode ID where RTT can be created
public Map<Integer, ArrayList<String>> interfaceNames = new HashMap<>();
public Map<Integer, Map<String, IWifiIface>> interfacesByName = new HashMap<>();
public ArrayList<IWifiChip.ChipMode> availableModes;
void initialize() throws Exception {
chip = mock(IWifiChip.class);
interfaceNames.put(IfaceType.STA, new ArrayList<>());
interfaceNames.put(IfaceType.AP, new ArrayList<>());
interfaceNames.put(IfaceType.P2P, new ArrayList<>());
interfaceNames.put(IfaceType.NAN, new ArrayList<>());
interfacesByName.put(IfaceType.STA, new HashMap<>());
interfacesByName.put(IfaceType.AP, new HashMap<>());
interfacesByName.put(IfaceType.P2P, new HashMap<>());
interfacesByName.put(IfaceType.NAN, new HashMap<>());
when(chip.registerEventCallback(any(IWifiChipEventCallback.class))).thenReturn(
mStatusOk);
when(chip.configureChip(anyInt())).thenAnswer(new ConfigureChipAnswer(this));
doAnswer(new GetIdAnswer(this)).when(chip).getId(any(IWifiChip.getIdCallback.class));
doAnswer(new GetModeAnswer(this)).when(chip).getMode(
any(IWifiChip.getModeCallback.class));
GetXxxIfaceNamesAnswer getXxxIfaceNamesAnswer = new GetXxxIfaceNamesAnswer(this);
doAnswer(getXxxIfaceNamesAnswer).when(chip).getStaIfaceNames(
any(IWifiChip.getStaIfaceNamesCallback.class));
doAnswer(getXxxIfaceNamesAnswer).when(chip).getApIfaceNames(
any(IWifiChip.getApIfaceNamesCallback.class));
doAnswer(getXxxIfaceNamesAnswer).when(chip).getP2pIfaceNames(
any(IWifiChip.getP2pIfaceNamesCallback.class));
doAnswer(getXxxIfaceNamesAnswer).when(chip).getNanIfaceNames(
any(IWifiChip.getNanIfaceNamesCallback.class));
GetXxxIfaceAnswer getXxxIfaceAnswer = new GetXxxIfaceAnswer(this);
doAnswer(getXxxIfaceAnswer).when(chip).getStaIface(anyString(),
any(IWifiChip.getStaIfaceCallback.class));
doAnswer(getXxxIfaceAnswer).when(chip).getApIface(anyString(),
any(IWifiChip.getApIfaceCallback.class));
doAnswer(getXxxIfaceAnswer).when(chip).getP2pIface(anyString(),
any(IWifiChip.getP2pIfaceCallback.class));
doAnswer(getXxxIfaceAnswer).when(chip).getNanIface(anyString(),
any(IWifiChip.getNanIfaceCallback.class));
doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.STA)).when(chip).removeStaIface(
anyString());
doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.AP)).when(chip).removeApIface(
anyString());
doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.P2P)).when(chip).removeP2pIface(
anyString());
doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.NAN)).when(chip).removeNanIface(
anyString());
doAnswer(new CreateRttControllerAnswer(this, mRttControllerMock)).when(
chip).createRttController(any(), any());
}
}
// test chip configuration V1:
// mode: STA + (NAN || P2P)
// mode: AP
private class TestChipV1 extends ChipMockBase {
static final int STA_CHIP_MODE_ID = 0;
static final int AP_CHIP_MODE_ID = 1;
void initialize() throws Exception {
super.initialize();
chipMockId = CHIP_MOCK_V1;
// chip Id configuration
ArrayList<Integer> chipIds;
chipId = 10;
chipIds = new ArrayList<>();
chipIds.add(chipId);
doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds(
any(IWifi.getChipIdsCallback.class));
doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(10),
any(IWifi.getChipCallback.class));
// initialize dummy chip modes
IWifiChip.ChipMode cm;
IWifiChip.ChipIfaceCombination cic;
IWifiChip.ChipIfaceCombinationLimit cicl;
// Mode 0: 1xSTA + 1x{P2P,NAN}
// Mode 1: 1xAP
availableModes = new ArrayList<>();
cm = new IWifiChip.ChipMode();
cm.id = STA_CHIP_MODE_ID;
cic = new IWifiChip.ChipIfaceCombination();
cicl = new IWifiChip.ChipIfaceCombinationLimit();
cicl.maxIfaces = 1;
cicl.types.add(IfaceType.STA);
cic.limits.add(cicl);
cicl = new IWifiChip.ChipIfaceCombinationLimit();
cicl.maxIfaces = 1;
cicl.types.add(IfaceType.P2P);
cicl.types.add(IfaceType.NAN);
cic.limits.add(cicl);
cm.availableCombinations.add(cic);
availableModes.add(cm);
cm = new IWifiChip.ChipMode();
cm.id = AP_CHIP_MODE_ID;
cic = new IWifiChip.ChipIfaceCombination();
cicl = new IWifiChip.ChipIfaceCombinationLimit();
cicl.maxIfaces = 1;
cicl.types.add(IfaceType.AP);
cic.limits.add(cicl);
cm.availableCombinations.add(cic);
availableModes.add(cm);
chipModeIdValidForRtt = STA_CHIP_MODE_ID;
doAnswer(new GetAvailableModesAnswer(this)).when(chip)
.getAvailableModes(any(IWifiChip.getAvailableModesCallback.class));
}
}
// test chip configuration V2:
// mode: STA + (STA || AP) + (NAN || P2P)
private class TestChipV2 extends ChipMockBase {
// only mode (different number from any in TestChipV1 so can catch test errors)
static final int CHIP_MODE_ID = 5;
void initialize() throws Exception {
super.initialize();
chipMockId = CHIP_MOCK_V2;
// chip Id configuration
ArrayList<Integer> chipIds;
chipId = 12;
chipIds = new ArrayList<>();
chipIds.add(chipId);
doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds(
any(IWifi.getChipIdsCallback.class));
doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(12),
any(IWifi.getChipCallback.class));
// initialize dummy chip modes
IWifiChip.ChipMode cm;
IWifiChip.ChipIfaceCombination cic;
IWifiChip.ChipIfaceCombinationLimit cicl;
// Mode 0 (only one): 1xSTA + 1x{STA,AP} + 1x{P2P,NAN}
availableModes = new ArrayList<>();
cm = new IWifiChip.ChipMode();
cm.id = CHIP_MODE_ID;
cic = new IWifiChip.ChipIfaceCombination();
cicl = new IWifiChip.ChipIfaceCombinationLimit();
cicl.maxIfaces = 1;
cicl.types.add(IfaceType.STA);
cic.limits.add(cicl);
cicl = new IWifiChip.ChipIfaceCombinationLimit();
cicl.maxIfaces = 1;
cicl.types.add(IfaceType.STA);
cicl.types.add(IfaceType.AP);
cic.limits.add(cicl);
cicl = new IWifiChip.ChipIfaceCombinationLimit();
cicl.maxIfaces = 1;
cicl.types.add(IfaceType.P2P);
cicl.types.add(IfaceType.NAN);
cic.limits.add(cicl);
cm.availableCombinations.add(cic);
availableModes.add(cm);
chipModeIdValidForRtt = CHIP_MODE_ID;
doAnswer(new GetAvailableModesAnswer(this)).when(chip)
.getAvailableModes(any(IWifiChip.getAvailableModesCallback.class));
}
}
// test chip configuration V3:
// mode:
// STA + (STA || AP)
// STA + (NAN || P2P)
private class TestChipV3 extends ChipMockBase {
// only mode (different number from any in other TestChips so can catch test errors)
static final int CHIP_MODE_ID = 7;
void initialize() throws Exception {
super.initialize();
chipMockId = CHIP_MOCK_V3;
// chip Id configuration
ArrayList<Integer> chipIds;
chipId = 15;
chipIds = new ArrayList<>();
chipIds.add(chipId);
doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds(
any(IWifi.getChipIdsCallback.class));
doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(15),
any(IWifi.getChipCallback.class));
// initialize dummy chip modes
IWifiChip.ChipMode cm;
IWifiChip.ChipIfaceCombination cic;
IWifiChip.ChipIfaceCombinationLimit cicl;
// Mode 0 (only one): 1xSTA + 1x{STA,AP}, 1xSTA + 1x{P2P,NAN}
availableModes = new ArrayList<>();
cm = new IWifiChip.ChipMode();
cm.id = CHIP_MODE_ID;
cic = new IWifiChip.ChipIfaceCombination();
cicl = new IWifiChip.ChipIfaceCombinationLimit();
cicl.maxIfaces = 1;
cicl.types.add(IfaceType.STA);
cic.limits.add(cicl);
cicl = new IWifiChip.ChipIfaceCombinationLimit();
cicl.maxIfaces = 1;
cicl.types.add(IfaceType.STA);
cicl.types.add(IfaceType.AP);
cic.limits.add(cicl);
cm.availableCombinations.add(cic);
cic = new IWifiChip.ChipIfaceCombination();
cicl = new IWifiChip.ChipIfaceCombinationLimit();
cicl.maxIfaces = 1;
cicl.types.add(IfaceType.STA);
cic.limits.add(cicl);
cicl = new IWifiChip.ChipIfaceCombinationLimit();
cicl.maxIfaces = 1;
cicl.types.add(IfaceType.P2P);
cicl.types.add(IfaceType.NAN);
cic.limits.add(cicl);
cm.availableCombinations.add(cic);
availableModes.add(cm);
chipModeIdValidForRtt = CHIP_MODE_ID;
doAnswer(new GetAvailableModesAnswer(this)).when(chip)
.getAvailableModes(any(IWifiChip.getAvailableModesCallback.class));
}
}
// test chip configuration V4:
// mode:
// STA + AP
// STA + (NAN || P2P)
private class TestChipV4 extends ChipMockBase {
// only mode (different number from any in other TestChips so can catch test errors)
static final int CHIP_MODE_ID = 15;
void initialize() throws Exception {
super.initialize();
chipMockId = CHIP_MOCK_V4;
// chip Id configuration
ArrayList<Integer> chipIds;
chipId = 23;
chipIds = new ArrayList<>();
chipIds.add(chipId);
doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds(
any(IWifi.getChipIdsCallback.class));
doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(23),
any(IWifi.getChipCallback.class));
// initialize dummy chip modes
IWifiChip.ChipMode cm;
IWifiChip.ChipIfaceCombination cic;
IWifiChip.ChipIfaceCombinationLimit cicl;
// Mode 0 (only one): 1xSTA + 1xAP, 1xSTA + 1x{P2P,NAN}
availableModes = new ArrayList<>();
cm = new IWifiChip.ChipMode();
cm.id = CHIP_MODE_ID;
cic = new IWifiChip.ChipIfaceCombination();
cicl = new IWifiChip.ChipIfaceCombinationLimit();
cicl.maxIfaces = 1;
cicl.types.add(IfaceType.STA);
cic.limits.add(cicl);
cicl = new IWifiChip.ChipIfaceCombinationLimit();
cicl.maxIfaces = 1;
cicl.types.add(IfaceType.AP);
cic.limits.add(cicl);
cm.availableCombinations.add(cic);
cic = new IWifiChip.ChipIfaceCombination();
cicl = new IWifiChip.ChipIfaceCombinationLimit();
cicl.maxIfaces = 1;
cicl.types.add(IfaceType.STA);
cic.limits.add(cicl);
cicl = new IWifiChip.ChipIfaceCombinationLimit();
cicl.maxIfaces = 1;
cicl.types.add(IfaceType.P2P);
cicl.types.add(IfaceType.NAN);
cic.limits.add(cicl);
cm.availableCombinations.add(cic);
availableModes.add(cm);
chipModeIdValidForRtt = CHIP_MODE_ID;
doAnswer(new GetAvailableModesAnswer(this)).when(chip)
.getAvailableModes(any(IWifiChip.getAvailableModesCallback.class));
}
}
}