WifiStateMachinePrime: update interface management
Interface management moved from wificond to WifiNative. Update
interface creation and cleanup to the new calls available via the
WifiNative methods.
Bug: 68159269
Bug: 69421434
Test: frameworks/opt/net/wifi/tests/wifitests/runtests.sh
Change-Id: I82ad04091336acbd1544478bae2a772e43c15cc6
diff --git a/service/java/com/android/server/wifi/WifiStateMachinePrime.java b/service/java/com/android/server/wifi/WifiStateMachinePrime.java
index c49b645..de970ee 100644
--- a/service/java/com/android/server/wifi/WifiStateMachinePrime.java
+++ b/service/java/com/android/server/wifi/WifiStateMachinePrime.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.net.wifi.IApInterface;
-import android.net.wifi.IWificond;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.INetworkManagementService;
@@ -26,6 +25,7 @@
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
+import android.util.Pair;
import com.android.internal.util.Protocol;
import com.android.internal.util.State;
@@ -47,12 +47,13 @@
private final WifiInjector mWifiInjector;
private final Looper mLooper;
+ private final WifiNative mWifiNative;
private final INetworkManagementService mNMService;
- private IWificond mWificond;
-
private Queue<SoftApModeConfiguration> mApConfigQueue = new ConcurrentLinkedQueue<>();
+ private String mInterfaceName;
+
/* The base for wifi message types */
static final int BASE = Protocol.BASE_WIFI;
@@ -67,22 +68,17 @@
WifiStateMachinePrime(WifiInjector wifiInjector,
Looper looper,
+ WifiNative wifiNative,
INetworkManagementService nmService) {
mWifiInjector = wifiInjector;
mLooper = looper;
+ mWifiNative = wifiNative;
mNMService = nmService;
- // Clean up existing interfaces in wificond.
- // This ensures that the framework and wificond are in a consistent state after a framework
- // restart.
- try {
- mWificond = mWifiInjector.makeWificond();
- if (mWificond != null) {
- mWificond.tearDownInterfaces();
- }
- } catch (RemoteException e) {
- Log.e(TAG, "wificond died during framework startup");
- }
+ mInterfaceName = mWifiNative.getInterfaceName();
+
+ // make sure we do not have leftover state in the event of a restart
+ mWifiNative.tearDown();
}
/**
@@ -211,23 +207,13 @@
return HANDLED;
}
- private void tearDownInterfaces() {
- if (mWificond != null) {
- try {
- mWificond.tearDownInterfaces();
- } catch (RemoteException e) {
- // There is very little we can do here
- Log.e(TAG, "Failed to tear down interfaces via wificond");
- }
- mWificond = null;
- }
- return;
+ private void cleanup() {
+ mWifiNative.tearDown();
}
class ClientModeState extends State {
@Override
public void enter() {
- mWificond = mWifiInjector.makeWificond();
}
@Override
@@ -240,7 +226,7 @@
@Override
public void exit() {
- tearDownInterfaces();
+ cleanup();
}
}
@@ -280,17 +266,27 @@
// Continue with setup since we are changing modes
mApInterface = null;
+ Pair<Integer, IApInterface> statusAndInterface =
+ mWifiNative.setupForSoftApMode(mInterfaceName);
+ if (statusAndInterface.first == WifiNative.SETUP_SUCCESS) {
+ mApInterface = statusAndInterface.second;
+ } else {
+ // TODO: incorporate metrics - or this particular one will be done in WifiNative
+ //incrementMetricsForSetupFailure(statusAndInterface.first);
+ }
+ if (mApInterface == null) {
+ // TODO: update battery stats that a failure occured - best to do in
+ // initialization Failed. Keeping line copied from WSM for a reference
+ //setWifiApState(WIFI_AP_STATE_FAILED,
+ // WifiManager.SAP_START_FAILURE_GENERAL, null, mMode);
+ initializationFailed("Could not get IApInterface instance");
+ return;
+ }
+
try {
- mWificond = mWifiInjector.makeWificond();
- mApInterface = mWificond.createApInterface(
- mWifiInjector.getWifiNative().getInterfaceName());
mIfaceName = mApInterface.getInterfaceName();
} catch (RemoteException e) {
- initializationFailed(
- "Could not get IApInterface instance or its name from wificond");
- return;
- } catch (NullPointerException e) {
- initializationFailed("wificond failure when initializing softap mode");
+ initializationFailed("Could not get IApInterface name");
return;
}
mModeStateMachine.transitionTo(mSoftAPModeActiveState);
@@ -325,7 +321,7 @@
@Override
public void exit() {
- tearDownInterfaces();
+ cleanup();
}
protected IApInterface getInterface() {
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachinePrimeTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachinePrimeTest.java
index 2e26769..f2d6cc6 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachinePrimeTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachinePrimeTest.java
@@ -20,13 +20,13 @@
import static org.mockito.Mockito.*;
import android.net.wifi.IApInterface;
-import android.net.wifi.IWificond;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.INetworkManagementService;
import android.os.test.TestLooper;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;
+import android.util.Pair;
import org.junit.After;
import org.junit.Before;
@@ -56,7 +56,6 @@
@Mock WifiNative mWifiNative;
@Mock WifiApConfigStore mWifiApConfigStore;
TestLooper mLooper;
- @Mock IWificond mWificond;
@Mock IApInterface mApInterface;
@Mock INetworkManagementService mNMService;
@Mock SoftApManager mSoftApManager;
@@ -76,11 +75,15 @@
when(mWifiInjector.getWifiNative()).thenReturn(mWifiNative);
when(mWifiNative.getInterfaceName()).thenReturn(WIFI_IFACE_NAME);
mWifiStateMachinePrime = createWifiStateMachinePrime();
+
+ // creating a new WSMP cleans up any existing interfaces, check and reset expectations
+ verifyCleanupCalled();
+ reset(mWifiNative);
}
private WifiStateMachinePrime createWifiStateMachinePrime() {
- when(mWifiInjector.makeWificond()).thenReturn(null);
- return new WifiStateMachinePrime(mWifiInjector, mLooper.getLooper(), mNMService);
+ return new WifiStateMachinePrime(mWifiInjector, mLooper.getLooper(),
+ mWifiNative, mNMService);
}
/**
@@ -103,8 +106,8 @@
*/
private void enterSoftApActiveMode(SoftApModeConfiguration softApConfig) throws Exception {
String fromState = mWifiStateMachinePrime.getCurrentMode();
- when(mWifiInjector.makeWificond()).thenReturn(mWificond);
- when(mWificond.createApInterface(WIFI_IFACE_NAME)).thenReturn(mApInterface);
+ when(mWifiNative.setupForSoftApMode(WIFI_IFACE_NAME))
+ .thenReturn(new Pair(WifiNative.SETUP_SUCCESS, mApInterface));
when(mApInterface.getInterfaceName()).thenReturn(WIFI_IFACE_NAME);
doAnswer(
new Answer<Object>() {
@@ -126,24 +129,30 @@
mLooper.dispatchAll();
Log.e("WifiStateMachinePrimeTest", "check fromState: " + fromState);
if (!fromState.equals(WIFI_DISABLED_STATE_STRING)) {
- verify(mWificond).tearDownInterfaces();
+ verifyCleanupCalled();
}
assertEquals(SOFT_AP_MODE_ACTIVE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
verify(mSoftApManager).start();
}
+ private void verifyCleanupCalled() {
+ // for now, this is a single call, but make a helper to avoid adding any additional cleanup
+ // checks
+ verify(mWifiNative).tearDown();
+ }
+
/**
- * Test that when a new instance of WifiStateMachinePrime is created, any existing interfaces in
- * the retrieved Wificond instance are cleaned up.
+ * Test that when a new instance of WifiStateMachinePrime is created, any existing
+ * resources in WifiNative are cleaned up.
* Expectations: When the new WifiStateMachinePrime instance is created a call to
- * Wificond.tearDownInterfaces() is made.
+ * WifiNative.tearDown() is made.
*/
@Test
- public void testWificondExistsOnStartup() throws Exception {
- when(mWifiInjector.makeWificond()).thenReturn(mWificond);
+ public void testCleanupOnStart() throws Exception {
WifiStateMachinePrime testWifiStateMachinePrime =
- new WifiStateMachinePrime(mWifiInjector, mLooper.getLooper(), mNMService);
- verify(mWificond).tearDownInterfaces();
+ new WifiStateMachinePrime(mWifiInjector, mLooper.getLooper(),
+ mWifiNative, mNMService);
+ verifyCleanupCalled();
}
/**
@@ -157,12 +166,10 @@
/**
* Test that WifiStateMachinePrime properly enters the SoftApModeActiveState from another state.
- * Expectations: When going from one state to another, any interfaces that are still up are torn
- * down.
+ * Expectations: When going from one state to another, cleanup will be called
*/
@Test
public void testEnterSoftApModeFromDifferentState() throws Exception {
- when(mWifiInjector.makeWificond()).thenReturn(mWificond);
mWifiStateMachinePrime.enterClientMode();
mLooper.dispatchAll();
assertEquals(CLIENT_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
@@ -179,7 +186,7 @@
mWifiStateMachinePrime.disableWifi();
mLooper.dispatchAll();
verify(mSoftApManager).stop();
- verify(mWificond).tearDownInterfaces();
+ verifyCleanupCalled();
assertEquals(WIFI_DISABLED_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
}
@@ -188,8 +195,10 @@
*/
@Test
public void testDisableWifiFromSoftApModeState() throws Exception {
- // Use a failure getting wificond to stay in the SoftAPModeState
- when(mWifiInjector.makeWificond()).thenReturn(null);
+ // Use a failure getting the interface to stay in SoftApMode
+ when(mWifiNative.setupForSoftApMode(WIFI_IFACE_NAME))
+ .thenReturn(new Pair(WifiNative.SETUP_FAILURE_HAL, null));
+
mWifiStateMachinePrime.enterSoftAPMode(
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null));
mLooper.dispatchAll();
@@ -197,7 +206,7 @@
mWifiStateMachinePrime.disableWifi();
mLooper.dispatchAll();
- // mWificond will be null due to this test, no call to tearDownInterfaces here.
+ verifyCleanupCalled();
assertEquals(WIFI_DISABLED_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
}
@@ -213,26 +222,11 @@
mWifiStateMachinePrime.enterClientMode();
mLooper.dispatchAll();
verify(mSoftApManager).stop();
- verify(mWificond).tearDownInterfaces();
+ verifyCleanupCalled();
assertEquals(CLIENT_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
}
/**
- * Test that we do not attempt to enter SoftApModeActiveState when we cannot get a reference to
- * wificond.
- * Expectations: After a failed attempt to get wificond from WifiInjector, we should remain in
- * the SoftApModeState.
- */
- @Test
- public void testWificondNullWhenSwitchingToApMode() throws Exception {
- when(mWifiInjector.makeWificond()).thenReturn(null);
- mWifiStateMachinePrime.enterSoftAPMode(
- new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null));
- mLooper.dispatchAll();
- assertEquals(SOFT_AP_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
- }
-
- /**
* Test that we do not attempt to enter SoftApModeActiveState when we cannot get an ApInterface
* from wificond.
* Expectations: After a failed attempt to get an ApInterface from WifiInjector, we should
@@ -240,8 +234,8 @@
*/
@Test
public void testAPInterfaceFailedWhenSwitchingToApMode() throws Exception {
- when(mWifiInjector.makeWificond()).thenReturn(mWificond);
- when(mWificond.createApInterface(WIFI_IFACE_NAME)).thenReturn(null);
+ when(mWifiNative.setupForSoftApMode(WIFI_IFACE_NAME))
+ .thenReturn(new Pair(WifiNative.SETUP_FAILURE_HAL, null));
mWifiStateMachinePrime.enterSoftAPMode(
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null));
mLooper.dispatchAll();
@@ -255,8 +249,8 @@
*/
@Test
public void testEnterSoftApModeActiveWhenAlreadyInSoftApMode() throws Exception {
- when(mWifiInjector.makeWificond()).thenReturn(mWificond);
- when(mWificond.createApInterface(WIFI_IFACE_NAME)).thenReturn(null);
+ when(mWifiNative.setupForSoftApMode(WIFI_IFACE_NAME))
+ .thenReturn(new Pair(WifiNative.SETUP_SUCCESS, null));
mWifiStateMachinePrime.enterSoftAPMode(
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null));
mLooper.dispatchAll();
@@ -330,8 +324,8 @@
*/
@Test
public void testNullApModeConfigFails() throws Exception {
- when(mWifiInjector.makeWificond()).thenReturn(mWificond);
- when(mWificond.createApInterface(WIFI_IFACE_NAME)).thenReturn(null);
+ when(mWifiNative.setupForSoftApMode(WIFI_IFACE_NAME))
+ .thenReturn(new Pair(WifiNative.SETUP_SUCCESS, null));
mWifiStateMachinePrime.enterSoftAPMode(
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null));
mLooper.dispatchAll();
@@ -352,7 +346,8 @@
*/
@Test
public void testValidConfigIsSavedOnFailureToStart() throws Exception {
- when(mWifiInjector.makeWificond()).thenReturn(null);
+ when(mWifiNative.setupForSoftApMode(WIFI_IFACE_NAME))
+ .thenReturn(new Pair(WifiNative.SETUP_SUCCESS, null));
when(mWifiInjector.getWifiApConfigStore()).thenReturn(mWifiApConfigStore);
WifiConfiguration config = new WifiConfiguration();
config.SSID = "ThisIsAConfig";
@@ -365,14 +360,14 @@
}
/**
- * Thest that two calls to switch to SoftAPMode in succession ends up with the correct config.
+ * Test that two calls to switch to SoftAPMode in succession ends up with the correct config.
*
* Expectation: we should end up in SoftAPMode state configured with the second config.
*/
@Test
public void testStartSoftApModeTwiceWithTwoConfigs() throws Exception {
- when(mWifiInjector.makeWificond()).thenReturn(mWificond);
- when(mWificond.createApInterface(WIFI_IFACE_NAME)).thenReturn(mApInterface);
+ when(mWifiNative.setupForSoftApMode(WIFI_IFACE_NAME))
+ .thenReturn(new Pair(WifiNative.SETUP_SUCCESS, mApInterface));
when(mApInterface.getInterfaceName()).thenReturn(WIFI_IFACE_NAME);
when(mWifiInjector.getWifiApConfigStore()).thenReturn(mWifiApConfigStore);
WifiConfiguration config1 = new WifiConfiguration();
@@ -406,12 +401,12 @@
/**
* Test that we safely disable wifi if it is already disabled.
- * Expectations: We should not interact with wificond since we should have already cleaned up
+ * Expectations: We should not interact with WifiNative since we should have already cleaned up
* everything.
*/
@Test
public void disableWifiWhenAlreadyOff() throws Exception {
- verifyNoMoreInteractions(mWificond);
+ verifyNoMoreInteractions(mWifiNative);
mWifiStateMachinePrime.disableWifi();
}
}