diff --git a/api/system-current.txt b/api/system-current.txt index 319efa121c078..d3f4ac49ef885 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -5608,11 +5608,19 @@ package android.net.wifi { field public static final int KEY_MGMT_WAPI_PSK = 13; // 0xd } + public final class SoftApCapability implements android.os.Parcelable { + method public int describeContents(); + method public int getMaxSupportedClients(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + } + public final class SoftApConfiguration implements android.os.Parcelable { method public int describeContents(); method public int getBand(); method @Nullable public android.net.MacAddress getBssid(); method public int getChannel(); + method public int getMaxNumberOfClients(); method public int getSecurityType(); method @Nullable public String getSsid(); method @Nullable public String getWpa2Passphrase(); @@ -5635,6 +5643,7 @@ package android.net.wifi { method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBssid(@Nullable android.net.MacAddress); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setChannel(int, int); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setHiddenSsid(boolean); + method @NonNull public android.net.wifi.SoftApConfiguration.Builder setMaxNumberOfClients(int); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setSsid(@Nullable String); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setWpa2Passphrase(@Nullable String); } @@ -5868,6 +5877,7 @@ package android.net.wifi { field public static final int PASSPOINT_ROAMING_NETWORK = 1; // 0x1 field public static final int SAP_START_FAILURE_GENERAL = 0; // 0x0 field public static final int SAP_START_FAILURE_NO_CHANNEL = 1; // 0x1 + field public static final int SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION = 2; // 0x2 field public static final String WIFI_AP_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_AP_STATE_CHANGED"; field public static final int WIFI_AP_STATE_DISABLED = 11; // 0xb field public static final int WIFI_AP_STATE_DISABLING = 10; // 0xa @@ -5906,6 +5916,7 @@ package android.net.wifi { } public static interface WifiManager.SoftApCallback { + method public default void onCapabilityChanged(@NonNull android.net.wifi.SoftApCapability); method public default void onConnectedClientsChanged(@NonNull java.util.List); method public default void onInfoChanged(@NonNull android.net.wifi.SoftApInfo); method public default void onStateChanged(int, int); @@ -8908,6 +8919,11 @@ package android.telephony { field public static final String KEY_SUPPORT_CDMA_1X_VOICE_CALLS_BOOL = "support_cdma_1x_voice_calls_bool"; } + public static final class CarrierConfigManager.Wifi { + field public static final String KEY_HOTSPOT_MAX_CLIENT_COUNT = "wifi.hotspot_maximum_client_count"; + field public static final String KEY_PREFIX = "wifi."; + } + public final class CarrierRestrictionRules implements android.os.Parcelable { method @NonNull public java.util.List areCarrierIdentifiersAllowed(@NonNull java.util.List); method public int describeContents(); diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 71ce125b55a6e..eea08dc6c76bc 100755 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -3932,6 +3932,32 @@ public class CarrierConfigManager { sDefaults.putLong(KEY_DATA_SWITCH_VALIDATION_TIMEOUT_LONG, 2000); sDefaults.putInt(KEY_PARAMETERS_USED_FOR_LTE_SIGNAL_BAR_INT, CellSignalStrengthLte.USE_RSRP | CellSignalStrengthLte.USE_RSSNR); + // Default wifi configurations. + sDefaults.putAll(Wifi.getDefaults()); + } + + /** + * Wi-Fi configs used in WiFi Module. + * + * @hide + */ + @SystemApi + public static final class Wifi { + /** Prefix of all Wifi.KEY_* constants. */ + public static final String KEY_PREFIX = "wifi."; + /** + * It contains the maximum client count definition that the carrier owns. + */ + public static final String KEY_HOTSPOT_MAX_CLIENT_COUNT = + KEY_PREFIX + "hotspot_maximum_client_count"; + + private static PersistableBundle getDefaults() { + PersistableBundle defaults = new PersistableBundle(); + defaults.putInt(KEY_HOTSPOT_MAX_CLIENT_COUNT, 0); + return defaults; + } + + private Wifi() {} } /** diff --git a/wifi/java/android/net/wifi/ISoftApCallback.aidl b/wifi/java/android/net/wifi/ISoftApCallback.aidl index 452a655edc7bb..482b4910921de 100644 --- a/wifi/java/android/net/wifi/ISoftApCallback.aidl +++ b/wifi/java/android/net/wifi/ISoftApCallback.aidl @@ -15,6 +15,7 @@ */ package android.net.wifi; +import android.net.wifi.SoftApCapability; import android.net.wifi.SoftApInfo; import android.net.wifi.WifiClient; @@ -51,4 +52,12 @@ oneway interface ISoftApCallback * @param softApInfo is the softap information. {@link SoftApInfo} */ void onInfoChanged(in SoftApInfo softApInfo); + + + /** + * Service to manager callback providing information of softap. + * + * @param capability is the softap capability. {@link SoftApCapability} + */ + void onCapabilityChanged(in SoftApCapability capability); } diff --git a/wifi/java/android/net/wifi/SoftApCapability.aidl b/wifi/java/android/net/wifi/SoftApCapability.aidl new file mode 100644 index 0000000000000..bf30709f15d1e --- /dev/null +++ b/wifi/java/android/net/wifi/SoftApCapability.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; + +parcelable SoftApCapability; diff --git a/wifi/java/android/net/wifi/SoftApCapability.java b/wifi/java/android/net/wifi/SoftApCapability.java new file mode 100644 index 0000000000000..506f49335bc6c --- /dev/null +++ b/wifi/java/android/net/wifi/SoftApCapability.java @@ -0,0 +1,114 @@ +/* + * 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.Nullable; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Objects; + +/** + * A class representing capability of the SoftAp. + * {@see WifiManager} + * + * @hide + */ +@SystemApi +public final class SoftApCapability implements Parcelable { + + private int mMaximumSupportedClientNumber; + + /** + * Get the maximum supported client numbers which AP resides on. + */ + public int getMaxSupportedClients() { + return mMaximumSupportedClientNumber; + } + + /** + * Set the maximum supported client numbers which AP resides on. + * @hide + */ + public void setMaxSupportedClients(int maxClient) { + mMaximumSupportedClientNumber = maxClient; + } + + /** + * @hide + */ + public SoftApCapability(@Nullable SoftApCapability source) { + if (source != null) { + mMaximumSupportedClientNumber = source.mMaximumSupportedClientNumber; + } + } + + /** + * @hide + */ + public SoftApCapability() { + } + + @Override + /** Implement the Parcelable interface. */ + public int describeContents() { + return 0; + } + + @Override + /** Implement the Parcelable interface */ + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mMaximumSupportedClientNumber); + } + + @NonNull + /** Implement the Parcelable interface */ + public static final Creator CREATOR = new Creator() { + public SoftApCapability createFromParcel(Parcel in) { + SoftApCapability capability = new SoftApCapability(); + capability.mMaximumSupportedClientNumber = in.readInt(); + return capability; + } + + public SoftApCapability[] newArray(int size) { + return new SoftApCapability[size]; + } + }; + + @NonNull + @Override + public String toString() { + StringBuilder sbuf = new StringBuilder(); + sbuf.append("MaximumSupportedClientNumber=").append(mMaximumSupportedClientNumber); + return sbuf.toString(); + } + + @Override + public boolean equals(@NonNull Object o) { + if (this == o) return true; + if (!(o instanceof SoftApCapability)) return false; + SoftApCapability capability = (SoftApCapability) o; + return mMaximumSupportedClientNumber == capability.mMaximumSupportedClientNumber; + } + + @Override + public int hashCode() { + return Objects.hash(mMaximumSupportedClientNumber); + } +} diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java index fd8a924bdbee9..cd2826bb17641 100644 --- a/wifi/java/android/net/wifi/SoftApConfiguration.java +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -163,6 +163,11 @@ public final class SoftApConfiguration implements Parcelable { */ private final int mChannel; + /** + * The maximim allowed number of clients that can associate to the AP. + */ + private final int mMaxNumberOfClients; + /** * The operating security type of the AP. * One of the security types from {@link @SecurityType} @@ -191,7 +196,7 @@ public final class SoftApConfiguration implements Parcelable { /** Private constructor for Builder and Parcelable implementation. */ private SoftApConfiguration(@Nullable String ssid, @Nullable MacAddress bssid, @Nullable String wpa2Passphrase, boolean hiddenSsid, @BandType int band, int channel, - @SecurityType int securityType) { + @SecurityType int securityType, int maxNumberOfClients) { mSsid = ssid; mBssid = bssid; mWpa2Passphrase = wpa2Passphrase; @@ -199,6 +204,7 @@ public final class SoftApConfiguration implements Parcelable { mBand = band; mChannel = channel; mSecurityType = securityType; + mMaxNumberOfClients = maxNumberOfClients; } @Override @@ -216,13 +222,14 @@ public final class SoftApConfiguration implements Parcelable { && mHiddenSsid == other.mHiddenSsid && mBand == other.mBand && mChannel == other.mChannel - && mSecurityType == other.mSecurityType; + && mSecurityType == other.mSecurityType + && mMaxNumberOfClients == other.mMaxNumberOfClients; } @Override public int hashCode() { return Objects.hash(mSsid, mBssid, mWpa2Passphrase, mHiddenSsid, - mBand, mChannel, mSecurityType); + mBand, mChannel, mSecurityType, mMaxNumberOfClients); } @Override @@ -236,6 +243,7 @@ public final class SoftApConfiguration implements Parcelable { sbuf.append(" \n Band =").append(mBand); sbuf.append(" \n Channel =").append(mChannel); sbuf.append(" \n SecurityType=").append(getSecurityType()); + sbuf.append(" \n MaxClient=").append(mMaxNumberOfClients); return sbuf.toString(); } @@ -248,6 +256,7 @@ public final class SoftApConfiguration implements Parcelable { dest.writeInt(mBand); dest.writeInt(mChannel); dest.writeInt(mSecurityType); + dest.writeInt(mMaxNumberOfClients); } @Override @@ -262,7 +271,8 @@ public final class SoftApConfiguration implements Parcelable { return new SoftApConfiguration( in.readString(), in.readParcelable(MacAddress.class.getClassLoader()), - in.readString(), in.readBoolean(), in.readInt(), in.readInt(), in.readInt()); + in.readString(), in.readBoolean(), in.readInt(), in.readInt(), in.readInt(), + in.readInt()); } @Override @@ -282,7 +292,7 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns MAC address set to be BSSID for the AP. - * {@link #setBssid(MacAddress)}. + * {@link Builder#setBssid(MacAddress)}. */ @Nullable public MacAddress getBssid() { @@ -291,7 +301,7 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns String set to be passphrase for the WPA2-PSK AP. - * {@link #setWpa2Passphrase(String)}. + * {@link Builder#setWpa2Passphrase(String)}. */ @Nullable public String getWpa2Passphrase() { @@ -301,7 +311,7 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns Boolean set to be indicate hidden (true: doesn't broadcast its SSID) or * not (false: broadcasts its SSID) for the AP. - * {@link #setHiddenSsid(boolean)}. + * {@link Builder#setHiddenSsid(boolean)}. */ public boolean isHiddenSsid() { return mHiddenSsid; @@ -309,7 +319,7 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns {@link BandType} set to be the band for the AP. - * {@link #setBand(@BandType int)}. + * {@link Builder#setBand(@BandType int)}. */ public @BandType int getBand() { return mBand; @@ -317,7 +327,7 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns Integer set to be the channel for the AP. - * {@link #setChannel(int)}. + * {@link Builder#setChannel(int)}. */ public int getChannel() { return mChannel; @@ -332,6 +342,14 @@ public final class SoftApConfiguration implements Parcelable { return mSecurityType; } + /** + * Returns the maximum number of clients that can associate to the AP. + * {@link Builder#setMaxNumberOfClients(int)}. + */ + public int getMaxNumberOfClients() { + return mMaxNumberOfClients; + } + /** * Builds a {@link SoftApConfiguration}, which allows an app to configure various aspects of a * Soft AP. @@ -346,6 +364,7 @@ public final class SoftApConfiguration implements Parcelable { private boolean mHiddenSsid; private int mBand; private int mChannel; + private int mMaxNumberOfClients; private int setSecurityType() { int securityType = SECURITY_TYPE_OPEN; @@ -369,6 +388,7 @@ public final class SoftApConfiguration implements Parcelable { mHiddenSsid = false; mBand = BAND_2GHZ; mChannel = 0; + mMaxNumberOfClients = 0; } /** @@ -383,6 +403,7 @@ public final class SoftApConfiguration implements Parcelable { mHiddenSsid = other.mHiddenSsid; mBand = other.mBand; mChannel = other.mChannel; + mMaxNumberOfClients = other.mMaxNumberOfClients; } /** @@ -393,7 +414,7 @@ public final class SoftApConfiguration implements Parcelable { @NonNull public SoftApConfiguration build() { return new SoftApConfiguration(mSsid, mBssid, mWpa2Passphrase, - mHiddenSsid, mBand, mChannel, setSecurityType()); + mHiddenSsid, mBand, mChannel, setSecurityType(), mMaxNumberOfClients); } /** @@ -523,5 +544,37 @@ public final class SoftApConfiguration implements Parcelable { mChannel = channel; return this; } + + /** + * Specifies the maximum number of clients that can associate to the AP. + * + * The maximum number of clients (STAs) which can associate to the AP. + * The AP will reject association from any clients above this number. + * Specify a value of 0 to have the framework automatically use the maximum number + * which the device can support (based on hardware and carrier constraints). + *

+ * Use {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)} and + * {@link SoftApCapability#getMaxSupportedClients} to get the maximum number of clients + * which the device supports (based on hardware and carrier constraints). + * + *

+ *

  • If not set, defaults to 0.
  • + * + * This method requires hardware support. If the method is used to set a + * non-zero {@code maxNumberOfClients} value then + * {@link WifiManager#startTetheredHotspot} will report error code + * {@link WifiManager#SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}. + * + * @param maxNumberOfClients maximum client number of the AP. + * @return Builder for chaining. + */ + @NonNull + public Builder setMaxNumberOfClients(int maxNumberOfClients) { + if (maxNumberOfClients < 0) { + throw new IllegalArgumentException("maxNumberOfClients should be not negative"); + } + mMaxNumberOfClients = maxNumberOfClients; + return this; + } } } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 5ab05834cd780..7693f9a1a79ab 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -549,6 +549,7 @@ public class WifiManager { * currently support general and no_channel * @see #SAP_START_FAILURE_GENERAL * @see #SAP_START_FAILURE_NO_CHANNEL + * @see #SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION * * @hide */ @@ -652,6 +653,7 @@ public class WifiManager { @IntDef(flag = false, prefix = { "SAP_START_FAILURE_" }, value = { SAP_START_FAILURE_GENERAL, SAP_START_FAILURE_NO_CHANNEL, + SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION, }) @Retention(RetentionPolicy.SOURCE) public @interface SapStartFailure {} @@ -673,6 +675,15 @@ public class WifiManager { @SystemApi public static final int SAP_START_FAILURE_NO_CHANNEL = 1; + /** + * If Wi-Fi AP start failed, this reason code means that the specified configuration + * is not supported by the current HAL version. + * + * @hide + */ + @SystemApi + public static final int SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION = 2; + /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"IFACE_IP_MODE_"}, value = { @@ -3431,6 +3442,16 @@ public class WifiManager { default void onInfoChanged(@NonNull SoftApInfo softApInfo) { // Do nothing: can be updated to add SoftApInfo details (e.g. channel) to the UI. } + + /** + * Called when capability of softap changes. + * + * @param softApCapability is the softap capability. {@link SoftApCapability} + */ + default void onCapabilityChanged(@NonNull SoftApCapability softApCapability) { + // Do nothing: can be updated to add SoftApCapability details (e.g. meximum supported + // client number) to the UI. + } } /** @@ -3484,6 +3505,19 @@ public class WifiManager { mCallback.onInfoChanged(softApInfo); }); } + + @Override + public void onCapabilityChanged(SoftApCapability capability) { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "SoftApCallbackProxy: onCapabilityChanged: SoftApCapability=" + + capability); + } + + Binder.clearCallingIdentity(); + mExecutor.execute(() -> { + mCallback.onCapabilityChanged(capability); + }); + } } /** diff --git a/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java b/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java new file mode 100644 index 0000000000000..9cb221d81070c --- /dev/null +++ b/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java @@ -0,0 +1,69 @@ +/* + * 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.os.Parcel; + +import static org.junit.Assert.assertEquals; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + +/** + * Unit tests for {@link android.net.wifi.SoftApCapability}. + */ +@SmallTest +public class SoftApCapabilityTest { + + /** + * Verifies copy constructor. + */ + @Test + public void testCopyOperator() throws Exception { + SoftApCapability capability = new SoftApCapability(); + capability.setMaxSupportedClients(10); + + SoftApCapability copiedCapability = new SoftApCapability(capability); + + assertEquals(capability, copiedCapability); + assertEquals(capability.hashCode(), copiedCapability.hashCode()); + } + + /** + * Verifies parcel serialization/deserialization. + */ + @Test + public void testParcelOperation() throws Exception { + SoftApCapability capability = new SoftApCapability(); + capability.setMaxSupportedClients(10); + + Parcel parcelW = Parcel.obtain(); + capability.writeToParcel(parcelW, 0); + byte[] bytes = parcelW.marshall(); + parcelW.recycle(); + + Parcel parcelR = Parcel.obtain(); + parcelR.unmarshall(bytes, 0, bytes.length); + parcelR.setDataPosition(0); + SoftApCapability fromParcel = SoftApCapability.CREATOR.createFromParcel(parcelR); + + assertEquals(capability, fromParcel); + assertEquals(capability.hashCode(), fromParcel.hashCode()); + } + +} diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java index 60125e372cd5e..1f601036a718c 100644 --- a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java @@ -50,6 +50,7 @@ public class SoftApConfigurationTest { assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ); assertThat(original.getChannel()).isEqualTo(0); assertThat(original.isHiddenSsid()).isEqualTo(false); + assertThat(original.getMaxNumberOfClients()).isEqualTo(0); SoftApConfiguration unparceled = parcelUnparcel(original); assertThat(unparceled).isNotSameAs(original); @@ -73,7 +74,7 @@ public class SoftApConfigurationTest { assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ); assertThat(original.getChannel()).isEqualTo(0); assertThat(original.isHiddenSsid()).isEqualTo(false); - + assertThat(original.getMaxNumberOfClients()).isEqualTo(0); SoftApConfiguration unparceled = parcelUnparcel(original); assertThat(unparceled).isNotSameAs(original); @@ -87,12 +88,13 @@ public class SoftApConfigurationTest { } @Test - public void testWpa2WithBandAndChannelAndHiddenNetwork() { + public void testWpa2WithAllFieldCustomized() { SoftApConfiguration original = new SoftApConfiguration.Builder() .setWpa2Passphrase("secretsecret") .setBand(SoftApConfiguration.BAND_ANY) .setChannel(149, SoftApConfiguration.BAND_5GHZ) .setHiddenSsid(true) + .setMaxNumberOfClients(10) .build(); assertThat(original.getWpa2Passphrase()).isEqualTo("secretsecret"); assertThat(original.getSecurityType()).isEqualTo( @@ -100,7 +102,7 @@ public class SoftApConfigurationTest { assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ); assertThat(original.getChannel()).isEqualTo(149); assertThat(original.isHiddenSsid()).isEqualTo(true); - + assertThat(original.getMaxNumberOfClients()).isEqualTo(10); SoftApConfiguration unparceled = parcelUnparcel(original); assertThat(unparceled).isNotSameAs(original); diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 821661196f4fe..d8bc1347c3328 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -877,6 +877,25 @@ public class WifiManagerTest { verify(mSoftApCallback).onInfoChanged(testSoftApInfo); } + + /* + * Verify client-provided callback is being called through callback proxy + */ + @Test + public void softApCallbackProxyCallsOnCapabilityChanged() throws Exception { + SoftApCapability testSoftApCapability = new SoftApCapability(); + testSoftApCapability.setMaxSupportedClients(10); + ArgumentCaptor callbackCaptor = + ArgumentCaptor.forClass(ISoftApCallback.Stub.class); + mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); + verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), + anyInt()); + + callbackCaptor.getValue().onCapabilityChanged(testSoftApCapability); + mLooper.dispatchAll(); + verify(mSoftApCallback).onCapabilityChanged(testSoftApCapability); + } + /* * Verify client-provided callback is being called through callback proxy on multiple events */ @@ -885,6 +904,8 @@ public class WifiManagerTest { SoftApInfo testSoftApInfo = new SoftApInfo(); testSoftApInfo.setFrequency(TEST_AP_FREQUENCY); testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH); + SoftApCapability testSoftApCapability = new SoftApCapability(); + testSoftApCapability.setMaxSupportedClients(10); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); @@ -896,12 +917,15 @@ public class WifiManagerTest { callbackCaptor.getValue().onConnectedClientsChanged(testClients); callbackCaptor.getValue().onInfoChanged(testSoftApInfo); callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL); + callbackCaptor.getValue().onCapabilityChanged(testSoftApCapability); + mLooper.dispatchAll(); verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLING, 0); verify(mSoftApCallback).onConnectedClientsChanged(testClients); verify(mSoftApCallback).onInfoChanged(testSoftApInfo); verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL); + verify(mSoftApCallback).onCapabilityChanged(testSoftApCapability); } /*