diff options
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(); |