diff --git a/api/system-current.txt b/api/system-current.txt index d3f4ac49ef885..c34f32086fb97 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -5611,8 +5611,11 @@ package android.net.wifi { public final class SoftApCapability implements android.os.Parcelable { method public int describeContents(); method public int getMaxSupportedClients(); + method public boolean isFeatureSupported(int); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator CREATOR; + field public static final int SOFTAP_FEATURE_ACS_OFFLOAD = 1; // 0x1 + field public static final int SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT = 2; // 0x2 } public final class SoftApConfiguration implements android.os.Parcelable { diff --git a/wifi/java/android/net/wifi/SoftApCapability.java b/wifi/java/android/net/wifi/SoftApCapability.java index 506f49335bc6c..c4474e2bc9cc1 100644 --- a/wifi/java/android/net/wifi/SoftApCapability.java +++ b/wifi/java/android/net/wifi/SoftApCapability.java @@ -16,12 +16,15 @@ package android.net.wifi; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.Objects; /** @@ -33,6 +36,41 @@ import java.util.Objects; @SystemApi public final class SoftApCapability implements Parcelable { + /** + * Support for automatic channel selection in driver (ACS). + * Driver will auto select best channel based on interference to optimize performance. + * + * flag when {@link R.bool.config_wifi_softap_acs_supported)} is true. + * + *

+ * Use {@link WifiManager.SoftApCallback#onInfoChanged(SoftApInfo)} and + * {@link SoftApInfo#getFrequency} and {@link SoftApInfo#getBandwidth} to get + * driver channel selection result. + */ + public static final int SOFTAP_FEATURE_ACS_OFFLOAD = 1 << 0; + + /** + * Support for client force disconnect. + * flag when {@link R.bool.config_wifi_sofap_client_force_disconnect_supported)} is true + * + *

+ * Several Soft AP client control features, e.g. specifying the maximum number of + * Soft AP clients, only work when this feature support is present. + * Check feature support before invoking + * {@link SoftApConfiguration.Builder#setMaxNumberOfClients(int)} + */ + public static final int SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT = 1 << 1; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(flag = true, prefix = { "SOFTAP_FEATURE_" }, value = { + SOFTAP_FEATURE_ACS_OFFLOAD, + SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT, + }) + public @interface HotspotFeatures {} + + private @HotspotFeatures int mSupportedFeatures = 0; + private int mMaximumSupportedClientNumber; /** @@ -44,6 +82,8 @@ public final class SoftApCapability implements Parcelable { /** * Set the maximum supported client numbers which AP resides on. + * + * @param maxClient maximum supported client numbers for the softap. * @hide */ public void setMaxSupportedClients(int maxClient) { @@ -51,18 +91,33 @@ public final class SoftApCapability implements Parcelable { } /** - * @hide + * Returns true when feature supported, otherwise false. + * + * @param feature one of feature from {@link HotspotFeatures} */ - public SoftApCapability(@Nullable SoftApCapability source) { - if (source != null) { - mMaximumSupportedClientNumber = source.mMaximumSupportedClientNumber; - } + public boolean isFeatureSupported(@HotspotFeatures int feature) { + return (mSupportedFeatures & feature) == feature; } /** * @hide */ - public SoftApCapability() { + public SoftApCapability(@Nullable SoftApCapability source) { + if (source != null) { + mSupportedFeatures = source.mSupportedFeatures; + mMaximumSupportedClientNumber = source.mMaximumSupportedClientNumber; + } + } + + /** + * Constructor with combination of the feature. + * Zero to no supported feature. + * + * @param features One or combination of the feature from {@link @HotspotFeatures}. + * @hide + */ + public SoftApCapability(@HotspotFeatures int features) { + mSupportedFeatures = features; } @Override @@ -74,6 +129,7 @@ public final class SoftApCapability implements Parcelable { @Override /** Implement the Parcelable interface */ public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mSupportedFeatures); dest.writeInt(mMaximumSupportedClientNumber); } @@ -81,7 +137,8 @@ public final class SoftApCapability implements Parcelable { /** Implement the Parcelable interface */ public static final Creator CREATOR = new Creator() { public SoftApCapability createFromParcel(Parcel in) { - SoftApCapability capability = new SoftApCapability(); + int supportedFeatures = in.readInt(); + SoftApCapability capability = new SoftApCapability(supportedFeatures); capability.mMaximumSupportedClientNumber = in.readInt(); return capability; } @@ -95,6 +152,7 @@ public final class SoftApCapability implements Parcelable { @Override public String toString() { StringBuilder sbuf = new StringBuilder(); + sbuf.append("SupportedFeatures=").append(mSupportedFeatures); sbuf.append("MaximumSupportedClientNumber=").append(mMaximumSupportedClientNumber); return sbuf.toString(); } @@ -104,11 +162,12 @@ public final class SoftApCapability implements Parcelable { if (this == o) return true; if (!(o instanceof SoftApCapability)) return false; SoftApCapability capability = (SoftApCapability) o; - return mMaximumSupportedClientNumber == capability.mMaximumSupportedClientNumber; + return mSupportedFeatures == capability.mSupportedFeatures + && mMaximumSupportedClientNumber == capability.mMaximumSupportedClientNumber; } @Override public int hashCode() { - return Objects.hash(mMaximumSupportedClientNumber); + return Objects.hash(mSupportedFeatures, mMaximumSupportedClientNumber); } } diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java index cd2826bb17641..05e245b8eabc0 100644 --- a/wifi/java/android/net/wifi/SoftApConfiguration.java +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -523,9 +523,16 @@ public final class SoftApConfiguration implements Parcelable { * Specifies the channel and associated band for the AP. * * The channel which AP resides on. Valid channels are country dependent. + *

* The default for the channel is a the special value 0 to have the framework * auto-select a valid channel from the band configured with * {@link #setBand(@BandType int)}. + * + * The channel auto selection will offload to driver when + * {@link SoftApCapability#isFeatureSupported(SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD)} + * return true. Driver will auto select best channel which based on environment + * interference to get best performance. Check {@link SoftApCapability} to get more detail. + * * Note, since 6GHz band use the same channel numbering of 2.4GHz and 5GHZ bands, * the caller needs to pass the band containing the selected channel. * @@ -565,6 +572,12 @@ public final class SoftApConfiguration implements Parcelable { * {@link WifiManager#startTetheredHotspot} will report error code * {@link WifiManager#SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}. * + *

+ * Use {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)} and + * {@link SoftApCapability#isFeatureSupported(int)} + * with {@link SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT} to determine whether + * or not this feature is supported. + * * @param maxNumberOfClients maximum client number of the AP. * @return Builder for chaining. */ diff --git a/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java b/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java index 9cb221d81070c..ef476ebc26678 100644 --- a/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java +++ b/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java @@ -35,7 +35,9 @@ public class SoftApCapabilityTest { */ @Test public void testCopyOperator() throws Exception { - SoftApCapability capability = new SoftApCapability(); + int testSoftApFeature = SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT + | SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD; + SoftApCapability capability = new SoftApCapability(testSoftApFeature); capability.setMaxSupportedClients(10); SoftApCapability copiedCapability = new SoftApCapability(capability); @@ -49,7 +51,9 @@ public class SoftApCapabilityTest { */ @Test public void testParcelOperation() throws Exception { - SoftApCapability capability = new SoftApCapability(); + int testSoftApFeature = SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT + | SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD; + SoftApCapability capability = new SoftApCapability(testSoftApFeature); capability.setMaxSupportedClients(10); Parcel parcelW = Parcel.obtain(); diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index d8bc1347c3328..f9bd31d57ffca 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -883,7 +883,7 @@ public class WifiManagerTest { */ @Test public void softApCallbackProxyCallsOnCapabilityChanged() throws Exception { - SoftApCapability testSoftApCapability = new SoftApCapability(); + SoftApCapability testSoftApCapability = new SoftApCapability(0); testSoftApCapability.setMaxSupportedClients(10); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); @@ -904,7 +904,7 @@ public class WifiManagerTest { SoftApInfo testSoftApInfo = new SoftApInfo(); testSoftApInfo.setFrequency(TEST_AP_FREQUENCY); testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH); - SoftApCapability testSoftApCapability = new SoftApCapability(); + SoftApCapability testSoftApCapability = new SoftApCapability(0); testSoftApCapability.setMaxSupportedClients(10); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class);