blob: 12ef6ecccf495c73f712f9b497f9804d2f295142 [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 org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.eq;
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.net.InterfaceConfiguration;
import android.net.wifi.IApInterface;
import android.net.wifi.IClientInterface;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiScanner;
import android.os.INetworkManagementService;
import android.os.RemoteException;
import android.support.test.filters.SmallTest;
import com.android.server.net.BaseNetworkObserver;
import com.android.server.wifi.HalDeviceManager.InterfaceDestroyedListener;
import com.android.server.wifi.WifiNative.SupplicantDeathEventHandler;
import com.android.server.wifi.WifiNative.VendorHalDeathEventHandler;
import com.android.server.wifi.WifiNative.WificondDeathEventHandler;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
/**
* Unit tests for the interface management operations in
* {@link com.android.server.wifi.WifiNative}.
*/
@SmallTest
public class WifiNativeInterfaceManagementTest {
private static final String IFACE_NAME_0 = "mockWlan0";
private static final String IFACE_NAME_1 = "mockWlan1";
@Mock private WifiVendorHal mWifiVendorHal;
@Mock private WificondControl mWificondControl;
@Mock private SupplicantStaIfaceHal mSupplicantStaIfaceHal;
@Mock private HostapdHal mHostapdHal;
@Mock private WifiMonitor mWifiMonitor;
@Mock private INetworkManagementService mNwManagementService;
@Mock private PropertyService mPropertyService;
@Mock private WifiMetrics mWifiMetrics;
@Mock private WifiNative.StatusListener mStatusListener;
@Mock private WifiNative.InterfaceCallback mIfaceCallback0;
@Mock private WifiNative.InterfaceCallback mIfaceCallback1;
private final InterfaceConfiguration mInterfaceConfiguration = new InterfaceConfiguration();
private ArgumentCaptor<VendorHalDeathEventHandler> mWifiVendorHalDeathHandlerCaptor =
ArgumentCaptor.forClass(VendorHalDeathEventHandler.class);
private ArgumentCaptor<WificondDeathEventHandler> mWificondDeathHandlerCaptor =
ArgumentCaptor.forClass(WificondDeathEventHandler.class);
private ArgumentCaptor<WifiNative.VendorHalRadioModeChangeEventHandler>
mWifiVendorHalRadioModeChangeHandlerCaptor =
ArgumentCaptor.forClass(WifiNative.VendorHalRadioModeChangeEventHandler.class);
private ArgumentCaptor<SupplicantDeathEventHandler> mSupplicantDeathHandlerCaptor =
ArgumentCaptor.forClass(SupplicantDeathEventHandler.class);
private ArgumentCaptor<WifiNative.HostapdDeathEventHandler> mHostapdDeathHandlerCaptor =
ArgumentCaptor.forClass(WifiNative.HostapdDeathEventHandler.class);
private ArgumentCaptor<BaseNetworkObserver> mNetworkObserverCaptor0 =
ArgumentCaptor.forClass(BaseNetworkObserver.class);
private ArgumentCaptor<BaseNetworkObserver> mNetworkObserverCaptor1 =
ArgumentCaptor.forClass(BaseNetworkObserver.class);
private ArgumentCaptor<InterfaceDestroyedListener> mIfaceDestroyedListenerCaptor0 =
ArgumentCaptor.forClass(InterfaceDestroyedListener.class);
private ArgumentCaptor<InterfaceDestroyedListener> mIfaceDestroyedListenerCaptor1 =
ArgumentCaptor.forClass(InterfaceDestroyedListener.class);
private InOrder mInOrder;
private WifiNative mWifiNative;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
// Setup mocks for the positive single interface cases, individual tests can modify the
// mocks for negative or multi-interface tests.
when(mWifiVendorHal.initialize(mWifiVendorHalDeathHandlerCaptor.capture()))
.thenReturn(true);
doNothing().when(mWifiVendorHal).registerRadioModeChangeHandler(
mWifiVendorHalRadioModeChangeHandlerCaptor.capture());
when(mWifiVendorHal.isVendorHalSupported()).thenReturn(true);
when(mWifiVendorHal.startVendorHal()).thenReturn(true);
when(mWifiVendorHal.createStaIface(anyBoolean(), any())).thenReturn(IFACE_NAME_0);
when(mWifiVendorHal.createApIface(any())).thenReturn(IFACE_NAME_0);
when(mWifiVendorHal.removeStaIface(any())).thenReturn(true);
when(mWifiVendorHal.removeApIface(any())).thenReturn(true);
when(mWificondControl.initialize(mWificondDeathHandlerCaptor.capture()))
.thenReturn(true);
when(mWificondControl.enableSupplicant()).thenReturn(true);
when(mWificondControl.disableSupplicant()).thenReturn(true);
when(mWificondControl.startHostapd(any(), any())).thenReturn(true);
when(mWificondControl.stopHostapd(any())).thenReturn(true);
when(mWificondControl.setupInterfaceForClientMode(any()))
.thenReturn(mock(IClientInterface.class));
when(mWificondControl.setupInterfaceForSoftApMode(any()))
.thenReturn(mock(IApInterface.class));
when(mWificondControl.tearDownClientInterface(any())).thenReturn(true);
when(mWificondControl.tearDownSoftApInterface(any())).thenReturn(true);
when(mWificondControl.tearDownInterfaces()).thenReturn(true);
when(mSupplicantStaIfaceHal.registerDeathHandler(mSupplicantDeathHandlerCaptor.capture()))
.thenReturn(true);
when(mSupplicantStaIfaceHal.deregisterDeathHandler()).thenReturn(true);
when(mSupplicantStaIfaceHal.initialize()).thenReturn(true);
when(mSupplicantStaIfaceHal.isInitializationStarted()).thenReturn(false);
when(mSupplicantStaIfaceHal.isInitializationComplete()).thenReturn(true);
when(mSupplicantStaIfaceHal.setupIface(any())).thenReturn(true);
when(mSupplicantStaIfaceHal.teardownIface(any())).thenReturn(true);
when(mHostapdHal.registerDeathHandler(mHostapdDeathHandlerCaptor.capture()))
.thenReturn(true);
when(mHostapdHal.deregisterDeathHandler()).thenReturn(true);
when(mHostapdHal.initialize()).thenReturn(true);
when(mHostapdHal.isInitializationStarted()).thenReturn(false);
when(mHostapdHal.isInitializationComplete()).thenReturn(true);
when(mHostapdHal.addAccessPoint(any(), any())).thenReturn(true);
when(mHostapdHal.removeAccessPoint(any())).thenReturn(true);
when(mNwManagementService.getInterfaceConfig(IFACE_NAME_0))
.thenReturn(mInterfaceConfiguration);
mInOrder = inOrder(mWifiVendorHal, mWificondControl, mSupplicantStaIfaceHal, mHostapdHal,
mWifiMonitor, mNwManagementService, mIfaceCallback0, mIfaceCallback1, mWifiMetrics);
mWifiNative = new WifiNative(
mWifiVendorHal, mSupplicantStaIfaceHal, mHostapdHal, mWificondControl,
mWifiMonitor, mNwManagementService, mPropertyService, mWifiMetrics);
mWifiNative.initialize();
mWifiNative.registerStatusListener(mStatusListener);
mInOrder.verify(mWifiVendorHal).initialize(any());
mInOrder.verify(mWificondControl).initialize(any());
mInOrder.verify(mWifiVendorHal).registerRadioModeChangeHandler(any());
}
@After
public void tearDown() throws Exception {
verifyNoMoreInteractions(mWifiVendorHal, mWificondControl, mSupplicantStaIfaceHal,
mHostapdHal, mWifiMonitor, mNwManagementService, mIfaceCallback0, mIfaceCallback1,
mWifiMetrics);
}
/**
* Verifies the setup of a single client interface.
*/
@Test
public void testSetupClientInterface() throws Exception {
executeAndValidateSetupClientInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
assertEquals(IFACE_NAME_0, mWifiNative.getClientInterfaceName());
}
/**
* Verifies the setup of a single softAp interface.
*/
@Test
public void testSetupSoftApInterface() throws Exception {
executeAndValidateSetupSoftApInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
assertNull(mWifiNative.getClientInterfaceName());
}
/**
* Verifies the setup & teardown of a single client interface.
*/
@Test
public void testSetupAndTeardownClientInterface() throws Exception {
executeAndValidateSetupClientInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
assertEquals(IFACE_NAME_0, mWifiNative.getClientInterfaceName());
executeAndValidateTeardownClientInterface(false, false, IFACE_NAME_0, mIfaceCallback0,
mIfaceDestroyedListenerCaptor0.getValue(), mNetworkObserverCaptor0.getValue());
}
/**
* Verifies the setup & teardown of a single softAp interface.
*/
@Test
public void testSetupAndTeardownSoftApInterface() throws Exception {
executeAndValidateSetupSoftApInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
assertNull(mWifiNative.getClientInterfaceName());
executeAndValidateTeardownSoftApInterface(false, false, IFACE_NAME_0, mIfaceCallback0,
mIfaceDestroyedListenerCaptor0.getValue(), mNetworkObserverCaptor0.getValue());
}
/**
* Verifies the setup & teardown of a client & softAp interface.
*
* Sequence tested:
* a) Setup client interface.
* b) Setup softAp interface.
* c) Teardown client interface.
* d) Teardown softAp interface.
*/
@Test
public void testSetupAndTeardownClientAndSoftApInterface_Seq1() throws Exception {
executeAndValidateSetupClientInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
executeAndValidateSetupSoftApInterface(
true, false, IFACE_NAME_1, mIfaceCallback1, mIfaceDestroyedListenerCaptor1,
mNetworkObserverCaptor1);
assertEquals(IFACE_NAME_0, mWifiNative.getClientInterfaceName());
executeAndValidateTeardownClientInterface(false, true, IFACE_NAME_0, mIfaceCallback0,
mIfaceDestroyedListenerCaptor0.getValue(), mNetworkObserverCaptor0.getValue());
executeAndValidateTeardownSoftApInterface(false, false, IFACE_NAME_1, mIfaceCallback1,
mIfaceDestroyedListenerCaptor1.getValue(), mNetworkObserverCaptor1.getValue());
}
/**
* Verifies the setup & teardown of a client & softAp interface.
*
* Sequence tested:
* a) Setup client interface.
* b) Setup softAp interface.
* c) Teardown softAp interface.
* d) Teardown client interface.
*/
@Test
public void testSetupAndTeardownClientAndSoftApInterface_Seq2() throws Exception {
executeAndValidateSetupClientInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
executeAndValidateSetupSoftApInterface(
true, false, IFACE_NAME_1, mIfaceCallback1, mIfaceDestroyedListenerCaptor1,
mNetworkObserverCaptor1);
assertEquals(IFACE_NAME_0, mWifiNative.getClientInterfaceName());
executeAndValidateTeardownSoftApInterface(true, false, IFACE_NAME_1, mIfaceCallback1,
mIfaceDestroyedListenerCaptor1.getValue(), mNetworkObserverCaptor1.getValue());
executeAndValidateTeardownClientInterface(false, false, IFACE_NAME_0, mIfaceCallback0,
mIfaceDestroyedListenerCaptor0.getValue(), mNetworkObserverCaptor0.getValue());
}
/**
* Verifies the setup & teardown of a client & softAp interface.
*
* Sequence tested:
* a) Setup softAp interface.
* b) Setup client interface.
* c) Teardown softAp interface.
* d) Teardown client interface.
*/
@Test
public void testSetupAndTeardownClientAndSoftApInterface_Seq3() throws Exception {
executeAndValidateSetupSoftApInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
executeAndValidateSetupClientInterface(
false, true, IFACE_NAME_1, mIfaceCallback1, mIfaceDestroyedListenerCaptor1,
mNetworkObserverCaptor1);
assertEquals(IFACE_NAME_1, mWifiNative.getClientInterfaceName());
executeAndValidateTeardownSoftApInterface(true, false, IFACE_NAME_0, mIfaceCallback0,
mIfaceDestroyedListenerCaptor0.getValue(), mNetworkObserverCaptor0.getValue());
executeAndValidateTeardownClientInterface(false, false, IFACE_NAME_1, mIfaceCallback1,
mIfaceDestroyedListenerCaptor1.getValue(), mNetworkObserverCaptor1.getValue());
}
/**
* Verifies the setup & teardown of a client & softAp interface.
*
* Sequence tested:
* a) Setup softAp interface.
* b) Setup client interface.
* c) Teardown client interface.
* d) Teardown softAp interface.
*/
@Test
public void testSetupAndTeardownClientAndSoftApInterface_Seq4() throws Exception {
executeAndValidateSetupSoftApInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
executeAndValidateSetupClientInterface(
false, true, IFACE_NAME_1, mIfaceCallback1, mIfaceDestroyedListenerCaptor1,
mNetworkObserverCaptor1);
assertEquals(IFACE_NAME_1, mWifiNative.getClientInterfaceName());
executeAndValidateTeardownClientInterface(false, true, IFACE_NAME_1, mIfaceCallback1,
mIfaceDestroyedListenerCaptor1.getValue(), mNetworkObserverCaptor1.getValue());
executeAndValidateTeardownSoftApInterface(false, false, IFACE_NAME_0, mIfaceCallback0,
mIfaceDestroyedListenerCaptor0.getValue(), mNetworkObserverCaptor0.getValue());
}
/**
* Verifies the setup of a client & softAp interface & then initiate teardown of all active
* interfaces.
*
* Sequence tested:
* a) Setup softAp interface.
* b) Setup client interface.
* c) Teardown all active interfaces.
*/
@Test
public void testTeardownAllInterfaces() throws Exception {
executeAndValidateSetupSoftApInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
executeAndValidateSetupClientInterface(
false, true, IFACE_NAME_1, mIfaceCallback1, mIfaceDestroyedListenerCaptor1,
mNetworkObserverCaptor1);
// Assert that a client & softap interface is present.
assertNotNull(mWifiNative.getClientInterfaceName());
assertNotNull(mWifiNative.getSoftApInterfaceName());
mWifiNative.teardownAllInterfaces();
// Note: This is not using InOrder because order of interface deletion cannot be
// predetermined.
// Verify STA removal
verify(mWifiMonitor).stopMonitoring(IFACE_NAME_1);
verify(mNwManagementService).unregisterObserver(mNetworkObserverCaptor1.getValue());
verify(mSupplicantStaIfaceHal).teardownIface(IFACE_NAME_1);
verify(mWificondControl).tearDownClientInterface(IFACE_NAME_1);
verify(mSupplicantStaIfaceHal).deregisterDeathHandler();
verify(mWificondControl).disableSupplicant();
verify(mIfaceCallback1).onDestroyed(IFACE_NAME_1);
// Verify AP removal
verify(mNwManagementService).unregisterObserver(mNetworkObserverCaptor0.getValue());
verify(mHostapdHal).removeAccessPoint(IFACE_NAME_0);
verify(mHostapdHal).deregisterDeathHandler();
verify(mWificondControl).stopHostapd(IFACE_NAME_0);
verify(mWificondControl).tearDownSoftApInterface(IFACE_NAME_0);
// Verify we stopped HAL & wificond
verify(mWificondControl).tearDownInterfaces();
verify(mWifiVendorHal).stopVendorHal();
verify(mIfaceCallback0).onDestroyed(IFACE_NAME_0);
verify(mWifiVendorHal, atLeastOnce()).isVendorHalSupported();
// Assert that the client & softap interface is no more there.
assertNull(mWifiNative.getClientInterfaceName());
assertNull(mWifiNative.getSoftApInterfaceName());
}
/**
* Verifies the setup of a client interface and then a SoftAp interface which would
* destroy the Client interface. This is what would happen on older devices which do not
* support concurrent interfaces.
*/
@Test
public void testSetupClientAndSoftApInterfaceCausesClientInterfaceTeardown() throws Exception {
executeAndValidateSetupClientInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
// Trigger the STA interface teardown when AP interface is created.
// The iface name will remain the same.
doAnswer(new MockAnswerUtil.AnswerWithArguments() {
public String answer(InterfaceDestroyedListener destroyedListener) {
mIfaceDestroyedListenerCaptor0.getValue().onDestroyed(IFACE_NAME_0);
return IFACE_NAME_0;
}
}).when(mWifiVendorHal).createApIface(any());
assertEquals(IFACE_NAME_0, mWifiNative.setupInterfaceForSoftApMode(mIfaceCallback1));
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).createApIface(mIfaceDestroyedListenerCaptor1.capture());
// Creation of AP interface should trigger the STA interface destroy
validateOnDestroyedClientInterface(
false, true, IFACE_NAME_0, mIfaceCallback0, mNetworkObserverCaptor0.getValue());
// Now continue with rest of AP interface setup.
mInOrder.verify(mWificondControl).setupInterfaceForSoftApMode(IFACE_NAME_0);
mInOrder.verify(mNwManagementService).registerObserver(mNetworkObserverCaptor1.capture());
mInOrder.verify(mNwManagementService).getInterfaceConfig(IFACE_NAME_0);
// Execute a teardown of the interface to ensure that the new iface removal works.
executeAndValidateTeardownSoftApInterface(false, false, IFACE_NAME_0, mIfaceCallback1,
mIfaceDestroyedListenerCaptor1.getValue(), mNetworkObserverCaptor1.getValue());
}
/**
* Verifies the setup of a client interface and then a SoftAp interface which would
* destroy the Client interface. This is what would happen on older devices which do not
* support concurrent interfaces.
*/
@Test
public void testSetupSoftApAndClientInterfaceCausesSoftApInterfaceTeardown() throws Exception {
executeAndValidateSetupSoftApInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
// Trigger the AP interface teardown when STA interface is created.
// The iface name will remain the same.
doAnswer(new MockAnswerUtil.AnswerWithArguments() {
public String answer(boolean lowPrioritySta,
InterfaceDestroyedListener destroyedListener) {
mIfaceDestroyedListenerCaptor0.getValue().onDestroyed(IFACE_NAME_0);
return IFACE_NAME_0;
}
}).when(mWifiVendorHal).createStaIface(anyBoolean(), any());
assertEquals(IFACE_NAME_0, mWifiNative.setupInterfaceForClientMode(false, mIfaceCallback1));
mInOrder.verify(mWificondControl).enableSupplicant();
mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
mInOrder.verify(mSupplicantStaIfaceHal).initialize();
mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete();
mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any());
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).createStaIface(eq(false),
mIfaceDestroyedListenerCaptor1.capture());
// Creation of STA interface should trigger the AP interface destroy.
validateOnDestroyedSoftApInterface(
true, false, IFACE_NAME_0, mIfaceCallback0, mNetworkObserverCaptor0.getValue());
// Now continue with rest of STA interface setup.
mInOrder.verify(mWificondControl).setupInterfaceForClientMode(IFACE_NAME_0);
mInOrder.verify(mSupplicantStaIfaceHal).setupIface(IFACE_NAME_0);
mInOrder.verify(mNwManagementService).registerObserver(mNetworkObserverCaptor1.capture());
mInOrder.verify(mWifiMonitor).startMonitoring(IFACE_NAME_0);
mInOrder.verify(mNwManagementService).getInterfaceConfig(IFACE_NAME_0);
mInOrder.verify(mNwManagementService).clearInterfaceAddresses(IFACE_NAME_0);
mInOrder.verify(mNwManagementService).setInterfaceIpv6PrivacyExtensions(IFACE_NAME_0, true);
mInOrder.verify(mNwManagementService).disableIpv6(IFACE_NAME_0);
// Execute a teardown of the interface to ensure that the new iface removal works.
executeAndValidateTeardownClientInterface(false, false, IFACE_NAME_0, mIfaceCallback1,
mIfaceDestroyedListenerCaptor1.getValue(), mNetworkObserverCaptor1.getValue());
}
/**
* Verifies the setup of a client interface and trigger an interface down event.
* This should be ignored since interface is considered to be down before setup.
*/
@Test
public void testSetupClientInterfaceAndTriggerInterfaceDown() throws Exception {
executeAndValidateSetupSoftApInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
executeAndValidateInterfaceStateChange(
IFACE_NAME_0, false, mNetworkObserverCaptor0.getValue());
}
/**
* Verifies the setup of a client interface and trigger an interface up event.
*/
@Test
public void testSetupClientInterfaceAndTriggerInterfaceUp() throws Exception {
executeAndValidateSetupSoftApInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
executeAndValidateInterfaceStateChange(
IFACE_NAME_0, true, mNetworkObserverCaptor0.getValue());
mInOrder.verify(mIfaceCallback0).onUp(IFACE_NAME_0);
}
/**
* Verifies the setup of a client interface and trigger an interface up event, followed by a
* down event.
*/
@Test
public void testSetupClientInterfaceAndTriggerInterfaceUpFollowedByDown() throws Exception {
executeAndValidateSetupClientInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
executeAndValidateInterfaceStateChange(
IFACE_NAME_0, true, mNetworkObserverCaptor0.getValue());
mInOrder.verify(mIfaceCallback0).onUp(IFACE_NAME_0);
executeAndValidateInterfaceStateChange(
IFACE_NAME_0, false, mNetworkObserverCaptor0.getValue());
mInOrder.verify(mIfaceCallback0).onDown(IFACE_NAME_0);
mInOrder.verify(mWifiMetrics).incrementNumClientInterfaceDown();
}
/**
* Verifies the setup of a softap interface and trigger an interface up event, followed by a
* down event.
*/
@Test
public void testSetupSoftApInterfaceAndTriggerInterfaceUpFollowedByDown() throws Exception {
executeAndValidateSetupSoftApInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
executeAndValidateInterfaceStateChange(
IFACE_NAME_0, true, mNetworkObserverCaptor0.getValue());
mInOrder.verify(mIfaceCallback0).onUp(IFACE_NAME_0);
executeAndValidateInterfaceStateChange(
IFACE_NAME_0, false, mNetworkObserverCaptor0.getValue());
mInOrder.verify(mIfaceCallback0).onDown(IFACE_NAME_0);
mInOrder.verify(mWifiMetrics).incrementNumSoftApInterfaceDown();
}
/**
* Verifies the setup of a client interface and trigger an interface up event, followed by
* link down/up events. The link state change events should be ignored since we only care for
* interface state changes.
*/
@Test
public void testSetupClientInterfaceAndTriggerInterfaceUpFollowedByLinkDownAndUp()
throws Exception {
executeAndValidateSetupClientInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
executeAndValidateInterfaceStateChange(
IFACE_NAME_0, true, mNetworkObserverCaptor0.getValue());
mInOrder.verify(mIfaceCallback0).onUp(IFACE_NAME_0);
// Trigger a link down, with the interface still up.
// Should not trigger the external iface callback.
mNetworkObserverCaptor0.getValue().interfaceLinkStateChanged(IFACE_NAME_0, false);
mInOrder.verify(mNwManagementService).getInterfaceConfig(IFACE_NAME_0);
// Now trigger a link up, with the interface still up.
// Should not trigger the external iface callback.
mNetworkObserverCaptor0.getValue().interfaceLinkStateChanged(IFACE_NAME_0, true);
mInOrder.verify(mNwManagementService).getInterfaceConfig(IFACE_NAME_0);
}
/**
* Verifies the setup of a client interface and trigger an interface up event, followed by
* link down/up events. The link state change events should be ignored since we only care for
* interface state changes.
*/
@Test
public void testSetupSoftApInterfaceAndTriggerInterfaceUpFollowedByLinkDownAndUp()
throws Exception {
executeAndValidateSetupSoftApInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
executeAndValidateInterfaceStateChange(
IFACE_NAME_0, true, mNetworkObserverCaptor0.getValue());
mInOrder.verify(mIfaceCallback0).onUp(IFACE_NAME_0);
// Trigger a link down, with the interface still up.
// Should not trigger the external iface callback.
mNetworkObserverCaptor0.getValue().interfaceLinkStateChanged(IFACE_NAME_0, false);
mInOrder.verify(mNwManagementService).getInterfaceConfig(IFACE_NAME_0);
// Now trigger a link up, with the interface still up.
// Should not trigger the external iface callback.
mNetworkObserverCaptor0.getValue().interfaceLinkStateChanged(IFACE_NAME_0, true);
mInOrder.verify(mNwManagementService).getInterfaceConfig(IFACE_NAME_0);
}
/**
* Verifies the setup of a client interface and trigger an interface up event twice.
* The second interface up event should be masked.
*/
@Test
public void testSetupClientInterfaceAndTriggerInterfaceUpTwice() throws Exception {
executeAndValidateSetupSoftApInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
executeAndValidateInterfaceStateChange(
IFACE_NAME_0, true, mNetworkObserverCaptor0.getValue());
mInOrder.verify(mIfaceCallback0).onUp(IFACE_NAME_0);
executeAndValidateInterfaceStateChange(
IFACE_NAME_0, true, mNetworkObserverCaptor0.getValue());
}
/**
* Verifies the setup of a client interface and trigger an interface up event on a different
* interface.
*/
@Test
public void testSetupClientInterfaceAndTriggerInterfaceUpOnAnInvalidIface() throws Exception {
executeAndValidateSetupSoftApInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
mNetworkObserverCaptor0.getValue().interfaceLinkStateChanged(IFACE_NAME_1, true);
}
/**
* Verifies that interface down on a destroyed interface is ignored.
* The test triggers
* a) Setup of a client interface
* b) Setup of a SoftAp interface which would destroy the Client interface.
* This is what would happen on older devices which do not support concurrent interfaces.
* c) Once the client interface is destroyed, trigger an interface up event on the old
* network observer. This should be ignored.
* d) Trigger an interface down event on the new network observer. This should trigger an
* interface up event to external clients.
* e) Remove the new SoftAp interface.
*/
@Test
public void testSetupClientInterfaceAndTriggerInterfaceUpOnDestroyedIface() throws Exception {
// Step (a)
executeAndValidateSetupClientInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
// Step (b)
// Trigger the STA interface teardown when AP interface is created.
// The iface name will remain the same.
doAnswer(new MockAnswerUtil.AnswerWithArguments() {
public String answer(InterfaceDestroyedListener destroyedListener) {
mIfaceDestroyedListenerCaptor0.getValue().onDestroyed(IFACE_NAME_0);
return IFACE_NAME_0;
}
}).when(mWifiVendorHal).createApIface(any());
assertEquals(IFACE_NAME_0, mWifiNative.setupInterfaceForSoftApMode(mIfaceCallback1));
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).createApIface(mIfaceDestroyedListenerCaptor1.capture());
// Creation of AP interface should trigger the STA interface destroy
validateOnDestroyedClientInterface(
false, true, IFACE_NAME_0, mIfaceCallback0, mNetworkObserverCaptor0.getValue());
// Now continue with rest of AP interface setup.
mInOrder.verify(mWificondControl).setupInterfaceForSoftApMode(IFACE_NAME_0);
mInOrder.verify(mNwManagementService).registerObserver(mNetworkObserverCaptor1.capture());
mInOrder.verify(mNwManagementService).getInterfaceConfig(IFACE_NAME_0);
// Step (c) - Iface up on old iface, ignored!
mNetworkObserverCaptor0.getValue().interfaceLinkStateChanged(IFACE_NAME_0, true);
// Step (d) - Iface up on new iface, handled!
executeAndValidateInterfaceStateChange(
IFACE_NAME_0, true, mNetworkObserverCaptor1.getValue());
mInOrder.verify(mIfaceCallback1).onUp(IFACE_NAME_0);
// Execute a teardown of the softap interface to ensure that the new iface removal works.
executeAndValidateTeardownSoftApInterface(false, false, IFACE_NAME_0, mIfaceCallback1,
mIfaceDestroyedListenerCaptor1.getValue(), mNetworkObserverCaptor1.getValue());
}
/**
* Verifies the setup of a client interface and wificond death handling.
*/
@Test
public void testSetupClientInterfaceAndWicondDied() throws Exception {
executeAndValidateSetupClientInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
// Trigger wificond death
mWificondDeathHandlerCaptor.getValue().onDeath();
mInOrder.verify(mWifiMetrics).incrementNumWificondCrashes();
verify(mStatusListener).onStatusChanged(false);
verify(mStatusListener).onStatusChanged(true);
}
/**
* Verifies the setup of a soft ap interface and vendor HAL death handling.
*/
@Test
public void testSetupSoftApInterfaceAndVendorHalDied() throws Exception {
executeAndValidateSetupSoftApInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
// Trigger vendor HAL death
mWifiVendorHalDeathHandlerCaptor.getValue().onDeath();
mInOrder.verify(mWifiMetrics).incrementNumHalCrashes();
verify(mStatusListener).onStatusChanged(false);
verify(mStatusListener).onStatusChanged(true);
}
/**
* Verifies the setup of a client interface and supplicant HAL death handling.
*/
@Test
public void testSetupClientInterfaceAndSupplicantDied() throws Exception {
executeAndValidateSetupClientInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
// Trigger wificond death
mSupplicantDeathHandlerCaptor.getValue().onDeath();
mInOrder.verify(mWifiMetrics).incrementNumSupplicantCrashes();
verify(mStatusListener).onStatusChanged(false);
verify(mStatusListener).onStatusChanged(true);
}
/**
* Verifies the setup of a soft ap interface and hostapd death handling.
*/
@Test
public void testStartSoftApAndHostapdDied() throws Exception {
executeAndValidateSetupSoftApInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
// Start softap
assertTrue(mWifiNative.startSoftAp(IFACE_NAME_0, new WifiConfiguration(),
mock(WifiNative.SoftApListener.class)));
mInOrder.verify(mWificondControl).startHostapd(eq(IFACE_NAME_0), any());
mInOrder.verify(mHostapdHal).isInitializationStarted();
mInOrder.verify(mHostapdHal).initialize();
mInOrder.verify(mHostapdHal).isInitializationComplete();
mInOrder.verify(mHostapdHal).registerDeathHandler(any());
mInOrder.verify(mHostapdHal).addAccessPoint(any(), any());
// Trigger vendor HAL death
mHostapdDeathHandlerCaptor.getValue().onDeath();
mInOrder.verify(mWifiMetrics).incrementNumHostapdCrashes();
verify(mStatusListener).onStatusChanged(false);
verify(mStatusListener).onStatusChanged(true);
}
/**
* Verifies failure handling in setup of a client interface.
*/
@Test
public void testSetupClientInterfaceFailureInStartHal() throws Exception {
when(mWifiVendorHal.startVendorHal()).thenReturn(false);
assertNull(mWifiNative.setupInterfaceForClientMode(false, mIfaceCallback0));
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).startVendorHal();
mInOrder.verify(mWifiMetrics).incrementNumSetupClientInterfaceFailureDueToHal();
// To test if the failure is handled cleanly, invoke teardown and ensure that
// none of the mocks are used because the iface does not exist in the internal
// database.
mWifiNative.teardownInterface(IFACE_NAME_0);
}
/**
* Verifies failure handling in setup of a client interface.
*/
@Test
public void testSetupClientInterfaceFailureInStartSupplicant() throws Exception {
when(mWificondControl.enableSupplicant()).thenReturn(false);
assertNull(mWifiNative.setupInterfaceForClientMode(false, mIfaceCallback0));
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).startVendorHal();
mInOrder.verify(mWificondControl).enableSupplicant();
mInOrder.verify(mWifiMetrics).incrementNumSetupClientInterfaceFailureDueToSupplicant();
// To test if the failure is handled cleanly, invoke teardown and ensure that
// none of the mocks are used because the iface does not exist in the internal
// database.
mWifiNative.teardownInterface(IFACE_NAME_0);
}
/**
* Verifies failure handling in setup of a client interface.
*/
@Test
public void testSetupClientInterfaceFailureInHalCreateStaIface() throws Exception {
when(mWifiVendorHal.createStaIface(anyBoolean(), any())).thenReturn(null);
assertNull(mWifiNative.setupInterfaceForClientMode(false, mIfaceCallback0));
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).startVendorHal();
mInOrder.verify(mWificondControl).enableSupplicant();
mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
mInOrder.verify(mSupplicantStaIfaceHal).initialize();
mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete();
mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any());
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).createStaIface(eq(false), any());
mInOrder.verify(mWifiMetrics).incrementNumSetupClientInterfaceFailureDueToHal();
// To test if the failure is handled cleanly, invoke teardown and ensure that
// none of the mocks are used because the iface does not exist in the internal
// database.
mWifiNative.teardownInterface(IFACE_NAME_0);
}
/**
* Verifies failure handling in setup of a client interface.
*/
@Test
public void testSetupClientInterfaceFailureInWificondSetupInterfaceForClientMode()
throws Exception {
when(mWificondControl.setupInterfaceForClientMode(any())).thenReturn(null);
assertNull(mWifiNative.setupInterfaceForClientMode(false, mIfaceCallback0));
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).startVendorHal();
mInOrder.verify(mWificondControl).enableSupplicant();
mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
mInOrder.verify(mSupplicantStaIfaceHal).initialize();
mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete();
mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any());
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).createStaIface(eq(false),
mIfaceDestroyedListenerCaptor0.capture());
mInOrder.verify(mWificondControl).setupInterfaceForClientMode(any());
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).removeStaIface(any());
mInOrder.verify(mWifiMetrics).incrementNumSetupClientInterfaceFailureDueToWificond();
// Trigger the HAL interface destroyed callback to verify the whole removal sequence.
mIfaceDestroyedListenerCaptor0.getValue().onDestroyed(IFACE_NAME_0);
validateOnDestroyedClientInterface(false, false, IFACE_NAME_0, mIfaceCallback0,
null);
// To test if the failure is handled cleanly, invoke teardown and ensure that
// none of the mocks are used because the iface does not exist in the internal
// database.
mWifiNative.teardownInterface(IFACE_NAME_0);
}
/**
* Verifies failure handling in setup of a client interface.
*/
@Test
public void testSetupClientInterfaceFailureInSupplicantSetupIface() throws Exception {
when(mSupplicantStaIfaceHal.setupIface(any())).thenReturn(false);
assertNull(mWifiNative.setupInterfaceForClientMode(false, mIfaceCallback0));
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).startVendorHal();
mInOrder.verify(mWificondControl).enableSupplicant();
mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
mInOrder.verify(mSupplicantStaIfaceHal).initialize();
mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete();
mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any());
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).createStaIface(eq(false),
mIfaceDestroyedListenerCaptor0.capture());
mInOrder.verify(mWificondControl).setupInterfaceForClientMode(any());
mInOrder.verify(mSupplicantStaIfaceHal).setupIface(any());
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).removeStaIface(any());
mInOrder.verify(mWifiMetrics).incrementNumSetupClientInterfaceFailureDueToSupplicant();
// Trigger the HAL interface destroyed callback to verify the whole removal sequence.
mIfaceDestroyedListenerCaptor0.getValue().onDestroyed(IFACE_NAME_0);
validateOnDestroyedClientInterface(false, false, IFACE_NAME_0, mIfaceCallback0,
null);
// To test if the failure is handled cleanly, invoke teardown and ensure that
// none of the mocks are used because the iface does not exist in the internal
// database.
mWifiNative.teardownInterface(IFACE_NAME_0);
}
/**
* Verifies failure handling in setup of a client interface.
*/
@Test
public void testSetupClientInterfaceFailureInNetworkObserverRegister() throws Exception {
doThrow(new RemoteException()).when(mNwManagementService).registerObserver(any());
assertNull(mWifiNative.setupInterfaceForClientMode(false, mIfaceCallback0));
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).startVendorHal();
mInOrder.verify(mWificondControl).enableSupplicant();
mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
mInOrder.verify(mSupplicantStaIfaceHal).initialize();
mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete();
mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any());
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).createStaIface(eq(false),
mIfaceDestroyedListenerCaptor0.capture());
mInOrder.verify(mWificondControl).setupInterfaceForClientMode(any());
mInOrder.verify(mSupplicantStaIfaceHal).setupIface(any());
mInOrder.verify(mNwManagementService).registerObserver(mNetworkObserverCaptor0.capture());
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).removeStaIface(any());
// Trigger the HAL interface destroyed callback to verify the whole removal sequence.
mIfaceDestroyedListenerCaptor0.getValue().onDestroyed(IFACE_NAME_0);
validateOnDestroyedClientInterface(false, false, IFACE_NAME_0, mIfaceCallback0,
mNetworkObserverCaptor0.getValue());
// To test if the failure is handled cleanly, invoke teardown and ensure that
// none of the mocks are used because the iface does not exist in the internal
// database.
mWifiNative.teardownInterface(IFACE_NAME_0);
}
/**
* Verifies failure handling in setup of a softAp interface.
*/
@Test
public void testSetupSoftApInterfaceFailureInStartHal() throws Exception {
when(mWifiVendorHal.startVendorHal()).thenReturn(false);
assertNull(mWifiNative.setupInterfaceForSoftApMode(mIfaceCallback0));
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).startVendorHal();
mInOrder.verify(mWifiMetrics).incrementNumSetupSoftApInterfaceFailureDueToHal();
// To test if the failure is handled cleanly, invoke teardown and ensure that
// none of the mocks are used because the iface does not exist in the internal
// database.
mWifiNative.teardownInterface(IFACE_NAME_0);
}
/**
* Verifies failure handling in setup of a softAp interface.
*/
@Test
public void testSetupSoftApInterfaceFailureInHalCreateApIface() throws Exception {
when(mWifiVendorHal.createApIface(any())).thenReturn(null);
assertNull(mWifiNative.setupInterfaceForSoftApMode(mIfaceCallback0));
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).startVendorHal();
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).createApIface(any());
mInOrder.verify(mWifiMetrics).incrementNumSetupSoftApInterfaceFailureDueToHal();
// To test if the failure is handled cleanly, invoke teardown and ensure that
// none of the mocks are used because the iface does not exist in the internal
// database.
mWifiNative.teardownInterface(IFACE_NAME_0);
}
/**
* Verifies failure handling in setup of a softAp interface.
*/
@Test
public void testSetupSoftApInterfaceFailureInWificondSetupInterfaceForSoftapMode()
throws Exception {
when(mWificondControl.setupInterfaceForSoftApMode(any())).thenReturn(null);
assertNull(mWifiNative.setupInterfaceForSoftApMode(mIfaceCallback0));
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).startVendorHal();
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).createApIface(mIfaceDestroyedListenerCaptor0.capture());
mInOrder.verify(mWificondControl).setupInterfaceForSoftApMode(any());
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).removeApIface(any());
mInOrder.verify(mWifiMetrics).incrementNumSetupSoftApInterfaceFailureDueToWificond();
// Trigger the HAL interface destroyed callback to verify the whole removal sequence.
mIfaceDestroyedListenerCaptor0.getValue().onDestroyed(IFACE_NAME_0);
validateOnDestroyedSoftApInterface(false, false, IFACE_NAME_0, mIfaceCallback0,
null);
// To test if the failure is handled cleanly, invoke teardown and ensure that
// none of the mocks are used because the iface does not exist in the internal
// database.
mWifiNative.teardownInterface(IFACE_NAME_0);
}
/**
* Verifies the interface state query API.
*/
@Test
public void testIsInterfaceUp() throws Exception {
executeAndValidateSetupClientInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
mInterfaceConfiguration.setInterfaceUp();
assertTrue(mWifiNative.isInterfaceUp(IFACE_NAME_0));
mInterfaceConfiguration.setInterfaceDown();
assertFalse(mWifiNative.isInterfaceUp(IFACE_NAME_0));
when(mNwManagementService.getInterfaceConfig(IFACE_NAME_0)).thenReturn(null);
assertFalse(mWifiNative.isInterfaceUp(IFACE_NAME_0));
verify(mNwManagementService, times(4)).getInterfaceConfig(IFACE_NAME_0);
}
/**
* Verifies that the interface name is null when there are no interfaces setup.
*/
@Test
public void testGetClientInterfaceNameWithNoInterfacesSetup() throws Exception {
assertNull(mWifiNative.getClientInterfaceName());
}
/**
* Verifies that the interface name is null when there are no client interfaces setup.
*/
@Test
public void testGetClientInterfaceNameWithNoClientInterfaceSetup() throws Exception {
executeAndValidateSetupSoftApInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
assertNull(mWifiNative.getClientInterfaceName());
}
/**
* Verifies that the interface name is not null when there is one client interface setup.
*/
@Test
public void testGetClientInterfaceNameWithOneClientInterfaceSetup() throws Exception {
executeAndValidateSetupClientInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
assertEquals(IFACE_NAME_0, mWifiNative.getClientInterfaceName());
}
/**
* Verifies that the interface name is not null when there are more than one client interfaces
* setup.
*/
@Test
public void testGetClientInterfaceNameWithMoreThanOneClientInterfaceSetup() throws Exception {
executeAndValidateSetupClientInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
executeAndValidateSetupClientInterface(
true, false, IFACE_NAME_1, mIfaceCallback1, mIfaceDestroyedListenerCaptor1,
mNetworkObserverCaptor1);
String interfaceName = mWifiNative.getClientInterfaceName();
assertNotNull(interfaceName);
assertTrue(interfaceName.equals(IFACE_NAME_0) || interfaceName.equals(IFACE_NAME_1));
}
/*
* Verifies the setup of a client interface and then a SoftAp interface which would
* destroy the Client interface. This is what would happen on older devices which do not
* support the vendor HAL.
*/
@Test
public void testSetupClientAndSoftApInterfaceCausesClientInterfaceTeardownWithNoVendorHal()
throws Exception {
when(mWifiVendorHal.isVendorHalSupported()).thenReturn(false);
when(mPropertyService.getString(any(), any())).thenReturn(IFACE_NAME_0);
// First setup a STA interface and verify.
assertEquals(IFACE_NAME_0, mWifiNative.setupInterfaceForClientMode(false, mIfaceCallback0));
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWificondControl).enableSupplicant();
mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
mInOrder.verify(mSupplicantStaIfaceHal).initialize();
mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete();
mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any());
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWificondControl).setupInterfaceForClientMode(IFACE_NAME_0);
mInOrder.verify(mSupplicantStaIfaceHal).setupIface(IFACE_NAME_0);
mInOrder.verify(mNwManagementService).registerObserver(mNetworkObserverCaptor0.capture());
mInOrder.verify(mWifiMonitor).startMonitoring(IFACE_NAME_0);
mInOrder.verify(mNwManagementService).getInterfaceConfig(IFACE_NAME_0);
mInOrder.verify(mNwManagementService).clearInterfaceAddresses(IFACE_NAME_0);
mInOrder.verify(mNwManagementService).setInterfaceIpv6PrivacyExtensions(IFACE_NAME_0, true);
mInOrder.verify(mNwManagementService).disableIpv6(IFACE_NAME_0);
// Now setup an AP interface.
assertEquals(IFACE_NAME_0, mWifiNative.setupInterfaceForSoftApMode(mIfaceCallback1));
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
// Creation of AP interface should trigger the STA interface destroy
verify(mWifiMonitor).stopMonitoring(IFACE_NAME_0);
mInOrder.verify(mNwManagementService).unregisterObserver(
mNetworkObserverCaptor0.getValue());
mInOrder.verify(mSupplicantStaIfaceHal).teardownIface(IFACE_NAME_0);
mInOrder.verify(mWificondControl).tearDownClientInterface(IFACE_NAME_0);
mInOrder.verify(mSupplicantStaIfaceHal).deregisterDeathHandler();
mInOrder.verify(mWificondControl).disableSupplicant();
mInOrder.verify(mIfaceCallback0).onDestroyed(IFACE_NAME_0);
// Now continue with rest of AP interface setup.
mInOrder.verify(mWificondControl).setupInterfaceForSoftApMode(IFACE_NAME_0);
mInOrder.verify(mNwManagementService).registerObserver(mNetworkObserverCaptor1.capture());
mInOrder.verify(mNwManagementService).getInterfaceConfig(IFACE_NAME_0);
}
/**
* Verifies the setup of a client interface and then a SoftAp interface which would
* destroy the Client interface. This is what would happen on older devices which do not
* support the vendor HAL.
*/
@Test
public void testSetupSoftApAndClientInterfaceCausesSoftApInterfaceTeardownWithNoVendorHal()
throws Exception {
when(mWifiVendorHal.isVendorHalSupported()).thenReturn(false);
when(mPropertyService.getString(any(), any())).thenReturn(IFACE_NAME_0);
// First setup an AP interface and verify.
assertEquals(IFACE_NAME_0, mWifiNative.setupInterfaceForSoftApMode(mIfaceCallback0));
mInOrder.verify(mWifiVendorHal, times(2)).isVendorHalSupported();
mInOrder.verify(mWificondControl).setupInterfaceForSoftApMode(IFACE_NAME_0);
mInOrder.verify(mNwManagementService).registerObserver(mNetworkObserverCaptor0.capture());
mInOrder.verify(mNwManagementService).getInterfaceConfig(IFACE_NAME_0);
// Now setup a STA interface.
assertEquals(IFACE_NAME_0, mWifiNative.setupInterfaceForClientMode(false, mIfaceCallback1));
mInOrder.verify(mWificondControl).enableSupplicant();
mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
mInOrder.verify(mSupplicantStaIfaceHal).initialize();
mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete();
mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any());
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
// Creation of STA interface should trigger the AP interface destroy.
mInOrder.verify(mNwManagementService).unregisterObserver(
mNetworkObserverCaptor0.getValue());
mInOrder.verify(mHostapdHal).removeAccessPoint(IFACE_NAME_0);
mInOrder.verify(mHostapdHal).deregisterDeathHandler();
mInOrder.verify(mWificondControl).stopHostapd(IFACE_NAME_0);
mInOrder.verify(mWificondControl).tearDownSoftApInterface(IFACE_NAME_0);
mInOrder.verify(mIfaceCallback0).onDestroyed(IFACE_NAME_0);
// Now continue with rest of STA interface setup.
mInOrder.verify(mWificondControl).setupInterfaceForClientMode(IFACE_NAME_0);
mInOrder.verify(mSupplicantStaIfaceHal).setupIface(IFACE_NAME_0);
mInOrder.verify(mNwManagementService).registerObserver(mNetworkObserverCaptor1.capture());
mInOrder.verify(mWifiMonitor).startMonitoring(IFACE_NAME_0);
mInOrder.verify(mNwManagementService).getInterfaceConfig(IFACE_NAME_0);
mInOrder.verify(mNwManagementService).clearInterfaceAddresses(IFACE_NAME_0);
mInOrder.verify(mNwManagementService).setInterfaceIpv6PrivacyExtensions(IFACE_NAME_0, true);
mInOrder.verify(mNwManagementService).disableIpv6(IFACE_NAME_0);
}
/**
* Verifies the handling of radio mode change callbacks.
*/
@Test
public void testRadioModeChangeCallback() {
WifiNative.VendorHalRadioModeChangeEventHandler handler =
mWifiVendorHalRadioModeChangeHandlerCaptor.getValue();
handler.onMcc(WifiScanner.WIFI_BAND_5_GHZ);
mInOrder.verify(mWifiMetrics).incrementNumRadioModeChangeToMcc();
handler.onScc(WifiScanner.WIFI_BAND_24_GHZ);
mInOrder.verify(mWifiMetrics).incrementNumRadioModeChangeToScc();
handler.onSbs(WifiScanner.WIFI_BAND_24_GHZ);
mInOrder.verify(mWifiMetrics).incrementNumRadioModeChangeToSbs();
handler.onDbs();
mInOrder.verify(mWifiMetrics).incrementNumRadioModeChangeToDbs();
}
private void executeAndValidateSetupClientInterface(
boolean existingStaIface, boolean existingApIface,
String ifaceName, @Mock WifiNative.InterfaceCallback callback,
ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor,
ArgumentCaptor<BaseNetworkObserver> networkObserverCaptor) throws Exception {
when(mWifiVendorHal.createStaIface(anyBoolean(), any())).thenReturn(ifaceName);
assertEquals(ifaceName, mWifiNative.setupInterfaceForClientMode(false, callback));
validateSetupClientInterface(
existingStaIface, existingApIface, ifaceName, destroyedListenerCaptor,
networkObserverCaptor);
}
private void validateSetupClientInterface(
boolean existingStaIface, boolean existingApIface,
String ifaceName, ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor,
ArgumentCaptor<BaseNetworkObserver> networkObserverCaptor) throws Exception {
if (!existingStaIface && !existingApIface) {
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).startVendorHal();
}
if (!existingStaIface) {
mInOrder.verify(mWificondControl).enableSupplicant();
mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
mInOrder.verify(mSupplicantStaIfaceHal).initialize();
mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete();
mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any());
}
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).createStaIface(eq(false),
destroyedListenerCaptor.capture());
mInOrder.verify(mWificondControl).setupInterfaceForClientMode(ifaceName);
mInOrder.verify(mSupplicantStaIfaceHal).setupIface(ifaceName);
mInOrder.verify(mNwManagementService).registerObserver(networkObserverCaptor.capture());
mInOrder.verify(mWifiMonitor).startMonitoring(ifaceName);
mInOrder.verify(mNwManagementService).getInterfaceConfig(ifaceName);
mInOrder.verify(mNwManagementService).clearInterfaceAddresses(ifaceName);
mInOrder.verify(mNwManagementService).setInterfaceIpv6PrivacyExtensions(ifaceName, true);
mInOrder.verify(mNwManagementService).disableIpv6(ifaceName);
}
private void executeAndValidateTeardownClientInterface(
boolean anyOtherStaIface, boolean anyOtherApIface,
String ifaceName, @Mock WifiNative.InterfaceCallback callback,
InterfaceDestroyedListener destroyedListener,
BaseNetworkObserver networkObserver) throws Exception {
mWifiNative.teardownInterface(ifaceName);
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).removeStaIface(ifaceName);
// Now trigger the HalDeviceManager destroy callback to initiate the rest of the teardown.
destroyedListener.onDestroyed(ifaceName);
validateOnDestroyedClientInterface(
anyOtherStaIface, anyOtherApIface, ifaceName, callback, networkObserver);
}
private void validateOnDestroyedClientInterface(
boolean anyOtherStaIface, boolean anyOtherApIface,
String ifaceName, @Mock WifiNative.InterfaceCallback callback,
BaseNetworkObserver networkObserver) throws Exception {
mInOrder.verify(mWifiMonitor).stopMonitoring(ifaceName);
if (networkObserver != null) {
mInOrder.verify(mNwManagementService).unregisterObserver(networkObserver);
}
mInOrder.verify(mSupplicantStaIfaceHal).teardownIface(ifaceName);
mInOrder.verify(mWificondControl).tearDownClientInterface(ifaceName);
if (!anyOtherStaIface) {
mInOrder.verify(mSupplicantStaIfaceHal).deregisterDeathHandler();
mInOrder.verify(mWificondControl).disableSupplicant();
}
if (!anyOtherStaIface && !anyOtherApIface) {
mInOrder.verify(mWificondControl).tearDownInterfaces();
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).stopVendorHal();
}
mInOrder.verify(callback).onDestroyed(ifaceName);
}
private void executeAndValidateSetupSoftApInterface(
boolean existingStaIface, boolean existingApIface,
String ifaceName, @Mock WifiNative.InterfaceCallback callback,
ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor,
ArgumentCaptor<BaseNetworkObserver> networkObserverCaptor) throws Exception {
when(mWifiVendorHal.createApIface(any())).thenReturn(ifaceName);
assertEquals(ifaceName, mWifiNative.setupInterfaceForSoftApMode(callback));
validateSetupSoftApInterface(
existingStaIface, existingApIface, ifaceName, destroyedListenerCaptor,
networkObserverCaptor);
}
private void validateSetupSoftApInterface(
boolean existingStaIface, boolean existingApIface,
String ifaceName, ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor,
ArgumentCaptor<BaseNetworkObserver> networkObserverCaptor) throws Exception {
if (!existingStaIface && !existingApIface) {
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).startVendorHal();
}
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).createApIface(destroyedListenerCaptor.capture());
mInOrder.verify(mWificondControl).setupInterfaceForSoftApMode(ifaceName);
mInOrder.verify(mNwManagementService).registerObserver(networkObserverCaptor.capture());
mInOrder.verify(mNwManagementService).getInterfaceConfig(ifaceName);
}
private void executeAndValidateTeardownSoftApInterface(
boolean anyOtherStaIface, boolean anyOtherApIface,
String ifaceName, @Mock WifiNative.InterfaceCallback callback,
InterfaceDestroyedListener destroyedListener,
BaseNetworkObserver networkObserver) throws Exception {
mWifiNative.teardownInterface(ifaceName);
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).removeApIface(ifaceName);
// Now trigger the HalDeviceManager destroy callback to initiate the rest of the teardown.
destroyedListener.onDestroyed(ifaceName);
validateOnDestroyedSoftApInterface(
anyOtherStaIface, anyOtherApIface, ifaceName, callback, networkObserver);
}
private void validateOnDestroyedSoftApInterface(
boolean anyOtherStaIface, boolean anyOtherApIface,
String ifaceName, @Mock WifiNative.InterfaceCallback callback,
BaseNetworkObserver networkObserver) throws Exception {
if (networkObserver != null) {
mInOrder.verify(mNwManagementService).unregisterObserver(networkObserver);
}
mInOrder.verify(mHostapdHal).removeAccessPoint(ifaceName);
mInOrder.verify(mHostapdHal).deregisterDeathHandler();
mInOrder.verify(mWificondControl).stopHostapd(ifaceName);
mInOrder.verify(mWificondControl).tearDownSoftApInterface(ifaceName);
if (!anyOtherStaIface && !anyOtherApIface) {
mInOrder.verify(mWificondControl).tearDownInterfaces();
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).stopVendorHal();
}
mInOrder.verify(callback).onDestroyed(ifaceName);
}
private void executeAndValidateInterfaceStateChange(
String ifaceName, boolean up, BaseNetworkObserver networkObserver) throws Exception {
if (up) {
mInterfaceConfiguration.setInterfaceUp();
} else {
mInterfaceConfiguration.setInterfaceDown();
}
networkObserver.interfaceLinkStateChanged(ifaceName, up);
mInOrder.verify(mNwManagementService).getInterfaceConfig(ifaceName);
}
}