diff options
author | James Mattis <jmattis@google.com> | 2019-10-04 18:19:07 -0700 |
---|---|---|
committer | James Mattis <jmattis@google.com> | 2019-10-24 17:11:44 -0700 |
commit | b1a1f59a259f79574e33b2cbd1d47a5573244858 (patch) | |
tree | c678e7ef4dc0b76242989afe7b854cd843e69ee6 | |
parent | 2d22d21a2bf52b552880742ecb1fa50d734beff1 (diff) |
Support for hotspot client visibility.
Adding support for visibility into clients that connect to an active hotspot.
Bug: 137309578
Test: atest FrameworksWifiTests:com.android.server.wifi.ActiveModeWardenTest
atest FrameworksWifiTests:com.android.server.wifi.SoftApManagerTest
atest FrameworksWifiTests:com.android.server.wifi.WifiServiceImplTest
atest FrameworksWifiTests:com.android.server.wifi.WificondControlTest
Change-Id: Ifab5be1c969106916412617043074c7b5bc9a2d1
9 files changed, 261 insertions, 132 deletions
diff --git a/service/java/com/android/server/wifi/ActiveModeWarden.java b/service/java/com/android/server/wifi/ActiveModeWarden.java index 315ae5f0a..818c410ae 100644 --- a/service/java/com/android/server/wifi/ActiveModeWarden.java +++ b/service/java/com/android/server/wifi/ActiveModeWarden.java @@ -22,6 +22,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.location.LocationManager; +import android.net.wifi.WifiClient; import android.net.wifi.WifiManager; import android.os.BatteryStats; import android.os.Handler; @@ -44,6 +45,7 @@ import com.android.server.wifi.util.WifiPermissionsUtil; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.Collection; +import java.util.List; /** * This class provides the implementation for different WiFi operating modes. @@ -397,13 +399,17 @@ public class ActiveModeWarden { } @Override - public void onNumClientsChanged(int numClients) { + public void onConnectedClientsChanged(List<WifiClient> clients) { switch (mMode) { case WifiManager.IFACE_IP_MODE_TETHERED: - if (mSoftApCallback != null) mSoftApCallback.onNumClientsChanged(numClients); + if (mSoftApCallback != null) { + mSoftApCallback.onConnectedClientsChanged(clients); + } break; case WifiManager.IFACE_IP_MODE_LOCAL_ONLY: - if (mLohsCallback != null) mLohsCallback.onNumClientsChanged(numClients); + if (mLohsCallback != null) { + mLohsCallback.onConnectedClientsChanged(clients); + } break; } } diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java index 3c4a6797c..1f6a5fcc6 100644 --- a/service/java/com/android/server/wifi/SoftApManager.java +++ b/service/java/com/android/server/wifi/SoftApManager.java @@ -26,6 +26,7 @@ import android.content.Intent; import android.database.ContentObserver; import android.net.MacAddress; import android.net.wifi.ScanResult; +import android.net.wifi.WifiClient; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.Handler; @@ -46,11 +47,14 @@ import com.android.internal.util.WakeupMessage; import com.android.server.wifi.WifiNative.InterfaceCallback; import com.android.server.wifi.WifiNative.SoftApListener; import com.android.server.wifi.util.ApConfigUtil; +import com.android.server.wifi.wificond.NativeWifiClient; import java.io.FileDescriptor; import java.io.PrintWriter; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Date; +import java.util.List; import java.util.Locale; /** @@ -92,7 +96,7 @@ public class SoftApManager implements ActiveModeManager { private int mReportedFrequency = -1; private int mReportedBandwidth = -1; - private int mNumAssociatedStations = 0; + private List<WifiClient> mConnectedClients = new ArrayList<>(); private boolean mTimeoutEnabled = false; private final SarManager mSarManager; @@ -114,9 +118,9 @@ public class SoftApManager implements ActiveModeManager { } @Override - public void onNumAssociatedStationsChanged(int numStations) { - mStateMachine.sendMessage( - SoftApStateMachine.CMD_NUM_ASSOCIATED_STATIONS_CHANGED, numStations); + public void onConnectedClientsChanged(List<NativeWifiClient> clients) { + mStateMachine.sendMessage(SoftApStateMachine.CMD_ASSOCIATED_STATIONS_CHANGED, + clients); } @Override @@ -203,7 +207,7 @@ public class SoftApManager implements ActiveModeManager { pw.println("mApConfig.wifiConfiguration.SSID: " + wifiConfig.SSID); pw.println("mApConfig.wifiConfiguration.apBand: " + wifiConfig.apBand); pw.println("mApConfig.wifiConfiguration.hiddenSSID: " + wifiConfig.hiddenSSID); - pw.println("mNumAssociatedStations: " + mNumAssociatedStations); + pw.println("mConnectedClients.size(): " + mConnectedClients.size()); pw.println("mTimeoutEnabled: " + mTimeoutEnabled); pw.println("mReportedFrequency: " + mReportedFrequency); pw.println("mReportedBandwidth: " + mReportedBandwidth); @@ -223,9 +227,10 @@ public class SoftApManager implements ActiveModeManager { /** * Update AP state. - * @param newState new AP state + * + * @param newState new AP state * @param currentState current AP state - * @param reason Failure reason if the new AP state is in failure state + * @param reason Failure reason if the new AP state is in failure state */ private void updateApState(int newState, int currentState, int reason) { mSoftApCallback.onStateChanged(newState, reason); @@ -363,7 +368,7 @@ public class SoftApManager implements ActiveModeManager { 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_ASSOCIATED_STATIONS_CHANGED = 4; public static final int CMD_NO_ASSOCIATED_STATIONS_TIMEOUT = 5; public static final int CMD_TIMEOUT_TOGGLE_CHANGED = 6; public static final int CMD_INTERFACE_DESTROYED = 7; @@ -439,8 +444,8 @@ public class SoftApManager implements ActiveModeManager { failureReason = WifiManager.SAP_START_FAILURE_NO_CHANNEL; } updateApState(WifiManager.WIFI_AP_STATE_FAILED, - WifiManager.WIFI_AP_STATE_ENABLING, - failureReason); + WifiManager.WIFI_AP_STATE_ENABLING, + failureReason); stopSoftAp(); mWifiMetrics.incrementSoftApStartResult(false, failureReason); mModeListener.onStartFailure(); @@ -463,8 +468,8 @@ public class SoftApManager implements ActiveModeManager { private SoftApTimeoutEnabledSettingObserver mSettingObserver; /** - * Observer for timeout settings changes. - */ + * Observer for timeout settings changes. + */ private class SoftApTimeoutEnabledSettingObserver extends ContentObserver { SoftApTimeoutEnabledSettingObserver(Handler handler) { super(handler); @@ -520,35 +525,61 @@ public class SoftApManager implements ActiveModeManager { } /** - * Set number of stations associated with this soft AP - * @param numStations Number of connected stations + * Set stations associated with this soft AP + * @param clients The connected stations */ - private void setNumAssociatedStations(int numStations) { - if (mNumAssociatedStations == numStations) { + private void setConnectedClients(List<NativeWifiClient> clients) { + if (clients == null) { + return; + } + + List<WifiClient> convertedClients = createWifiClients(clients); + if (mConnectedClients.equals(convertedClients)) { return; } - mNumAssociatedStations = numStations; - Log.d(TAG, "Number of associated stations changed: " + mNumAssociatedStations); + + mConnectedClients = new ArrayList<>(convertedClients); + Log.d(TAG, "The connected wifi stations have changed with count: " + + clients.size()); if (mSoftApCallback != null) { - mSoftApCallback.onNumClientsChanged(mNumAssociatedStations); + mSoftApCallback.onConnectedClientsChanged(mConnectedClients); } else { - Log.e(TAG, "SoftApCallback is null. Dropping NumClientsChanged event."); + Log.e(TAG, + "SoftApCallback is null. Dropping ConnectedClientsChanged event." + ); } + mWifiMetrics.addSoftApNumAssociatedStationsChangedEvent( - mNumAssociatedStations, mApConfig.getTargetMode()); + mConnectedClients.size(), mApConfig.getTargetMode()); - if (mNumAssociatedStations == 0) { + if (mConnectedClients.size() == 0) { scheduleTimeoutMessage(); } else { cancelTimeoutMessage(); } } + private List<WifiClient> createWifiClients(List<NativeWifiClient> nativeClients) { + List<WifiClient> clients = new ArrayList<>(); + if (nativeClients == null || nativeClients.size() == 0) { + return clients; + } + + for (int i = 0; i < nativeClients.size(); i++) { + MacAddress macAddress = MacAddress.fromBytes(nativeClients.get(i).macAddress); + WifiClient client = new WifiClient(macAddress); + clients.add(client); + } + + return clients; + } + private void onUpChanged(boolean isUp) { if (isUp == mIfaceIsUp) { return; // no change } + mIfaceIsUp = isUp; if (isUp) { Log.d(TAG, "SoftAp is ready for use"); @@ -557,7 +588,7 @@ public class SoftApManager implements ActiveModeManager { mModeListener.onStarted(); mWifiMetrics.incrementSoftApStartResult(true, 0); if (mSoftApCallback != null) { - mSoftApCallback.onNumClientsChanged(mNumAssociatedStations); + mSoftApCallback.onConnectedClientsChanged(mConnectedClients); } } else { // the interface was up, but goes down @@ -585,8 +616,8 @@ public class SoftApManager implements ActiveModeManager { mSarManager.setSapWifiState(WifiManager.WIFI_AP_STATE_ENABLED); - Log.d(TAG, "Resetting num stations on start"); - mNumAssociatedStations = 0; + Log.d(TAG, "Resetting connected clients on start"); + mConnectedClients = new ArrayList<>(); scheduleTimeoutMessage(); } @@ -600,7 +631,7 @@ public class SoftApManager implements ActiveModeManager { mSettingObserver.unregister(); } Log.d(TAG, "Resetting num stations on stop"); - setNumAssociatedStations(0); + setConnectedClients(new ArrayList<>()); cancelTimeoutMessage(); // Need this here since we are exiting |Started| state and won't handle any // future CMD_INTERFACE_STATUS_CHANGED events after this point @@ -620,9 +651,9 @@ public class SoftApManager implements ActiveModeManager { int band = mApConfig.getWifiConfiguration().apBand; boolean bandPreferenceViolated = (band == WifiConfiguration.AP_BAND_2GHZ - && ScanResult.is5GHz(mReportedFrequency)) - || (band == WifiConfiguration.AP_BAND_5GHZ - && ScanResult.is24GHz(mReportedFrequency)); + && ScanResult.is5GHz(mReportedFrequency)) + || (band == WifiConfiguration.AP_BAND_5GHZ + && ScanResult.is24GHz(mReportedFrequency)); if (bandPreferenceViolated) { Log.e(TAG, "Channel does not satisfy user band preference: " + mReportedFrequency); @@ -633,13 +664,16 @@ public class SoftApManager implements ActiveModeManager { @Override public boolean processMessage(Message message) { switch (message.what) { - case CMD_NUM_ASSOCIATED_STATIONS_CHANGED: - if (message.arg1 < 0) { - Log.e(TAG, "Invalid number of associated stations: " + message.arg1); + case CMD_ASSOCIATED_STATIONS_CHANGED: + if (!(message.obj instanceof List)) { + Log.e(TAG, "Invalid type returned for" + + " CMD_ASSOCIATED_STATIONS_CHANGED"); break; } - Log.d(TAG, "Setting num stations on CMD_NUM_ASSOCIATED_STATIONS_CHANGED"); - setNumAssociatedStations(message.arg1); + + Log.d(TAG, "Setting connected stations on" + + " CMD_ASSOCIATED_STATIONS_CHANGED"); + setConnectedClients((List<NativeWifiClient>) message.obj); break; case CMD_SOFT_AP_CHANNEL_SWITCHED: mReportedFrequency = message.arg1; @@ -659,7 +693,7 @@ public class SoftApManager implements ActiveModeManager { if (!mTimeoutEnabled) { cancelTimeoutMessage(); } - if (mTimeoutEnabled && mNumAssociatedStations == 0) { + if (mTimeoutEnabled && mConnectedClients.size() == 0) { scheduleTimeoutMessage(); } break; @@ -676,7 +710,7 @@ public class SoftApManager implements ActiveModeManager { + " Dropping."); break; } - if (mNumAssociatedStations != 0) { + if (mConnectedClients.size() != 0) { Log.wtf(TAG, "Timeout message received but has clients. Dropping."); break; } diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java index 7b55af147..b9e766811 100644 --- a/service/java/com/android/server/wifi/WifiNative.java +++ b/service/java/com/android/server/wifi/WifiNative.java @@ -39,6 +39,7 @@ import com.android.internal.util.HexDump; import com.android.server.net.BaseNetworkObserver; import com.android.server.wifi.util.FrameParser; import com.android.server.wifi.util.NativeUtil; +import com.android.server.wifi.wificond.NativeWifiClient; import java.io.PrintWriter; import java.io.StringWriter; @@ -1618,9 +1619,9 @@ public class WifiNative { void onFailure(); /** - * Invoked when the number of associated stations changes. + * Invoked when the associated stations changes. */ - void onNumAssociatedStationsChanged(int numStations); + void onConnectedClientsChanged(List<NativeWifiClient> clients); /** * Invoked when the channel switch event happens. diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java index 26415465f..9d3f422cb 100644 --- a/service/java/com/android/server/wifi/WifiServiceImpl.java +++ b/service/java/com/android/server/wifi/WifiServiceImpl.java @@ -59,6 +59,7 @@ import android.net.wifi.ITrafficStateCallback; import android.net.wifi.ITxPacketCountListener; import android.net.wifi.ScanResult; import android.net.wifi.WifiActivityEnergyInfo; +import android.net.wifi.WifiClient; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; @@ -831,7 +832,7 @@ public class WifiServiceImpl extends BaseWifiService { */ private final Object mLock = new Object(); private int mTetheredSoftApState = WIFI_AP_STATE_DISABLED; - private int mTetheredSoftApNumClients = 0; + private List<WifiClient> mTetheredSoftApConnectedClients = new ArrayList<>(); public int getState() { synchronized (mLock) { @@ -848,8 +849,8 @@ public class WifiServiceImpl extends BaseWifiService { } } - public int getNumClients() { - return mTetheredSoftApNumClients; + public List<WifiClient> getConnectedClients() { + return mTetheredSoftApConnectedClients; } private final ExternalCallbackTracker<ISoftApCallback> mRegisteredSoftApCallbacks = @@ -894,22 +895,22 @@ public class WifiServiceImpl extends BaseWifiService { } /** - * Called when number of connected clients to soft AP changes. + * Called when the connected clients to soft AP changes. * - * @param numClients number of connected clients to soft AP + * @param clients connected clients to soft AP */ @Override - public void onNumClientsChanged(int numClients) { - mTetheredSoftApNumClients = numClients; + public void onConnectedClientsChanged(List<WifiClient> clients) { + mTetheredSoftApConnectedClients = new ArrayList<>(clients); Iterator<ISoftApCallback> iterator = mRegisteredSoftApCallbacks.getCallbacks().iterator(); while (iterator.hasNext()) { ISoftApCallback callback = iterator.next(); try { - callback.onNumClientsChanged(numClients); + callback.onConnectedClientsChanged(mTetheredSoftApConnectedClients); } catch (RemoteException e) { - Log.e(TAG, "onNumClientsChanged: remote exception -- " + e); + Log.e(TAG, "onConnectedClientsChanged: remote exception -- " + e); // TODO(b/138863863) remove does nothing, getCallbacks() returns a copy iterator.remove(); } @@ -1210,8 +1211,9 @@ public class WifiServiceImpl extends BaseWifiService { mLohsState = state; } } + @Override - public void onNumClientsChanged(int numClients) { + public void onConnectedClientsChanged(List<WifiClient> clients) { // Nothing to do } } @@ -1254,7 +1256,7 @@ public class WifiServiceImpl extends BaseWifiService { // Update the client about the current state immediately after registering the callback try { callback.onStateChanged(mTetheredSoftApTracker.getState(), 0); - callback.onNumClientsChanged(mTetheredSoftApTracker.getNumClients()); + callback.onConnectedClientsChanged(mTetheredSoftApTracker.getConnectedClients()); } catch (RemoteException e) { Log.e(TAG, "registerSoftApCallback: remote exception -- " + e); } @@ -2166,7 +2168,7 @@ public class WifiServiceImpl extends BaseWifiService { final boolean privilegedFinal = privileged; return mWifiThreadRunner.call( () -> mPasspointManager.getProviderConfigs(uid, privilegedFinal), - Collections.emptyList()); + Collections.emptyList()); } /** diff --git a/service/java/com/android/server/wifi/WificondControl.java b/service/java/com/android/server/wifi/WificondControl.java index 217a0dd98..0fc151bb8 100644 --- a/service/java/com/android/server/wifi/WificondControl.java +++ b/service/java/com/android/server/wifi/WificondControl.java @@ -46,6 +46,7 @@ import com.android.server.wifi.wificond.ISendMgmtFrameEvent; import com.android.server.wifi.wificond.IWifiScannerImpl; import com.android.server.wifi.wificond.IWificond; import com.android.server.wifi.wificond.NativeScanResult; +import com.android.server.wifi.wificond.NativeWifiClient; import com.android.server.wifi.wificond.PnoNetwork; import com.android.server.wifi.wificond.PnoSettings; import com.android.server.wifi.wificond.RadioChainInfo; @@ -173,8 +174,15 @@ public class WificondControl implements IBinder.DeathRecipient { } @Override - public void onNumAssociatedStationsChanged(int numStations) { - mSoftApListener.onNumAssociatedStationsChanged(numStations); + public void onConnectedClientsChanged(NativeWifiClient[] clients) { + if (mVerboseLoggingEnabled) { + Log.d(TAG, "onConnectedClientsChanged called with " + clients.length + " clients"); + for (int i = 0; i < clients.length; i++) { + Log.d(TAG, " mac " + clients[i].macAddress); + } + } + + mSoftApListener.onConnectedClientsChanged(Arrays.asList(clients)); } @Override diff --git a/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java b/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java index d7d1868af..a8e4a8acc 100644 --- a/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java +++ b/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java @@ -22,7 +22,20 @@ import static com.android.server.wifi.ActiveModeManager.SCAN_WITH_HIDDEN_NETWORK import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockingDetails; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; import android.content.BroadcastReceiver; import android.content.Context; @@ -30,6 +43,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; import android.location.LocationManager; +import android.net.wifi.WifiClient; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.BatteryStats; @@ -54,6 +68,7 @@ import org.mockito.stubbing.Answer; import java.io.ByteArrayOutputStream; import java.io.PrintWriter; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; @@ -328,7 +343,8 @@ public class ActiveModeWardenTest extends WifiBaseTest { /** * Asserts that the runnable r has shut down wifi properly. - * @param r runnable that will shut down wifi + * + * @param r runnable that will shut down wifi * @param times expected number of times that <code>r</code> shut down wifi */ private void assertWifiShutDown(Runnable r, int times) { @@ -363,7 +379,8 @@ public class ActiveModeWardenTest extends WifiBaseTest { /** * Asserts that the runnable r has entered ECM state properly. - * @param r runnable that will enter ECM + * + * @param r runnable that will enter ECM * @param times expected number of times that <code>r</code> shut down wifi */ private void assertEnteredEcmMode(Runnable r, int times) { @@ -617,7 +634,7 @@ public class ActiveModeWardenTest extends WifiBaseTest { mLooper.dispatchAll(); verify(mSoftApStateMachineCallback, never()).onStateChanged(anyInt(), anyInt()); - verify(mSoftApStateMachineCallback, never()).onNumClientsChanged(anyInt()); + verify(mSoftApStateMachineCallback, never()).onConnectedClientsChanged(any()); } /** @@ -641,13 +658,13 @@ public class ActiveModeWardenTest extends WifiBaseTest { * Verifies that NumClientsChanged event is being passed from SoftApManager to WifiServiceImpl */ @Test - public void callsWifiServiceCallbackOnSoftApNumClientsChanged() throws Exception { - final int testNumClients = 3; + public void callsWifiServiceCallbackOnSoftApConnectedClientsChanged() throws Exception { + final List<WifiClient> testClients = new ArrayList(); enterSoftApActiveMode(); - mSoftApManagerCallback.onNumClientsChanged(testNumClients); + mSoftApManagerCallback.onConnectedClientsChanged(testClients); mLooper.dispatchAll(); - verify(mSoftApStateMachineCallback).onNumClientsChanged(testNumClients); + verify(mSoftApStateMachineCallback).onConnectedClientsChanged(testClients); } /** @@ -655,16 +672,16 @@ public class ActiveModeWardenTest extends WifiBaseTest { * WifiServiceImpl is null. */ @Test - public void testNullCallbackToWifiServiceImplForNumClientsChanged() throws Exception { - final int testNumClients = 3; + public void testNullCallbackToWifiServiceImplForConnectedClientsChanged() throws Exception { + final List<WifiClient> testClients = new ArrayList(); //set the callback to null mActiveModeWarden.registerSoftApCallback(null); enterSoftApActiveMode(); - mSoftApManagerCallback.onNumClientsChanged(testNumClients); + mSoftApManagerCallback.onConnectedClientsChanged(testClients); - verify(mSoftApStateMachineCallback, never()).onNumClientsChanged(anyInt()); + verify(mSoftApStateMachineCallback, never()).onConnectedClientsChanged(any()); } /** diff --git a/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java b/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java index 6f27aeb53..1f5166abb 100644 --- a/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java @@ -33,7 +33,19 @@ import static com.android.server.wifi.LocalOnlyHotspotRequestInfo.HOTSPOT_NO_ERR import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.anyLong; +import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; import android.app.test.TestAlarmManager; import android.content.Context; @@ -42,6 +54,7 @@ import android.content.res.Resources; import android.database.ContentObserver; import android.net.MacAddress; import android.net.Uri; +import android.net.wifi.WifiClient; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.UserHandle; @@ -53,14 +66,18 @@ import androidx.test.filters.SmallTest; import com.android.internal.R; import com.android.internal.util.WakeupMessage; import com.android.server.wifi.wificond.IApInterfaceEventCallback; +import com.android.server.wifi.wificond.NativeWifiClient; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.InOrder; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.MockitoAnnotations; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Locale; @@ -78,6 +95,15 @@ public class SoftApManagerTest extends WifiBaseTest { private static final String OTHER_INTERFACE_NAME = "otherif"; private static final int TEST_NUM_CONNECTED_CLIENTS = 4; private static final MacAddress TEST_MAC_ADDRESS = MacAddress.fromString("22:33:44:55:66:77"); + private static final WifiClient TEST_CONNECTED_CLIENT = new WifiClient(TEST_MAC_ADDRESS); + private static final List<WifiClient> TEST_CONNECTED_CLIENTS = + new ArrayList(Arrays.asList(TEST_CONNECTED_CLIENT)); + private static final NativeWifiClient TEST_NATIVE_CLIENT = new NativeWifiClient() {{ + macAddress = TEST_MAC_ADDRESS.toByteArray(); + } + }; + private static final List<NativeWifiClient> TEST_CONNECTED_NATIVECLIENTS = + new ArrayList(Arrays.asList(TEST_NATIVE_CLIENT)); private final WifiConfiguration mDefaultApConfig = createDefaultApConfig(); @@ -858,17 +884,21 @@ public class SoftApManagerTest extends WifiBaseTest { } @Test - public void updatesNumAssociatedStations() throws Exception { + public void updatesConnectedClients() throws Exception { SoftApModeConfiguration apConfig = new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null); startSoftApAndVerifyEnabled(apConfig); - mSoftApListenerCaptor.getValue().onNumAssociatedStationsChanged( - TEST_NUM_CONNECTED_CLIENTS); + mSoftApListenerCaptor.getValue().onConnectedClientsChanged( + TEST_CONNECTED_NATIVECLIENTS); mLooper.dispatchAll(); - verify(mCallback).onNumClientsChanged(TEST_NUM_CONNECTED_CLIENTS); - verify(mWifiMetrics).addSoftApNumAssociatedStationsChangedEvent(TEST_NUM_CONNECTED_CLIENTS, + verify(mCallback).onConnectedClientsChanged( + Mockito.argThat((List<WifiClient> clients) -> + clients.contains(TEST_CONNECTED_CLIENT)) + ); + verify(mWifiMetrics).addSoftApNumAssociatedStationsChangedEvent( + TEST_CONNECTED_CLIENTS.size(), apConfig.getTargetMode()); } @@ -877,36 +907,41 @@ public class SoftApManagerTest extends WifiBaseTest { * trigger callbacks a second time. */ @Test - public void testDoesNotTriggerCallbackForSameNumberClientUpdate() throws Exception { + public void testDoesNotTriggerCallbackForSameClients() throws Exception { SoftApModeConfiguration apConfig = new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null); startSoftApAndVerifyEnabled(apConfig); - mSoftApListenerCaptor.getValue().onNumAssociatedStationsChanged( - TEST_NUM_CONNECTED_CLIENTS); + mSoftApListenerCaptor.getValue().onConnectedClientsChanged( + TEST_CONNECTED_NATIVECLIENTS); mLooper.dispatchAll(); // now trigger callback again, but we should have each method only called once - mSoftApListenerCaptor.getValue().onNumAssociatedStationsChanged( - TEST_NUM_CONNECTED_CLIENTS); + mSoftApListenerCaptor.getValue().onConnectedClientsChanged( + TEST_CONNECTED_NATIVECLIENTS); mLooper.dispatchAll(); - verify(mCallback).onNumClientsChanged(TEST_NUM_CONNECTED_CLIENTS); - verify(mWifiMetrics).addSoftApNumAssociatedStationsChangedEvent(TEST_NUM_CONNECTED_CLIENTS, + verify(mCallback).onConnectedClientsChanged( + Mockito.argThat((List<WifiClient> clients) -> + clients.contains(TEST_CONNECTED_CLIENT)) + ); + verify(mWifiMetrics) + .addSoftApNumAssociatedStationsChangedEvent( + TEST_CONNECTED_CLIENTS.size(), apConfig.getTargetMode()); } @Test - public void handlesInvalidNumAssociatedStations() throws Exception { + public void handlesInvalidConnectedClients() throws Exception { SoftApModeConfiguration apConfig = new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null); startSoftApAndVerifyEnabled(apConfig); /* Invalid values should be ignored */ - final int mInvalidNumClients = -1; - mSoftApListenerCaptor.getValue().onNumAssociatedStationsChanged(mInvalidNumClients); + final List<NativeWifiClient> mInvalidClients = null; + mSoftApListenerCaptor.getValue().onConnectedClientsChanged(mInvalidClients); mLooper.dispatchAll(); - verify(mCallback, never()).onNumClientsChanged(mInvalidNumClients); + verify(mCallback, never()).onConnectedClientsChanged(null); verify(mWifiMetrics, never()).addSoftApNumAssociatedStationsChangedEvent(anyInt(), anyInt()); } @@ -918,20 +953,23 @@ public class SoftApManagerTest extends WifiBaseTest { new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null); startSoftApAndVerifyEnabled(apConfig); - mSoftApListenerCaptor.getValue().onNumAssociatedStationsChanged( - TEST_NUM_CONNECTED_CLIENTS); + mSoftApListenerCaptor.getValue().onConnectedClientsChanged( + TEST_CONNECTED_NATIVECLIENTS); mLooper.dispatchAll(); - order.verify(mCallback).onNumClientsChanged(TEST_NUM_CONNECTED_CLIENTS); + verify(mCallback).onConnectedClientsChanged( + Mockito.argThat((List<WifiClient> clients) -> + clients.contains(TEST_CONNECTED_CLIENT)) + ); order.verify(mWifiMetrics).addSoftApNumAssociatedStationsChangedEvent( - TEST_NUM_CONNECTED_CLIENTS, apConfig.getTargetMode()); + TEST_CONNECTED_CLIENTS.size(), apConfig.getTargetMode()); // Verify timer is canceled at this point verify(mAlarmManager.getAlarmManager()).cancel(any(WakeupMessage.class)); mSoftApManager.stop(); mLooper.dispatchAll(); - order.verify(mCallback).onNumClientsChanged(0); + order.verify(mCallback).onConnectedClientsChanged(new ArrayList<>()); order.verify(mWifiMetrics).addSoftApNumAssociatedStationsChangedEvent(0, apConfig.getTargetMode()); // Verify timer is canceled after stop softap @@ -966,8 +1004,8 @@ public class SoftApManagerTest extends WifiBaseTest { SoftApModeConfiguration apConfig = new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null); startSoftApAndVerifyEnabled(apConfig); - mSoftApListenerCaptor.getValue().onNumAssociatedStationsChanged( - TEST_NUM_CONNECTED_CLIENTS); + mSoftApListenerCaptor.getValue().onConnectedClientsChanged( + TEST_CONNECTED_NATIVECLIENTS); mLooper.dispatchAll(); // Verify timer is canceled @@ -980,16 +1018,23 @@ public class SoftApManagerTest extends WifiBaseTest { new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null); startSoftApAndVerifyEnabled(apConfig); - mSoftApListenerCaptor.getValue().onNumAssociatedStationsChanged( - TEST_NUM_CONNECTED_CLIENTS); + mSoftApListenerCaptor.getValue().onConnectedClientsChanged( + TEST_CONNECTED_NATIVECLIENTS); mLooper.dispatchAll(); - verify(mCallback).onNumClientsChanged(TEST_NUM_CONNECTED_CLIENTS); + verify(mCallback).onConnectedClientsChanged( + Mockito.argThat((List<WifiClient> clients) -> + clients.contains(TEST_CONNECTED_CLIENT)) + ); // Verify timer is canceled at this point verify(mAlarmManager.getAlarmManager()).cancel(any(WakeupMessage.class)); - mSoftApListenerCaptor.getValue().onNumAssociatedStationsChanged(0); + List<NativeWifiClient> testClients = new ArrayList(); + mSoftApListenerCaptor.getValue().onConnectedClientsChanged(testClients); mLooper.dispatchAll(); - verify(mCallback, times(2)).onNumClientsChanged(0); + verify(mCallback).onConnectedClientsChanged( + Mockito.argThat((List<WifiClient> clients) -> + clients.contains(TEST_CONNECTED_CLIENT)) + ); // Verify timer is scheduled again verify(mAlarmManager.getAlarmManager(), times(2)).setExact(anyInt(), anyLong(), eq(mSoftApManager.SOFT_AP_SEND_MESSAGE_TIMEOUT_TAG), any(), any()); @@ -1065,11 +1110,12 @@ public class SoftApManagerTest extends WifiBaseTest { new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null); startSoftApAndVerifyEnabled(apConfig); // add some clients - mSoftApListenerCaptor.getValue().onNumAssociatedStationsChanged( - TEST_NUM_CONNECTED_CLIENTS); + mSoftApListenerCaptor.getValue().onConnectedClientsChanged( + TEST_CONNECTED_NATIVECLIENTS); mLooper.dispatchAll(); // remove all clients - mSoftApListenerCaptor.getValue().onNumAssociatedStationsChanged(0); + mSoftApListenerCaptor.getValue() + .onConnectedClientsChanged(new ArrayList<NativeWifiClient>()); mLooper.dispatchAll(); // Verify timer is not scheduled verify(mAlarmManager.getAlarmManager(), never()).setExact(anyInt(), anyLong(), @@ -1179,11 +1225,11 @@ public class SoftApManagerTest extends WifiBaseTest { mWifiNativeInterfaceCallbackCaptor.getValue().onUp(TEST_INTERFACE_NAME); mLooper.dispatchAll(); order.verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_ENABLED, 0); - order.verify(mCallback).onNumClientsChanged(0); + order.verify(mCallback).onConnectedClientsChanged(new ArrayList<>()); verify(mSarManager).setSapWifiState(WifiManager.WIFI_AP_STATE_ENABLED); verify(mWifiDiagnostics).startLogging(TEST_INTERFACE_NAME); verify(mContext, times(2)).sendStickyBroadcastAsUser(intentCaptor.capture(), - eq(UserHandle.ALL)); + eq(UserHandle.ALL)); List<Intent> capturedIntents = intentCaptor.getAllValues(); checkApStateChangedBroadcast(capturedIntents.get(0), WIFI_AP_STATE_ENABLING, WIFI_AP_STATE_DISABLED, HOTSPOT_NO_ERROR, TEST_INTERFACE_NAME, @@ -1199,8 +1245,8 @@ public class SoftApManagerTest extends WifiBaseTest { } private void checkApStateChangedBroadcast(Intent intent, int expectedCurrentState, - int expectedPrevState, int expectedErrorCode, - String expectedIfaceName, int expectedMode) { + int expectedPrevState, int expectedErrorCode, + String expectedIfaceName, int expectedMode) { int currentState = intent.getIntExtra(EXTRA_WIFI_AP_STATE, WIFI_AP_STATE_DISABLED); int prevState = intent.getIntExtra(EXTRA_PREVIOUS_WIFI_AP_STATE, WIFI_AP_STATE_DISABLED); int errorCode = intent.getIntExtra(EXTRA_WIFI_AP_FAILURE_REASON, HOTSPOT_NO_ERROR); diff --git a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java index 8c1d3d901..fee95a88e 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java @@ -82,6 +82,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.content.res.Resources; +import android.net.MacAddress; import android.net.NetworkStack; import android.net.Uri; import android.net.wifi.IActionListener; @@ -94,6 +95,7 @@ import android.net.wifi.ISoftApCallback; import android.net.wifi.ITrafficStateCallback; import android.net.wifi.ITxPacketCountListener; import android.net.wifi.ScanResult; +import android.net.wifi.WifiClient; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiConfiguration.KeyMgmt; import android.net.wifi.WifiEnterpriseConfig; @@ -141,6 +143,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; import org.mockito.InOrder; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.Spy; @@ -177,6 +180,7 @@ public class WifiServiceImplTest extends WifiBaseTest { private static final String WIFI_IFACE_NAME2 = "wlan1"; private static final String TEST_COUNTRY_CODE = "US"; private static final String TEST_FACTORY_MAC = "10:22:34:56:78:92"; + private static final MacAddress TEST_FACTORY_MAC_ADDR = MacAddress.fromString(TEST_FACTORY_MAC); private static final String TEST_FQDN = "testfqdn"; private static final List<WifiConfiguration> TEST_WIFI_CONFIGURATION_LIST = Arrays.asList( WifiConfigurationTestUtil.generateWifiConfig( @@ -1749,7 +1753,7 @@ public class WifiServiceImplTest extends WifiBaseTest { mWifiServiceImpl.registerSoftApCallback(mAppBinder, mClientSoftApCallback, 1); mLooper.dispatchAll(); verify(mClientSoftApCallback, never()).onStateChanged(WIFI_AP_STATE_DISABLED, 0); - verify(mClientSoftApCallback, never()).onNumClientsChanged(0); + verify(mClientSoftApCallback, never()).onConnectedClientsChanged(any()); } @@ -1771,7 +1775,7 @@ public class WifiServiceImplTest extends WifiBaseTest { mWifiServiceImpl.registerSoftApCallback(binder, callback, callbackIdentifier); mLooper.dispatchAll(); verify(callback).onStateChanged(WIFI_AP_STATE_DISABLED, 0); - verify(callback).onNumClientsChanged(0); + verify(callback).onConnectedClientsChanged(Mockito.<WifiClient>anyList()); } /** @@ -1789,12 +1793,14 @@ public class WifiServiceImplTest extends WifiBaseTest { verify(mAnotherAppBinder).linkToDeath(any(), anyInt()); verify(mAnotherAppBinder, never()).unlinkToDeath(any(), anyInt()); - final int testNumClients = 4; - mStateMachineSoftApCallback.onNumClientsChanged(testNumClients); + final WifiClient testClient = new WifiClient(TEST_FACTORY_MAC_ADDR); + final List<WifiClient> testClients = new ArrayList(); + testClients.add(testClient); + mStateMachineSoftApCallback.onConnectedClientsChanged(testClients); mLooper.dispatchAll(); // Verify only the second callback is being called - verify(mClientSoftApCallback, never()).onNumClientsChanged(testNumClients); - verify(mAnotherSoftApCallback).onNumClientsChanged(testNumClients); + verify(mClientSoftApCallback, never()).onConnectedClientsChanged(testClients); + verify(mAnotherSoftApCallback).onConnectedClientsChanged(testClients); } /** @@ -1808,10 +1814,12 @@ public class WifiServiceImplTest extends WifiBaseTest { mWifiServiceImpl.unregisterSoftApCallback(callbackIdentifier); mLooper.dispatchAll(); - final int testNumClients = 4; - mStateMachineSoftApCallback.onNumClientsChanged(testNumClients); + final WifiClient testClient = new WifiClient(TEST_FACTORY_MAC_ADDR); + final List<WifiClient> testClients = new ArrayList(); + testClients.add(testClient); + mStateMachineSoftApCallback.onConnectedClientsChanged(testClients); mLooper.dispatchAll(); - verify(mClientSoftApCallback, never()).onNumClientsChanged(testNumClients); + verify(mClientSoftApCallback, never()).onConnectedClientsChanged(testClients); } /** @@ -1827,10 +1835,12 @@ public class WifiServiceImplTest extends WifiBaseTest { mWifiServiceImpl.unregisterSoftApCallback(differentCallbackIdentifier); mLooper.dispatchAll(); - final int testNumClients = 4; - mStateMachineSoftApCallback.onNumClientsChanged(testNumClients); + final WifiClient testClient = new WifiClient(TEST_FACTORY_MAC_ADDR); + final List<WifiClient> testClients = new ArrayList(); + testClients.add(testClient); + mStateMachineSoftApCallback.onConnectedClientsChanged(testClients); mLooper.dispatchAll(); - verify(mClientSoftApCallback).onNumClientsChanged(testNumClients); + verify(mClientSoftApCallback).onConnectedClientsChanged(testClients); } /** @@ -1843,16 +1853,16 @@ public class WifiServiceImplTest extends WifiBaseTest { callbackIdentifier); // Change state from default before registering the second callback - final int testNumClients = 4; + final List<WifiClient> testClients = new ArrayList(); mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0); - mStateMachineSoftApCallback.onNumClientsChanged(testNumClients); + mStateMachineSoftApCallback.onConnectedClientsChanged(testClients); // Register another callback and verify the new state is returned in the immediate callback final int anotherUid = 2; mWifiServiceImpl.registerSoftApCallback(mAppBinder, mAnotherSoftApCallback, anotherUid); mLooper.dispatchAll(); verify(mAnotherSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0); - verify(mAnotherSoftApCallback).onNumClientsChanged(testNumClients); + verify(mAnotherSoftApCallback).onConnectedClientsChanged(testClients); // unregister the fisrt callback mWifiServiceImpl.unregisterSoftApCallback(callbackIdentifier); @@ -1894,24 +1904,28 @@ public class WifiServiceImplTest extends WifiBaseTest { verify(mAppBinder).unlinkToDeath(drCaptor.getValue(), 0); // Verify callback is removed from the list as well - final int testNumClients = 4; - mStateMachineSoftApCallback.onNumClientsChanged(testNumClients); + final WifiClient testClient = new WifiClient(TEST_FACTORY_MAC_ADDR); + final List<WifiClient> testClients = new ArrayList(); + testClients.add(testClient); + mStateMachineSoftApCallback.onConnectedClientsChanged(testClients); mLooper.dispatchAll(); - verify(mClientSoftApCallback, never()).onNumClientsChanged(testNumClients); + verify(mClientSoftApCallback, never()).onConnectedClientsChanged(testClients); } /** * Verify that soft AP callback is called on NumClientsChanged event */ @Test - public void callsRegisteredCallbacksOnNumClientsChangedEvent() throws Exception { + public void callsRegisteredCallbacksOnConnectedClientsChangedEvent() throws Exception { final int callbackIdentifier = 1; registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier); - final int testNumClients = 4; - mStateMachineSoftApCallback.onNumClientsChanged(testNumClients); + final WifiClient testClient = new WifiClient(TEST_FACTORY_MAC_ADDR); + final List<WifiClient> testClients = new ArrayList(); + testClients.add(testClient); + mStateMachineSoftApCallback.onConnectedClientsChanged(testClients); mLooper.dispatchAll(); - verify(mClientSoftApCallback).onNumClientsChanged(testNumClients); + verify(mClientSoftApCallback).onConnectedClientsChanged(testClients); } /** @@ -1932,10 +1946,10 @@ public class WifiServiceImplTest extends WifiBaseTest { * Ap events, even when no callbacks are registered. */ @Test - public void updatesSoftApStateAndNumClientsOnSoftApEvents() throws Exception { - final int testNumClients = 4; + public void updatesSoftApStateAndConnectedClientsOnSoftApEvents() throws Exception { + final List<WifiClient> testClients = new ArrayList(); mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0); - mStateMachineSoftApCallback.onNumClientsChanged(testNumClients); + mStateMachineSoftApCallback.onConnectedClientsChanged(testClients); // Register callback after num clients and soft AP are changed. final int callbackIdentifier = 1; @@ -1943,7 +1957,7 @@ public class WifiServiceImplTest extends WifiBaseTest { callbackIdentifier); mLooper.dispatchAll(); verify(mClientSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0); - verify(mClientSoftApCallback).onNumClientsChanged(testNumClients); + verify(mClientSoftApCallback).onConnectedClientsChanged(testClients); } private class IntentFilterMatcher implements ArgumentMatcher<IntentFilter> { diff --git a/tests/wifitests/src/com/android/server/wifi/WificondControlTest.java b/tests/wifitests/src/com/android/server/wifi/WificondControlTest.java index 456f1f32e..dadab98d6 100644 --- a/tests/wifitests/src/com/android/server/wifi/WificondControlTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WificondControlTest.java @@ -63,6 +63,7 @@ import com.android.server.wifi.wificond.ISendMgmtFrameEvent; import com.android.server.wifi.wificond.IWifiScannerImpl; import com.android.server.wifi.wificond.IWificond; import com.android.server.wifi.wificond.NativeScanResult; +import com.android.server.wifi.wificond.NativeWifiClient; import com.android.server.wifi.wificond.PnoSettings; import com.android.server.wifi.wificond.RadioChainInfo; import com.android.server.wifi.wificond.SingleScanSettings; @@ -922,9 +923,9 @@ public class WificondControlTest extends WifiBaseTest { TEST_INTERFACE_NAME, mSoftApListener)); verify(mApInterface).registerCallback(apInterfaceCallbackCaptor.capture()); - int numStations = 5; - apInterfaceCallbackCaptor.getValue().onNumAssociatedStationsChanged(numStations); - verify(mSoftApListener).onNumAssociatedStationsChanged(eq(numStations)); + final NativeWifiClient[] testClients = new NativeWifiClient[]{}; + apInterfaceCallbackCaptor.getValue().onConnectedClientsChanged(testClients); + verify(mSoftApListener).onConnectedClientsChanged(Arrays.asList(testClients)); int channelFrequency = 2437; int channelBandwidth = IApInterfaceEventCallback.BANDWIDTH_20; |