diff options
10 files changed, 245 insertions, 53 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index 9dcacafd6569..dff1f05e32ff 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -4733,6 +4733,13 @@ package android.net.wifi { field @Deprecated public byte id; } + public final class WifiClient implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public android.net.MacAddress getMacAddress(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiClient> CREATOR; + } + @Deprecated public class WifiConfiguration implements android.os.Parcelable { method @Deprecated public boolean hasNoInternetAccess(); method @Deprecated public boolean isEphemeral(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java index 8f201c793258..a3a9322395c0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java @@ -19,6 +19,7 @@ package com.android.systemui.statusbar.policy; import android.app.ActivityManager; import android.content.Context; import android.net.ConnectivityManager; +import android.net.wifi.WifiClient; import android.net.wifi.WifiManager; import android.os.Handler; import android.os.UserManager; @@ -29,11 +30,13 @@ import com.android.systemui.dagger.qualifiers.MainHandler; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.List; import javax.inject.Inject; import javax.inject.Singleton; /** + * Controller used to retrieve information related to a hotspot. */ @Singleton public class HotspotControllerImpl implements HotspotController, WifiManager.SoftApCallback { @@ -48,11 +51,12 @@ public class HotspotControllerImpl implements HotspotController, WifiManager.Sof private final Context mContext; private int mHotspotState; - private int mNumConnectedDevices; + private volatile int mNumConnectedDevices; private boolean mWaitingForTerminalState; private boolean mListening; /** + * Controller used to retrieve information related to a hotspot. */ @Inject public HotspotControllerImpl(Context context, @MainHandler Handler mainHandler) { @@ -96,7 +100,6 @@ public class HotspotControllerImpl implements HotspotController, WifiManager.Sof /** * Adds {@code callback} to the controller. The controller will update the callback on state * changes. It will immediately trigger the callback added to notify current state. - * @param callback */ @Override public void addCallback(Callback callback) { @@ -110,8 +113,8 @@ public class HotspotControllerImpl implements HotspotController, WifiManager.Sof mWifiManager.registerSoftApCallback(this, mMainHandler); } else { // mWifiManager#registerSoftApCallback triggers a call to - // onNumClientsChanged on the Main Handler. In order to always update the - // callback on added, we make this call when adding callbacks after the + // onConnectedClientsChanged on the Main Handler. In order to always update + // the callback on added, we make this call when adding callbacks after the // first. mMainHandler.post(() -> callback.onHotspotChanged(isHotspotEnabled(), @@ -232,8 +235,8 @@ public class HotspotControllerImpl implements HotspotController, WifiManager.Sof } @Override - public void onNumClientsChanged(int numConnectedDevices) { - mNumConnectedDevices = numConnectedDevices; + public void onConnectedClientsChanged(List<WifiClient> clients) { + mNumConnectedDevices = clients.size(); fireHotspotChangedCallback(); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java index 556ed5c30496..4ccf8a4a4990 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java @@ -42,6 +42,8 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; +import java.util.ArrayList; + @SmallTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @@ -67,7 +69,8 @@ public class HotspotControllerImplTest extends SysuiTestCase { mContext.addMockSystemService(WifiManager.class, mWifiManager); doAnswer((InvocationOnMock invocation) -> { - ((WifiManager.SoftApCallback) invocation.getArgument(0)).onNumClientsChanged(1); + ((WifiManager.SoftApCallback) invocation.getArgument(0)) + .onConnectedClientsChanged(new ArrayList<>()); return null; }).when(mWifiManager).registerSoftApCallback(any(WifiManager.SoftApCallback.class), any(Handler.class)); diff --git a/wifi/java/android/net/wifi/ISoftApCallback.aidl b/wifi/java/android/net/wifi/ISoftApCallback.aidl index b8d2971e74bb..8a252dd1e447 100644 --- a/wifi/java/android/net/wifi/ISoftApCallback.aidl +++ b/wifi/java/android/net/wifi/ISoftApCallback.aidl @@ -16,6 +16,8 @@ package android.net.wifi; +import android.net.wifi.WifiClient; + /** * Interface for Soft AP callback. * @@ -36,9 +38,9 @@ oneway interface ISoftApCallback void onStateChanged(int state, int failureReason); /** - * Service to manager callback providing number of connected clients. + * Service to manager callback providing connected client's information. * - * @param numClients number of connected clients + * @param clients the currently connected clients */ - void onNumClientsChanged(int numClients); + void onConnectedClientsChanged(in List<WifiClient> clients); } diff --git a/wifi/java/android/net/wifi/WifiClient.aidl b/wifi/java/android/net/wifi/WifiClient.aidl new file mode 100644 index 000000000000..accdaddfc848 --- /dev/null +++ b/wifi/java/android/net/wifi/WifiClient.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi; + +@JavaOnlyStableParcelable parcelable WifiClient;
\ No newline at end of file diff --git a/wifi/java/android/net/wifi/WifiClient.java b/wifi/java/android/net/wifi/WifiClient.java new file mode 100644 index 000000000000..3e09580802ce --- /dev/null +++ b/wifi/java/android/net/wifi/WifiClient.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi; + +import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.net.MacAddress; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.internal.util.Preconditions; + +import java.util.Objects; + +/** @hide */ +@SystemApi +public final class WifiClient implements Parcelable { + + private final MacAddress mMacAddress; + + /** + * The mac address of this client. + */ + @NonNull + public MacAddress getMacAddress() { + return mMacAddress; + } + + private WifiClient(Parcel in) { + mMacAddress = in.readParcelable(null); + } + + /** @hide */ + public WifiClient(@NonNull MacAddress macAddress) { + Preconditions.checkNotNull(macAddress, "mMacAddress must not be null."); + + this.mMacAddress = macAddress; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeParcelable(mMacAddress, flags); + } + + @NonNull + public static final Creator<WifiClient> CREATOR = new Creator<WifiClient>() { + public WifiClient createFromParcel(Parcel in) { + return new WifiClient(in); + } + + public WifiClient[] newArray(int size) { + return new WifiClient[size]; + } + }; + + @NonNull + @Override + public String toString() { + return "WifiClient{" + + "mMacAddress=" + mMacAddress + + '}'; + } + + @Override + public boolean equals(@NonNull Object o) { + if (this == o) return true; + if (!(o instanceof WifiClient)) return false; + WifiClient client = (WifiClient) o; + return mMacAddress.equals(client.mMacAddress); + } + + @Override + public int hashCode() { + return Objects.hash(mMacAddress); + } +} + + diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index f626b0c46fa9..3b7690b1e8fa 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -3254,21 +3254,22 @@ public class WifiManager { /** * Called when soft AP state changes. * - * @param state new new AP state. One of {@link #WIFI_AP_STATE_DISABLED}, - * {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED}, - * {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED} + * @param state new new AP state. One of {@link #WIFI_AP_STATE_DISABLED}, + * {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED}, + * {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED} * @param failureReason reason when in failed state. One of - * {@link #SAP_START_FAILURE_GENERAL}, {@link #SAP_START_FAILURE_NO_CHANNEL} + * {@link #SAP_START_FAILURE_GENERAL}, + * {@link #SAP_START_FAILURE_NO_CHANNEL} */ - public abstract void onStateChanged(@WifiApState int state, + void onStateChanged(@WifiApState int state, @SapStartFailure int failureReason); /** - * 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 + * @param clients the currently connected clients */ - public abstract void onNumClientsChanged(int numClients); + void onConnectedClientsChanged(@NonNull List<WifiClient> clients); } /** @@ -3291,18 +3292,21 @@ public class WifiManager { Log.v(TAG, "SoftApCallbackProxy: onStateChanged: state=" + state + ", failureReason=" + failureReason); } + mHandler.post(() -> { mCallback.onStateChanged(state, failureReason); }); } @Override - public void onNumClientsChanged(int numClients) { + public void onConnectedClientsChanged(List<WifiClient> clients) { if (mVerboseLoggingEnabled) { - Log.v(TAG, "SoftApCallbackProxy: onNumClientsChanged: numClients=" + numClients); + Log.v(TAG, "SoftApCallbackProxy: onConnectedClientsChanged: clients=" + + clients.size() + " clients"); } + mHandler.post(() -> { - mCallback.onNumClientsChanged(numClients); + mCallback.onConnectedClientsChanged(clients); }); } } diff --git a/wifi/tests/Android.mk b/wifi/tests/Android.mk index 401b652289cd..3453d6ec827f 100644 --- a/wifi/tests/Android.mk +++ b/wifi/tests/Android.mk @@ -49,6 +49,7 @@ LOCAL_STATIC_JAVA_LIBRARIES := \ core-test-rules \ guava \ mockito-target-minus-junit4 \ + net-tests-utils \ frameworks-base-testutils \ truth-prebuilt \ diff --git a/wifi/tests/src/android/net/wifi/WifiClientTest.java b/wifi/tests/src/android/net/wifi/WifiClientTest.java new file mode 100644 index 000000000000..42cab55305b9 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/WifiClientTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi; + +import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals; +import static com.android.testutils.ParcelUtilsKt.assertParcelSane; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +import android.net.MacAddress; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + +/** + * Unit tests for {@link android.net.wifi.WifiClient}. + */ +@SmallTest +public class WifiClientTest { + private static final String INTERFACE_NAME = "wlan0"; + private static final String MAC_ADDRESS_STRING = "00:0a:95:9d:68:16"; + private static final MacAddress MAC_ADDRESS = MacAddress.fromString(MAC_ADDRESS_STRING); + + /** + * Verify parcel write/read with WifiClient. + */ + @Test + public void testWifiClientParcelWriteRead() throws Exception { + WifiClient writeWifiClient = new WifiClient(MAC_ADDRESS); + + assertParcelSane(writeWifiClient, 1); + } + + /** + * Verify equals with WifiClient. + */ + @Test + public void testWifiClientEquals() throws Exception { + WifiClient writeWifiClient = new WifiClient(MAC_ADDRESS); + WifiClient writeWifiClientEquals = new WifiClient(MAC_ADDRESS); + + assertEquals(writeWifiClient, writeWifiClientEquals); + assertEquals(writeWifiClient.hashCode(), writeWifiClientEquals.hashCode()); + assertFieldCountEquals(1, WifiClient.class); + } + + /** + * Verify not-equals with WifiClient. + */ + @Test + public void testWifiClientNotEquals() throws Exception { + final MacAddress macAddressNotEquals = MacAddress.fromString("00:00:00:00:00:00"); + WifiClient writeWifiClient = new WifiClient(MAC_ADDRESS); + WifiClient writeWifiClientNotEquals = new WifiClient(macAddressNotEquals); + + assertNotEquals(writeWifiClient, writeWifiClientNotEquals); + assertNotEquals(writeWifiClient.hashCode(), writeWifiClientNotEquals.hashCode()); + } +} diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 881dcbb80492..8d0579bde92c 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -99,8 +99,7 @@ public class WifiManagerTest { private static final String[] TEST_MAC_ADDRESSES = {"da:a1:19:0:0:0"}; @Mock Context mContext; - @Mock - android.net.wifi.IWifiManager mWifiService; + @Mock android.net.wifi.IWifiManager mWifiService; @Mock ApplicationInfo mApplicationInfo; @Mock WifiConfiguration mApConfig; @Mock SoftApCallback mSoftApCallback; @@ -115,7 +114,8 @@ public class WifiManagerTest { private TestLooper mLooper; private WifiManager mWifiManager; - @Before public void setUp() throws Exception { + @Before + public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mLooper = new TestLooper(); mHandler = spy(new Handler(mLooper.getLooper())); @@ -210,7 +210,7 @@ public class WifiManagerTest { @Test public void testCreationOfLocalOnlyHotspotSubscription() throws Exception { try (WifiManager.LocalOnlyHotspotSubscription sub = - mWifiManager.new LocalOnlyHotspotSubscription()) { + mWifiManager.new LocalOnlyHotspotSubscription()) { sub.close(); } } @@ -752,17 +752,17 @@ public class WifiManagerTest { * Verify client-provided callback is being called through callback proxy */ @Test - public void softApCallbackProxyCallsOnNumClientsChanged() throws Exception { + public void softApCallbackProxyCallsOnConnectedClientsChanged() throws Exception { ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler); verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), anyInt()); - final int testNumClients = 3; - callbackCaptor.getValue().onNumClientsChanged(testNumClients); + final List<WifiClient> testClients = new ArrayList(); + callbackCaptor.getValue().onConnectedClientsChanged(testClients); mLooper.dispatchAll(); - verify(mSoftApCallback).onNumClientsChanged(testNumClients); + verify(mSoftApCallback).onConnectedClientsChanged(testClients); } /* @@ -776,14 +776,14 @@ public class WifiManagerTest { verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), anyInt()); - final int testNumClients = 5; + final List<WifiClient> testClients = new ArrayList(); callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLING, 0); - callbackCaptor.getValue().onNumClientsChanged(testNumClients); + callbackCaptor.getValue().onConnectedClientsChanged(testClients); callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL); mLooper.dispatchAll(); verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLING, 0); - verify(mSoftApCallback).onNumClientsChanged(testNumClients); + verify(mSoftApCallback).onConnectedClientsChanged(testClients); verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL); } @@ -1020,8 +1020,8 @@ public class WifiManagerTest { verifyNoMoreInteractions(mWifiService); } - /** -i * Verify that a call to cancel WPS immediately returns a failure. + /** + * Verify that a call to cancel WPS immediately returns a failure. */ @Test public void testCancelWpsImmediatelyFailsWithCallback() { @@ -1324,7 +1324,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Verify getting the factory MAC address. - * @throws Exception */ @Test public void testGetFactoryMacAddress() throws Exception { @@ -1371,7 +1370,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of isEnhancedOpenSupported - * @throws Exception */ @Test public void testIsEnhancedOpenSupported() throws Exception { @@ -1385,7 +1383,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of isWpa3SaeSupported - * @throws Exception */ @Test public void testIsWpa3SaeSupported() throws Exception { @@ -1399,7 +1396,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of isWpa3SuiteBSupported - * @throws Exception */ @Test public void testIsWpa3SuiteBSupported() throws Exception { @@ -1413,7 +1409,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of isEasyConnectSupported - * @throws Exception */ @Test public void testIsEasyConnectSupported() throws Exception { @@ -1427,7 +1422,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#addNetwork(WifiConfiguration)} - * @throws Exception */ @Test public void testAddNetwork() throws Exception { @@ -1444,7 +1438,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#addNetwork(WifiConfiguration)} - * @throws Exception */ @Test public void testUpdateNetwork() throws Exception { @@ -1466,7 +1459,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#enableNetwork(int, boolean)} - * @throws Exception */ @Test public void testEnableNetwork() throws Exception { @@ -1478,7 +1470,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#disableNetwork(int)} - * @throws Exception */ @Test public void testDisableNetwork() throws Exception { @@ -1500,7 +1491,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#disconnect()} - * @throws Exception */ @Test public void testDisconnect() throws Exception { @@ -1511,7 +1501,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#reconnect()} - * @throws Exception */ @Test public void testReconnect() throws Exception { @@ -1522,7 +1511,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#reassociate()} - * @throws Exception */ @Test public void testReassociate() throws Exception { @@ -1533,7 +1521,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#getSupportedFeatures()} - * @throws Exception */ @Test public void testGetSupportedFeatures() throws Exception { @@ -1560,7 +1547,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#getControllerActivityEnergyInfo()} - * @throws Exception */ @Test public void testGetControllerActivityEnergyInfo() throws Exception { @@ -1573,7 +1559,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#getConnectionInfo()} - * @throws Exception */ @Test public void testGetConnectionInfo() throws Exception { @@ -1585,7 +1570,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#isDualModeSupported()} ()} - * @throws Exception */ @Test public void testIsDualModeSupported() throws Exception { @@ -1596,7 +1580,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#isDualBandSupported()} - * @throws Exception */ @Test public void testIsDualBandSupported() throws Exception { @@ -1607,7 +1590,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#getDhcpInfo()} - * @throws Exception */ @Test public void testGetDhcpInfo() throws Exception { @@ -1620,7 +1602,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#setWifiEnabled(boolean)} - * @throws Exception */ @Test public void testSetWifiEnabled() throws Exception { |