summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/Android.mk1
-rw-r--r--service/java/com/android/server/wifi/HostapdHal.java99
-rw-r--r--service/java/com/android/server/wifi/SoftApManager.java10
-rw-r--r--service/java/com/android/server/wifi/WifiNative.java7
-rw-r--r--tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java122
-rw-r--r--tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java35
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java4
7 files changed, 252 insertions, 26 deletions
diff --git a/service/Android.mk b/service/Android.mk
index 21d776855..c43acfae8 100644
--- a/service/Android.mk
+++ b/service/Android.mk
@@ -68,6 +68,7 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
android.hardware.wifi-V1.2-java \
android.hardware.wifi-V1.3-java \
android.hardware.wifi.hostapd-V1.0-java \
+ android.hardware.wifi.hostapd-V1.1-java \
android.hardware.wifi.supplicant-V1.0-java \
android.hardware.wifi.supplicant-V1.1-java \
ksoap2
diff --git a/service/java/com/android/server/wifi/HostapdHal.java b/service/java/com/android/server/wifi/HostapdHal.java
index 9395e2daf..5fb828ba0 100644
--- a/service/java/com/android/server/wifi/HostapdHal.java
+++ b/service/java/com/android/server/wifi/HostapdHal.java
@@ -33,6 +33,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wifi.WifiNative.HostapdDeathEventHandler;
import com.android.server.wifi.util.NativeUtil;
+import java.util.HashMap;
import java.util.NoSuchElementException;
import javax.annotation.concurrent.ThreadSafe;
@@ -44,6 +45,8 @@ import javax.annotation.concurrent.ThreadSafe;
@ThreadSafe
public class HostapdHal {
private static final String TAG = "HostapdHal";
+ @VisibleForTesting
+ public static final String HAL_INSTANCE_NAME = "default";
private final Object mLock = new Object();
private boolean mVerboseLoggingEnabled = false;
@@ -53,6 +56,7 @@ public class HostapdHal {
// Hostapd HAL interface objects
private IServiceManager mIServiceManager = null;
private IHostapd mIHostapd;
+ private HashMap<String, WifiNative.SoftApListener> mSoftApListeners = new HashMap<>();
private HostapdDeathEventHandler mDeathEventHandler;
private final IServiceNotification mServiceNotificationCallback =
@@ -107,6 +111,30 @@ public class HostapdHal {
}
/**
+ * Uses the IServiceManager to check if the device is running V1_1 of the HAL from the VINTF for
+ * the device.
+ * @return true if supported, false otherwise.
+ */
+ private boolean isV1_1() {
+ synchronized (mLock) {
+ if (mIServiceManager == null) {
+ Log.e(TAG, "isV1_1: called but mServiceManager is null!?");
+ return false;
+ }
+ try {
+ return (mIServiceManager.getTransport(
+ android.hardware.wifi.hostapd.V1_1.IHostapd.kInterfaceName,
+ HAL_INSTANCE_NAME)
+ != IServiceManager.Transport.EMPTY);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception while operating on IServiceManager: " + e);
+ handleRemoteException(e, "getTransport");
+ return false;
+ }
+ }
+ }
+
+ /**
* Link to death for IServiceManager object.
* @return true on success, false otherwise.
*/
@@ -195,6 +223,22 @@ public class HostapdHal {
}
}
+ private boolean registerCallback(
+ android.hardware.wifi.hostapd.V1_1.IHostapdCallback callback) {
+ synchronized (mLock) {
+ String methodStr = "registerCallback_1_1";
+ try {
+ android.hardware.wifi.hostapd.V1_1.IHostapd iHostapdV1_1 = getHostapdMockableV1_1();
+ if (iHostapdV1_1 == null) return false;
+ HostapdStatus status = iHostapdV1_1.registerCallback(callback);
+ return checkStatusAndLogFailure(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+ }
+
/**
* Initialize the IHostapd object.
* @return true on success, false otherwise.
@@ -212,6 +256,12 @@ public class HostapdHal {
return false;
}
if (!linkToHostapdDeath()) {
+ mIHostapd = null;
+ return false;
+ }
+ // Register for callbacks for 1.1 hostapd.
+ if (isV1_1() && !registerCallback(new HostapdCallback())) {
+ mIHostapd = null;
return false;
}
}
@@ -223,9 +273,11 @@ public class HostapdHal {
*
* @param ifaceName Name of the interface.
* @param config Configuration to use for the AP.
+ * @param listener Callback for AP events.
* @return true on success, false otherwise.
*/
- public boolean addAccessPoint(@NonNull String ifaceName, @NonNull WifiConfiguration config) {
+ public boolean addAccessPoint(@NonNull String ifaceName, @NonNull WifiConfiguration config,
+ @NonNull WifiNative.SoftApListener listener) {
synchronized (mLock) {
final String methodStr = "addAccessPoint";
IHostapd.IfaceParams ifaceParams = new IHostapd.IfaceParams();
@@ -266,7 +318,11 @@ public class HostapdHal {
if (!checkHostapdAndLogFailure(methodStr)) return false;
try {
HostapdStatus status = mIHostapd.addAccessPoint(ifaceParams, nwParams);
- return checkStatusAndLogFailure(status, methodStr);
+ if (!checkStatusAndLogFailure(status, methodStr)) {
+ return false;
+ }
+ mSoftApListeners.put(ifaceName, listener);
+ return true;
} catch (RemoteException e) {
handleRemoteException(e, methodStr);
return false;
@@ -286,7 +342,11 @@ public class HostapdHal {
if (!checkHostapdAndLogFailure(methodStr)) return false;
try {
HostapdStatus status = mIHostapd.removeAccessPoint(ifaceName);
- return checkStatusAndLogFailure(status, methodStr);
+ if (!checkStatusAndLogFailure(status, methodStr)) {
+ return false;
+ }
+ mSoftApListeners.remove(ifaceName);
+ return true;
} catch (RemoteException e) {
handleRemoteException(e, methodStr);
return false;
@@ -414,6 +474,19 @@ public class HostapdHal {
}
}
+ @VisibleForTesting
+ protected android.hardware.wifi.hostapd.V1_1.IHostapd getHostapdMockableV1_1()
+ throws RemoteException {
+ synchronized (mLock) {
+ try {
+ return android.hardware.wifi.hostapd.V1_1.IHostapd.castFrom(mIHostapd);
+ } catch (NoSuchElementException e) {
+ Log.e(TAG, "Failed to get IHostapd", e);
+ return null;
+ }
+ }
+ }
+
private static int getEncryptionType(WifiConfiguration localConfig) {
int encryptionType;
switch (localConfig.getAuthType()) {
@@ -493,15 +566,15 @@ public class HostapdHal {
}
}
- private static void logd(String s) {
- Log.d(TAG, s);
- }
-
- private static void logi(String s) {
- Log.i(TAG, s);
- }
-
- private static void loge(String s) {
- Log.e(TAG, s);
+ private class HostapdCallback extends
+ android.hardware.wifi.hostapd.V1_1.IHostapdCallback.Stub {
+ @Override
+ public void onFailure(String ifaceName) {
+ Log.w(TAG, "Failure on iface " + ifaceName);
+ WifiNative.SoftApListener listener = mSoftApListeners.get(ifaceName);
+ if (listener != null) {
+ listener.onFailure();
+ }
+ }
}
}
diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java
index 1d11996b4..53cbd7958 100644
--- a/service/java/com/android/server/wifi/SoftApManager.java
+++ b/service/java/com/android/server/wifi/SoftApManager.java
@@ -99,6 +99,12 @@ public class SoftApManager implements ActiveModeManager {
* Listener for soft AP events.
*/
private final SoftApListener mSoftApListener = new SoftApListener() {
+
+ @Override
+ public void onFailure() {
+ mStateMachine.sendMessage(SoftApStateMachine.CMD_FAILURE);
+ }
+
@Override
public void onNumAssociatedStationsChanged(int numStations) {
mStateMachine.sendMessage(
@@ -292,6 +298,7 @@ public class SoftApManager implements ActiveModeManager {
private class SoftApStateMachine extends StateMachine {
// Commands for the state machine.
public static final int CMD_START = 0;
+ public static final int CMD_FAILURE = 2;
public static final int CMD_INTERFACE_STATUS_CHANGED = 3;
public static final int CMD_NUM_ASSOCIATED_STATIONS_CHANGED = 4;
public static final int CMD_NO_ASSOCIATED_STATIONS_TIMEOUT = 5;
@@ -622,6 +629,9 @@ public class SoftApManager implements ActiveModeManager {
mApInterfaceName = null;
transitionTo(mIdleState);
break;
+ case CMD_FAILURE:
+ Log.w(TAG, "hostapd failure, stop and report failure");
+ /* fall through */
case CMD_INTERFACE_DOWN:
Log.w(TAG, "interface error, stop and report failure");
updateApState(WifiManager.WIFI_AP_STATE_FAILED,
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index 625f89cfa..72663e7ab 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -1321,6 +1321,11 @@ public class WifiNative {
*/
public interface SoftApListener {
/**
+ * Invoked when there is some fatal failure in the lower layers.
+ */
+ void onFailure();
+
+ /**
* Invoked when the number of associated stations changes.
*/
void onNumAssociatedStationsChanged(int numStations);
@@ -1378,7 +1383,7 @@ public class WifiNative {
Log.e(TAG, "Failed to register ap listener");
return false;
}
- if (!mHostapdHal.addAccessPoint(ifaceName, config)) {
+ if (!mHostapdHal.addAccessPoint(ifaceName, config, listener)) {
Log.e(TAG, "Failed to add acccess point");
mWifiMetrics.incrementNumSetupSoftApInterfaceFailureDueToHostapd();
return false;
diff --git a/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java b/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java
index 23a61e6cb..9121fe728 100644
--- a/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java
@@ -22,10 +22,12 @@ import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.*;
+import android.app.test.MockAnswerUtil;
import android.content.Context;
import android.hardware.wifi.hostapd.V1_0.HostapdStatus;
import android.hardware.wifi.hostapd.V1_0.HostapdStatusCode;
import android.hardware.wifi.hostapd.V1_0.IHostapd;
+import android.hardware.wifi.hostapd.V1_1.IHostapdCallback;
import android.hidl.manager.V1_0.IServiceManager;
import android.hidl.manager.V1_0.IServiceNotification;
import android.net.wifi.WifiConfiguration;
@@ -56,6 +58,9 @@ public class HostapdHalTest {
private @Mock IServiceManager mServiceManagerMock;
private @Mock IHostapd mIHostapdMock;
private @Mock WifiNative.HostapdDeathEventHandler mHostapdHalDeathHandler;
+ private @Mock WifiNative.SoftApListener mSoftApListener;
+ private android.hardware.wifi.hostapd.V1_1.IHostapd mIHostapdMockV1_1;
+ private IHostapdCallback mIHostapdCallback;
private MockResources mResources;
HostapdStatus mStatusSuccess;
HostapdStatus mStatusFailure;
@@ -86,6 +91,12 @@ public class HostapdHalTest {
protected IHostapd getHostapdMockable() throws RemoteException {
return mIHostapdMock;
}
+
+ @Override
+ protected android.hardware.wifi.hostapd.V1_1.IHostapd getHostapdMockableV1_1()
+ throws RemoteException {
+ return mIHostapdMockV1_1;
+ }
}
@Before
@@ -103,6 +114,8 @@ public class HostapdHalTest {
anyLong())).thenReturn(true);
when(mServiceManagerMock.registerForNotifications(anyString(), anyString(),
any(IServiceNotification.Stub.class))).thenReturn(true);
+ when(mServiceManagerMock.getTransport(anyString(), anyString()))
+ .thenReturn(IServiceManager.Transport.EMPTY);
when(mIHostapdMock.linkToDeath(any(IHwBinder.DeathRecipient.class),
anyLong())).thenReturn(true);
when(mIHostapdMock.linkToDeath(any(IHwBinder.DeathRecipient.class),
@@ -140,6 +153,29 @@ public class HostapdHalTest {
}
/**
+ * Sunny day scenario for V1.1 HostapdHal initialization
+ * Asserts successful initialization
+ */
+ @Test
+ public void testInitialize_successV1_1() throws Exception {
+ when(mServiceManagerMock.getTransport(anyString(), anyString()))
+ .thenReturn(IServiceManager.Transport.HWBINDER);
+ mIHostapdMockV1_1 = mock(android.hardware.wifi.hostapd.V1_1.IHostapd.class);
+ executeAndValidateInitializationSequenceV1_1(false);
+ }
+
+ /**
+ * Failure scenario for V1.1 HostapdHal initialization
+ */
+ @Test
+ public void testInitialize_registerCallbackFailureV1_1() throws Exception {
+ when(mServiceManagerMock.getTransport(anyString(), anyString()))
+ .thenReturn(IServiceManager.Transport.HWBINDER);
+ mIHostapdMockV1_1 = mock(android.hardware.wifi.hostapd.V1_1.IHostapd.class);
+ executeAndValidateInitializationSequenceV1_1(true);
+ }
+
+ /**
* Verifies the hostapd death handling.
*/
@Test
@@ -167,7 +203,7 @@ public class HostapdHalTest {
configuration.apChannel = apChannel;
configuration.apBand = WifiConfiguration.AP_BAND_2GHZ;
- assertTrue(mHostapdHal.addAccessPoint(IFACE_NAME, configuration));
+ assertTrue(mHostapdHal.addAccessPoint(IFACE_NAME, configuration, mSoftApListener));
verify(mIHostapdMock).addAccessPoint(any(), any());
assertEquals(IFACE_NAME, mIfaceParamsCaptor.getValue().ifaceName);
@@ -200,7 +236,7 @@ public class HostapdHalTest {
configuration.apChannel = apChannel;
configuration.apBand = WifiConfiguration.AP_BAND_5GHZ;
- assertTrue(mHostapdHal.addAccessPoint(IFACE_NAME, configuration));
+ assertTrue(mHostapdHal.addAccessPoint(IFACE_NAME, configuration, mSoftApListener));
verify(mIHostapdMock).addAccessPoint(any(), any());
assertEquals(IFACE_NAME, mIfaceParamsCaptor.getValue().ifaceName);
@@ -234,7 +270,7 @@ public class HostapdHalTest {
configuration.apChannel = apChannel;
configuration.apBand = WifiConfiguration.AP_BAND_5GHZ;
- assertTrue(mHostapdHal.addAccessPoint(IFACE_NAME, configuration));
+ assertTrue(mHostapdHal.addAccessPoint(IFACE_NAME, configuration, mSoftApListener));
verify(mIHostapdMock).addAccessPoint(any(), any());
assertEquals(IFACE_NAME, mIfaceParamsCaptor.getValue().ifaceName);
@@ -272,7 +308,7 @@ public class HostapdHalTest {
configuration.apChannel = apChannel;
configuration.apBand = WifiConfiguration.AP_BAND_2GHZ;
- assertTrue(mHostapdHal.addAccessPoint(IFACE_NAME, configuration));
+ assertTrue(mHostapdHal.addAccessPoint(IFACE_NAME, configuration, mSoftApListener));
verify(mIHostapdMock).addAccessPoint(any(), any());
assertEquals(IFACE_NAME, mIfaceParamsCaptor.getValue().ifaceName);
@@ -310,7 +346,7 @@ public class HostapdHalTest {
configuration.apChannel = apChannel;
configuration.apBand = WifiConfiguration.AP_BAND_2GHZ;
- assertTrue(mHostapdHal.addAccessPoint(IFACE_NAME, configuration));
+ assertTrue(mHostapdHal.addAccessPoint(IFACE_NAME, configuration, mSoftApListener));
verify(mIHostapdMock).addAccessPoint(any(), any());
assertEquals(IFACE_NAME, mIfaceParamsCaptor.getValue().ifaceName);
@@ -347,7 +383,7 @@ public class HostapdHalTest {
configuration.apChannel = apChannel;
configuration.apBand = WifiConfiguration.AP_BAND_ANY;
- assertTrue(mHostapdHal.addAccessPoint(IFACE_NAME, configuration));
+ assertTrue(mHostapdHal.addAccessPoint(IFACE_NAME, configuration, mSoftApListener));
verify(mIHostapdMock).addAccessPoint(any(), any());
assertEquals(IFACE_NAME, mIfaceParamsCaptor.getValue().ifaceName);
@@ -385,7 +421,7 @@ public class HostapdHalTest {
configuration.apChannel = apChannel;
configuration.apBand = WifiConfiguration.AP_BAND_ANY;
- assertTrue(mHostapdHal.addAccessPoint(IFACE_NAME, configuration));
+ assertTrue(mHostapdHal.addAccessPoint(IFACE_NAME, configuration, mSoftApListener));
verify(mIHostapdMock).addAccessPoint(any(), any());
assertEquals(IFACE_NAME, mIfaceParamsCaptor.getValue().ifaceName);
@@ -416,7 +452,7 @@ public class HostapdHalTest {
configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
configuration.apBand = WifiConfiguration.AP_BAND_5GHZ + 1;
- assertFalse(mHostapdHal.addAccessPoint(IFACE_NAME, configuration));
+ assertFalse(mHostapdHal.addAccessPoint(IFACE_NAME, configuration, mSoftApListener));
verify(mIHostapdMock, never()).addAccessPoint(any(), any());
}
@@ -435,7 +471,7 @@ public class HostapdHalTest {
configuration.apChannel = 6;
configuration.apBand = WifiConfiguration.AP_BAND_2GHZ;
- assertFalse(mHostapdHal.addAccessPoint(IFACE_NAME, configuration));
+ assertFalse(mHostapdHal.addAccessPoint(IFACE_NAME, configuration, mSoftApListener));
verify(mIHostapdMock).addAccessPoint(any(), any());
}
@@ -453,7 +489,7 @@ public class HostapdHalTest {
configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
configuration.apChannel = 6;
- assertFalse(mHostapdHal.addAccessPoint(IFACE_NAME, configuration));
+ assertFalse(mHostapdHal.addAccessPoint(IFACE_NAME, configuration, mSoftApListener));
verify(mIHostapdMock).addAccessPoint(any(), any());
}
@@ -492,6 +528,34 @@ public class HostapdHalTest {
verify(mIHostapdMock).removeAccessPoint(any());
}
+ /**
+ * Verifies the handling of onFailure callback from hostapd.
+ */
+ @Test
+ public void testOnFailureCallbackHandling() throws Exception {
+ when(mServiceManagerMock.getTransport(anyString(), anyString()))
+ .thenReturn(IServiceManager.Transport.HWBINDER);
+ mIHostapdMockV1_1 = mock(android.hardware.wifi.hostapd.V1_1.IHostapd.class);
+ executeAndValidateInitializationSequenceV1_1(false);
+
+ WifiConfiguration configuration = new WifiConfiguration();
+ configuration.SSID = NETWORK_SSID;
+ configuration.apBand = WifiConfiguration.AP_BAND_2GHZ;
+
+ assertTrue(mHostapdHal.addAccessPoint(IFACE_NAME, configuration, mSoftApListener));
+ verify(mIHostapdMock).addAccessPoint(any(), any());
+
+ // Trigger on failure.
+ mIHostapdCallback.onFailure(IFACE_NAME);
+ verify(mSoftApListener).onFailure();
+
+ // Now remove the access point and ensure that the callback is no longer handled.
+ reset(mSoftApListener);
+ assertTrue(mHostapdHal.removeAccessPoint(IFACE_NAME));
+ mIHostapdCallback.onFailure(IFACE_NAME);
+ verify(mSoftApListener, never()).onFailure();
+ }
+
private void executeAndValidateInitializationSequence() throws Exception {
executeAndValidateInitializationSequence(false, false);
}
@@ -531,6 +595,44 @@ public class HostapdHalTest {
}
}
+ /**
+ * Calls.initialize(), mocking various callback answers and verifying flow, asserting for the
+ * expected result. Verifies if IHostapd manager is initialized or reset.
+ */
+ private void executeAndValidateInitializationSequenceV1_1(
+ boolean causeCallbackFailure) throws Exception {
+ boolean shouldSucceed = !causeCallbackFailure;
+ mInOrder = inOrder(mServiceManagerMock, mIHostapdMock);
+ if (causeCallbackFailure) {
+ doAnswer(new MockAnswerUtil.AnswerWithArguments() {
+ public HostapdStatus answer(IHostapdCallback cb)
+ throws RemoteException {
+ return mStatusFailure;
+ }
+ }).when(mIHostapdMockV1_1).registerCallback(any(IHostapdCallback.class));
+ } else {
+ doAnswer(new MockAnswerUtil.AnswerWithArguments() {
+ public HostapdStatus answer(IHostapdCallback cb)
+ throws RemoteException {
+ mIHostapdCallback = cb;
+ return mStatusSuccess;
+ }
+ }).when(mIHostapdMockV1_1).registerCallback(any(IHostapdCallback.class));
+ }
+ // Initialize HostapdHal, should call serviceManager.registerForNotifications
+ assertTrue(mHostapdHal.initialize());
+ // verify: service manager initialization sequence
+ mInOrder.verify(mServiceManagerMock).linkToDeath(mServiceManagerDeathCaptor.capture(),
+ anyLong());
+ mInOrder.verify(mServiceManagerMock).registerForNotifications(
+ eq(IHostapd.kInterfaceName), eq(""), mServiceNotificationCaptor.capture());
+ // act: cause the onRegistration(...) callback to execute
+ mServiceNotificationCaptor.getValue().onRegistration(IHostapd.kInterfaceName, "", true);
+ assertEquals(shouldSucceed, mHostapdHal.isInitializationComplete());
+ mInOrder.verify(mIHostapdMock).linkToDeath(mHostapdDeathCaptor.capture(), anyLong());
+ verify(mIHostapdMockV1_1).registerCallback(any(IHostapdCallback.class));
+ }
+
private HostapdStatus createHostapdStatus(int code) {
HostapdStatus status = new HostapdStatus();
status.code = code;
diff --git a/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java b/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
index 21c3797b3..b0ed93c22 100644
--- a/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
@@ -712,6 +712,41 @@ public class SoftApManagerTest {
verifyNoMoreInteractions(mContext, mCallback, mWifiNative);
}
+ /**
+ * Verify that onFailure from hostapd is handled by SoftApManager.
+ */
+ @Test
+ public void testHostapdOnFailureHandled() throws Exception {
+ SoftApModeConfiguration softApModeConfig =
+ new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null);
+ startSoftApAndVerifyEnabled(softApModeConfig);
+
+ // reset to clear verified Intents for ap state change updates
+ reset(mContext, mCallback, mWifiNative);
+
+ InOrder order = inOrder(mCallback, mContext);
+
+ mSoftApListenerCaptor.getValue().onFailure();
+ mLooper.dispatchAll();
+
+ order.verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
+ WifiManager.SAP_START_FAILURE_GENERAL);
+ ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mContext, times(3)).sendStickyBroadcastAsUser(intentCaptor.capture(),
+ eq(UserHandle.ALL));
+
+ List<Intent> capturedIntents = intentCaptor.getAllValues();
+ checkApStateChangedBroadcast(capturedIntents.get(0), WIFI_AP_STATE_FAILED,
+ WIFI_AP_STATE_ENABLED, WifiManager.SAP_START_FAILURE_GENERAL, TEST_INTERFACE_NAME,
+ softApModeConfig.getTargetMode());
+ checkApStateChangedBroadcast(capturedIntents.get(1), WIFI_AP_STATE_DISABLING,
+ WIFI_AP_STATE_FAILED, HOTSPOT_NO_ERROR, TEST_INTERFACE_NAME,
+ softApModeConfig.getTargetMode());
+ checkApStateChangedBroadcast(capturedIntents.get(2), WIFI_AP_STATE_DISABLED,
+ WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR, TEST_INTERFACE_NAME,
+ softApModeConfig.getTargetMode());
+ }
+
@Test
public void updatesMetricsOnChannelSwitchedEvent() throws Exception {
SoftApModeConfiguration apConfig =
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java
index 1f513699e..ce67b3510 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java
@@ -149,7 +149,7 @@ public class WifiNativeInterfaceManagementTest {
when(mHostapdHal.isInitializationStarted()).thenReturn(false);
when(mHostapdHal.isInitializationComplete()).thenReturn(true);
when(mHostapdHal.startDaemon()).thenReturn(true);
- when(mHostapdHal.addAccessPoint(any(), any())).thenReturn(true);
+ when(mHostapdHal.addAccessPoint(any(), any(), any())).thenReturn(true);
when(mHostapdHal.removeAccessPoint(any())).thenReturn(true);
when(mNwManagementService.getInterfaceConfig(IFACE_NAME_0))
@@ -774,7 +774,7 @@ public class WifiNativeInterfaceManagementTest {
mock(WifiNative.SoftApListener.class)));
mInOrder.verify(mWificondControl).registerApListener(any(), any());
- mInOrder.verify(mHostapdHal).addAccessPoint(any(), any());
+ mInOrder.verify(mHostapdHal).addAccessPoint(any(), any(), any());
// Trigger vendor HAL death
mHostapdDeathHandlerCaptor.getValue().onDeath();