diff options
4 files changed, 69 insertions, 3 deletions
diff --git a/service/java/com/android/server/wifi/HostapdHal.java b/service/java/com/android/server/wifi/HostapdHal.java index 418fde66f..6ef0a7f86 100644 --- a/service/java/com/android/server/wifi/HostapdHal.java +++ b/service/java/com/android/server/wifi/HostapdHal.java @@ -584,9 +584,12 @@ public class HostapdHal { case WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS: disconnectReason = Ieee80211ReasonCode.WLAN_REASON_DISASSOC_AP_BUSY; break; - default: + case WifiManager.SAP_CLIENT_DISCONNECT_REASON_CODE_UNSPECIFIED: disconnectReason = Ieee80211ReasonCode.WLAN_REASON_UNSPECIFIED; break; + default: + throw new IllegalArgumentException( + "Unknown disconnect reason code:" + reasonCode); } android.hardware.wifi.hostapd.V1_2.HostapdStatus status = iHostapdV1_2.forceClientDisconnect(ifaceName, diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java index 44bbc73c4..3bf12ca34 100644 --- a/service/java/com/android/server/wifi/SoftApManager.java +++ b/service/java/com/android/server/wifi/SoftApManager.java @@ -16,6 +16,8 @@ package com.android.server.wifi; +import static android.net.wifi.WifiManager.SAP_CLIENT_DISCONNECT_REASON_CODE_UNSPECIFIED; + import static com.android.server.wifi.util.ApConfigUtil.ERROR_GENERIC; import static com.android.server.wifi.util.ApConfigUtil.ERROR_NO_CHANNEL; import static com.android.server.wifi.util.ApConfigUtil.ERROR_UNSUPPORTED_CONFIGURATION; @@ -433,9 +435,21 @@ public class SoftApManager implements ActiveModeManager { } /** + * Disconnect all connected clients on active softap interface(s). + * This is usually done just before stopSoftAp(). + */ + private void disconnectAllClients() { + for (WifiClient client : mConnectedClients) { + mWifiNative.forceClientDisconnect(mApInterfaceName, client.getMacAddress(), + SAP_CLIENT_DISCONNECT_REASON_CODE_UNSPECIFIED); + } + } + + /** * Teardown soft AP and teardown the interface. */ private void stopSoftAp() { + disconnectAllClients(); mWifiDiagnostics.stopLogging(mApInterfaceName); mWifiNative.teardownInterface(mApInterfaceName); Log.d(TAG, "Soft AP is stopped"); diff --git a/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java b/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java index 9db553f3b..52a28eafe 100644 --- a/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java +++ b/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java @@ -34,6 +34,7 @@ import android.hidl.manager.V1_0.IServiceNotification; import android.net.MacAddress; import android.net.wifi.SoftApConfiguration; import android.net.wifi.SoftApConfiguration.Builder; +import android.net.wifi.WifiManager; import android.net.wifi.nl80211.WifiNl80211Manager; import android.os.Handler; import android.os.IHwBinder; @@ -820,10 +821,28 @@ public class HostapdHalTest extends WifiBaseTest { when(mIHostapdMockV12.forceClientDisconnect(any(), any(), anyShort())) .thenReturn(mStatusSuccess12); - assertTrue(mHostapdHal.forceClientDisconnect(IFACE_NAME, test_client, 0)); + assertTrue(mHostapdHal.forceClientDisconnect(IFACE_NAME, test_client, + WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER)); verify(mIHostapdMockV12).forceClientDisconnect(any(), any(), anyShort()); } + @Test + public void testForceClientDisconnectFailureDueToInvalidArg() throws Exception { + executeAndValidateInitializationSequence(); + when(mServiceManagerMock.getTransport(anyString(), anyString())) + .thenReturn(IServiceManager.Transport.HWBINDER); + MacAddress test_client = MacAddress.fromString("da:a1:19:0:0:0"); + mIHostapdMockV12 = mock(android.hardware.wifi.hostapd.V1_2.IHostapd.class); + when(mIHostapdMockV12.forceClientDisconnect(any(), any(), anyShort())) + .thenReturn(mStatusSuccess12); + + try { + mHostapdHal.forceClientDisconnect(IFACE_NAME, test_client, -1); + fail(); + } catch (IllegalArgumentException e) { + } + } + /** * Verifies the failure handling in forceClientDisconnect. */ @@ -837,7 +856,8 @@ public class HostapdHalTest extends WifiBaseTest { when(mIHostapdMockV12.forceClientDisconnect(any(), any(), anyShort())) .thenReturn(mStatusFailure12); - assertFalse(mHostapdHal.forceClientDisconnect(IFACE_NAME, test_client, 0)); + assertFalse(mHostapdHal.forceClientDisconnect(IFACE_NAME, test_client, + WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER)); verify(mIHostapdMockV12).forceClientDisconnect(any(), any(), anyShort()); } diff --git a/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java b/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java index a7e21c996..ca7bc627c 100644 --- a/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java @@ -23,6 +23,7 @@ import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME; import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE; import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE; import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY; +import static android.net.wifi.WifiManager.SAP_CLIENT_DISCONNECT_REASON_CODE_UNSPECIFIED; import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED; import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING; import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED; @@ -1106,6 +1107,34 @@ public class SoftApManagerTest extends WifiBaseTest { } @Test + public void stopDisconnectsConnectedClients() throws Exception { + InOrder order = inOrder(mCallback, mWifiMetrics); + SoftApModeConfiguration apConfig = + new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null, + mTestSoftApCapability); + startSoftApAndVerifyEnabled(apConfig); + + order.verify(mCallback).onConnectedClientsChanged(new ArrayList<>()); + + mSoftApListenerCaptor.getValue().onConnectedClientsChanged( + TEST_NATIVE_CLIENT, true); + mLooper.dispatchAll(); + + order.verify(mCallback).onConnectedClientsChanged( + Mockito.argThat((List<WifiClient> clients) -> + clients.contains(TEST_CONNECTED_CLIENT)) + ); + verify(mWifiMetrics).addSoftApNumAssociatedStationsChangedEvent( + 1, apConfig.getTargetMode()); + + mSoftApManager.stop(); + mLooper.dispatchAll(); + + verify(mWifiNative).forceClientDisconnect(TEST_INTERFACE_NAME, TEST_MAC_ADDRESS, + SAP_CLIENT_DISCONNECT_REASON_CODE_UNSPECIFIED); + } + + @Test public void handlesInvalidConnectedClients() throws Exception { SoftApModeConfiguration apConfig = new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null, |