Merge "Use wificond to configure and start hostapd"
diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java
index 266234b..46ef28f 100644
--- a/service/java/com/android/server/wifi/SoftApManager.java
+++ b/service/java/com/android/server/wifi/SoftApManager.java
@@ -23,8 +23,8 @@
import android.net.wifi.IApInterface;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
+import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.os.IBinder.DeathRecipient;
-import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
@@ -34,6 +34,7 @@
import com.android.internal.util.StateMachine;
import com.android.server.wifi.util.ApConfigUtil;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Locale;
@@ -44,18 +45,17 @@
public class SoftApManager {
private static final String TAG = "SoftApManager";
- private final INetworkManagementService mNmService;
private final WifiNative mWifiNative;
private final ArrayList<Integer> mAllowed2GChannels;
private final String mCountryCode;
- private final String mInterfaceName;
-
private final SoftApStateMachine mStateMachine;
private final Listener mListener;
+ private final IApInterface mApInterface;
+
/**
* Listener for soft AP state changes.
*/
@@ -70,20 +70,17 @@
public SoftApManager(Looper looper,
WifiNative wifiNative,
- INetworkManagementService nmService,
String countryCode,
ArrayList<Integer> allowed2GChannels,
Listener listener,
IApInterface apInterface) {
- mStateMachine = new SoftApStateMachine(looper, apInterface);
+ mStateMachine = new SoftApStateMachine(looper);
- mNmService = nmService;
mWifiNative = wifiNative;
mCountryCode = countryCode;
mAllowed2GChannels = allowed2GChannels;
mListener = listener;
-
- mInterfaceName = mWifiNative.getInterfaceName();
+ mApInterface = apInterface;
}
/**
@@ -118,8 +115,8 @@
* @return integer result code
*/
private int startSoftAp(WifiConfiguration config) {
- if (config == null) {
- Log.e(TAG, "Unable to start soft AP without configuration");
+ if (config == null || config.SSID == null) {
+ Log.e(TAG, "Unable to start soft AP without valid configuration");
return ERROR_GENERIC;
}
@@ -147,11 +144,30 @@
}
}
+ int encryptionType = getIApInterfaceEncryptionType(localConfig);
+
try {
- mNmService.startAccessPoint(localConfig, mInterfaceName);
- } catch (Exception e) {
+ // Note that localConfig.SSID is intended to be either a hex string or "double quoted".
+ // However, it seems that whatever is handing us these configurations does not obey
+ // this convention.
+ boolean success = mApInterface.writeHostapdConfig(
+ localConfig.SSID.getBytes(StandardCharsets.UTF_8), false,
+ localConfig.apChannel, encryptionType,
+ (localConfig.preSharedKey != null)
+ ? localConfig.preSharedKey.getBytes(StandardCharsets.UTF_8)
+ : new byte[0]);
+ if (!success) {
+ Log.e(TAG, "Failed to write hostapd configuration");
+ return ERROR_GENERIC;
+ }
+
+ success = mApInterface.startHostapd();
+ if (!success) {
+ Log.e(TAG, "Failed to start hostapd.");
+ return ERROR_GENERIC;
+ }
+ } catch (RemoteException e) {
Log.e(TAG, "Exception in starting soft AP: " + e);
- return ERROR_GENERIC;
}
Log.d(TAG, "Soft AP is started");
@@ -159,13 +175,34 @@
return SUCCESS;
}
+ private static int getIApInterfaceEncryptionType(WifiConfiguration localConfig) {
+ int encryptionType;
+ switch (localConfig.getAuthType()) {
+ case KeyMgmt.NONE:
+ encryptionType = IApInterface.ENCRYPTION_TYPE_NONE;
+ break;
+ case KeyMgmt.WPA_PSK:
+ encryptionType = IApInterface.ENCRYPTION_TYPE_WPA;
+ break;
+ case KeyMgmt.WPA2_PSK:
+ encryptionType = IApInterface.ENCRYPTION_TYPE_WPA2;
+ break;
+ default:
+ // We really shouldn't default to None, but this was how NetworkManagementService
+ // used to do this.
+ encryptionType = IApInterface.ENCRYPTION_TYPE_NONE;
+ break;
+ }
+ return encryptionType;
+ }
+
/**
* Teardown soft AP.
*/
private void stopSoftAp() {
try {
- mNmService.stopAccessPoint(mInterfaceName);
- } catch (Exception e) {
+ mApInterface.stopHostapd();
+ } catch (RemoteException e) {
Log.e(TAG, "Exception in stopping soft AP: " + e);
return;
}
@@ -178,8 +215,6 @@
public static final int CMD_STOP = 1;
public static final int CMD_AP_INTERFACE_BINDER_DEATH = 2;
- private final IApInterface mApInterface;
-
private final State mIdleState = new IdleState();
private final State mStartedState = new StartedState();
@@ -193,9 +228,8 @@
}
- SoftApStateMachine(Looper looper, IApInterface apInterface) {
+ SoftApStateMachine(Looper looper) {
super(TAG, looper);
- mApInterface = apInterface;
addState(mIdleState);
addState(mStartedState);
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index cc117da..c354407 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -232,7 +232,7 @@
SoftApManager.Listener listener, IApInterface apInterface) {
return new SoftApManager(
mWifiServiceHandlerThread.getLooper(),
- wifiNative, nmService, countryCode,
+ wifiNative, countryCode,
allowed2GChannels, listener, apInterface);
}
}
diff --git a/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java b/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
index 5919156..2cf2398 100644
--- a/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
@@ -17,6 +17,7 @@
package com.android.server.wifi;
import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.inOrder;
@@ -30,7 +31,6 @@
import android.net.wifi.WifiManager;
import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
-import android.os.INetworkManagementService;
import android.os.test.TestLooper;
import android.test.suitebuilder.annotation.SmallTest;
@@ -51,20 +51,19 @@
private static final String TAG = "SoftApManagerTest";
- private static final String TEST_INTERFACE_NAME = "TestInterface";
+ private static final String TEST_SSID = "TestSSID";
private static final String TEST_COUNTRY_CODE = "TestCountry";
private static final Integer[] ALLOWED_2G_CHANNELS = {1, 2, 3, 4};
private final ArrayList<Integer> mAllowed2GChannels =
- new ArrayList<Integer>(Arrays.asList(ALLOWED_2G_CHANNELS));
+ new ArrayList<>(Arrays.asList(ALLOWED_2G_CHANNELS));
TestLooper mLooper;
@Mock WifiNative mWifiNative;
- @Mock INetworkManagementService mNmService;
@Mock SoftApManager.Listener mListener;
@Mock InterfaceConfiguration mInterfaceConfiguration;
- @Mock IApInterface mApInterface;
@Mock IBinder mApInterfaceBinder;
+ @Mock IApInterface mApInterface;
final ArgumentCaptor<DeathRecipient> mDeathListenerCaptor =
ArgumentCaptor.forClass(DeathRecipient.class);
@@ -76,14 +75,14 @@
MockitoAnnotations.initMocks(this);
mLooper = new TestLooper();
- when(mWifiNative.getInterfaceName()).thenReturn(TEST_INTERFACE_NAME);
- when(mNmService.getInterfaceConfig(TEST_INTERFACE_NAME))
- .thenReturn(mInterfaceConfiguration);
when(mApInterface.asBinder()).thenReturn(mApInterfaceBinder);
+ when(mApInterface.startHostapd()).thenReturn(true);
+ when(mApInterface.stopHostapd()).thenReturn(true);
+ when(mApInterface.writeHostapdConfig(
+ any(), anyBoolean(), anyInt(), anyInt(), any())).thenReturn(true);
mSoftApManager = new SoftApManager(mLooper.getLooper(),
mWifiNative,
- mNmService,
TEST_COUNTRY_CODE,
mAllowed2GChannels,
mListener,
@@ -124,7 +123,7 @@
mSoftApManager.stop();
mLooper.dispatchAll();
- verify(mNmService).stopAccessPoint(TEST_INTERFACE_NAME);
+ verify(mApInterface).stopHostapd();
order.verify(mListener).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLING, 0);
order.verify(mListener).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLED, 0);
}
@@ -143,7 +142,7 @@
/** Starts soft AP and verifies that it is enabled successfully. */
protected void startSoftApAndVerifyEnabled() throws Exception {
- InOrder order = inOrder(mListener, mApInterfaceBinder);
+ InOrder order = inOrder(mListener, mApInterfaceBinder, mApInterface);
/**
* Only test the default configuration. Testing for different configurations
@@ -151,15 +150,17 @@
*/
WifiConfiguration config = new WifiConfiguration();
config.apBand = WifiConfiguration.AP_BAND_2GHZ;
+ config.SSID = TEST_SSID;
when(mWifiNative.isHalStarted()).thenReturn(false);
when(mWifiNative.setCountryCodeHal(TEST_COUNTRY_CODE.toUpperCase(Locale.ROOT)))
.thenReturn(true);
mSoftApManager.start(config);
mLooper.dispatchAll();
- verify(mNmService).startAccessPoint(
- any(WifiConfiguration.class), eq(TEST_INTERFACE_NAME));
order.verify(mListener).onStateChanged(WifiManager.WIFI_AP_STATE_ENABLING, 0);
order.verify(mApInterfaceBinder).linkToDeath(mDeathListenerCaptor.capture(), eq(0));
+ order.verify(mApInterface).writeHostapdConfig(
+ any(), anyBoolean(), anyInt(), anyInt(), any());
+ order.verify(mApInterface).startHostapd();
order.verify(mListener).onStateChanged(WifiManager.WIFI_AP_STATE_ENABLED, 0);
}