| /* |
| * 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.LongDef; |
| import android.annotation.NonNull; |
| import android.annotation.Nullable; |
| import android.annotation.SystemApi; |
| import android.net.MacAddress; |
| import android.net.wifi.SoftApConfiguration.BandType; |
| import android.os.Parcel; |
| import android.os.Parcelable; |
| |
| import java.lang.annotation.Retention; |
| import java.lang.annotation.RetentionPolicy; |
| import java.util.Arrays; |
| import java.util.Objects; |
| |
| /** |
| * A class representing capability of the SoftAp. |
| * {@see WifiManager} |
| * |
| * @hide |
| */ |
| @SystemApi |
| public final class SoftApCapability implements Parcelable { |
| |
| private static final String TAG = "SoftApCapability"; |
| private static final int[] EMPTY_INT_ARRAY = new int[0]; |
| /** |
| * Support for automatic channel selection in driver (ACS). |
| * Driver will auto select best channel based on interference to optimize performance. |
| * |
| * flag when {@code R.bool.config_wifi_softap_acs_supported} is true. |
| * |
| * <p> |
| * Use {@link WifiManager.SoftApCallback#onInfoChanged(SoftApInfo)} and |
| * {@link SoftApInfo#getFrequency()} and {@link SoftApInfo#getBandwidth()} to get |
| * driver channel selection result. |
| */ |
| public static final long SOFTAP_FEATURE_ACS_OFFLOAD = 1 << 0; |
| |
| /** |
| * Support for client force disconnect. |
| * flag when {@code R.bool.config_wifiSofapClientForceDisconnectSupported} is true |
| * |
| * <p> |
| * 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 long SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT = 1 << 1; |
| |
| /** |
| * Support for WPA3 Simultaneous Authentication of Equals (WPA3-SAE). |
| * |
| * flag when {@code config_wifi_softap_sae_supported} is true. |
| */ |
| public static final long SOFTAP_FEATURE_WPA3_SAE = 1 << 2; |
| |
| /** |
| * Support for MAC address customization. |
| * flag when {@code R.bool.config_wifiSoftapMacAddressCustomizationSupported} is true |
| * |
| * <p> |
| * Check feature support before invoking |
| * {@link SoftApConfiguration.Builder#setBssid(MacAddress)} or |
| * {@link SoftApConfiguration.Builder#setMacRandomizationSetting(int)} with |
| * {@link SoftApConfiguration#RANDOMIZATION_PERSISTENT} |
| */ |
| public static final long SOFTAP_FEATURE_MAC_ADDRESS_CUSTOMIZATION = 1 << 3; |
| |
| /** |
| * Support for 802.11ax SAP. |
| * flag when {@code R.bool.config_wifiSoftapIeee80211axSupported} is true |
| * |
| * <p> |
| * Check feature support before invoking |
| * {@link SoftApConfiguration.Builder#setIeee80211axEnabled(boolean)} |
| */ |
| public static final long SOFTAP_FEATURE_IEEE80211_AX = 1 << 4; |
| |
| /** |
| * Support for 2.4G Band. |
| * flag when {@code R.bool.config_wifiSoftap24ghzSupported} is true |
| */ |
| public static final long SOFTAP_FEATURE_BAND_24G_SUPPORTED = 1 << 5; |
| |
| /** |
| * Support for 5G Band. |
| * flag when {@code R.bool.config_wifiSoftap5ghzSupported} is true |
| */ |
| public static final long SOFTAP_FEATURE_BAND_5G_SUPPORTED = 1 << 6; |
| |
| /** |
| * Support for 6G Band. |
| * flag when {@code R.bool.config_wifiSoftap6ghzSupported} is true |
| */ |
| public static final long SOFTAP_FEATURE_BAND_6G_SUPPORTED = 1 << 7; |
| |
| /** |
| * Support for 60G Band. |
| * flag when {@code R.bool.config_wifiSoftap60ghzSupported} is true |
| */ |
| public static final long SOFTAP_FEATURE_BAND_60G_SUPPORTED = 1 << 8; |
| |
| /** @hide */ |
| @Retention(RetentionPolicy.SOURCE) |
| @LongDef(flag = true, prefix = { "SOFTAP_FEATURE_" }, value = { |
| SOFTAP_FEATURE_ACS_OFFLOAD, |
| SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT, |
| SOFTAP_FEATURE_WPA3_SAE, |
| SOFTAP_FEATURE_MAC_ADDRESS_CUSTOMIZATION, |
| SOFTAP_FEATURE_IEEE80211_AX, |
| SOFTAP_FEATURE_BAND_24G_SUPPORTED, |
| SOFTAP_FEATURE_BAND_5G_SUPPORTED, |
| SOFTAP_FEATURE_BAND_6G_SUPPORTED, |
| SOFTAP_FEATURE_BAND_60G_SUPPORTED |
| }) |
| public @interface HotspotFeatures {} |
| |
| private @HotspotFeatures long mSupportedFeatures = 0; |
| |
| private int mMaximumSupportedClientNumber; |
| |
| /** |
| * A list storing supported 2.4G channels. |
| */ |
| private int[] mSupportedChannelListIn24g = EMPTY_INT_ARRAY; |
| |
| /** |
| * A list storing supported 5G channels. |
| */ |
| private int[] mSupportedChannelListIn5g = EMPTY_INT_ARRAY; |
| |
| /** |
| * A list storing supported 6G channels. |
| */ |
| private int[] mSupportedChannelListIn6g = EMPTY_INT_ARRAY; |
| |
| /** |
| * A list storing supported 60G channels. |
| */ |
| private int[] mSupportedChannelListIn60g = EMPTY_INT_ARRAY; |
| |
| /** |
| * 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. |
| * |
| * @param maxClient maximum supported client numbers for the softap. |
| * @hide |
| */ |
| public void setMaxSupportedClients(int maxClient) { |
| mMaximumSupportedClientNumber = maxClient; |
| } |
| |
| /** |
| * Returns true when all of the queried features are supported, otherwise false. |
| * |
| * @param features One or combination of {@code SOFTAP_FEATURE_}, for instance: |
| * {@link #SOFTAP_FEATURE_ACS_OFFLOAD}, {@link #SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT} or |
| * {@link #SOFTAP_FEATURE_WPA3_SAE}. |
| */ |
| public boolean areFeaturesSupported(@HotspotFeatures long features) { |
| return (mSupportedFeatures & features) == features; |
| } |
| |
| /** |
| * Set supported channel list in target band type. |
| * |
| * @param band One of the following band types: |
| * {@link SoftApConfiguration#BAND_2GHZ}, {@link SoftApConfiguration#BAND_5GHZ}, |
| * {@link SoftApConfiguration#BAND_6GHZ}, or {@link SoftApConfiguration#BAND_60GHZ}. |
| * @param supportedChannelList supported channel list in target band |
| * @return true if band and supportedChannelList are valid, otherwise false. |
| * |
| * @throws IllegalArgumentException when band type is invalid. |
| * @hide |
| */ |
| public boolean setSupportedChannelList(@BandType int band, |
| @Nullable int[] supportedChannelList) { |
| if (supportedChannelList == null) return false; |
| switch (band) { |
| case SoftApConfiguration.BAND_2GHZ: |
| mSupportedChannelListIn24g = supportedChannelList; |
| break; |
| case SoftApConfiguration.BAND_5GHZ: |
| mSupportedChannelListIn5g = supportedChannelList; |
| break; |
| case SoftApConfiguration.BAND_6GHZ: |
| mSupportedChannelListIn6g = supportedChannelList; |
| break; |
| case SoftApConfiguration.BAND_60GHZ: |
| mSupportedChannelListIn60g = supportedChannelList; |
| break; |
| default: |
| throw new IllegalArgumentException("Invalid band: " + band); |
| } |
| return true; |
| } |
| |
| /** |
| * Returns a list of the supported channels in the given band. |
| * The result depends on the on the country code that has been set. |
| * Can be used to set the channel of the AP with the |
| * {@link SoftApConfiguration.Builder#setChannel(int, int)} API. |
| * |
| * @param band One of the following band types: |
| * {@link SoftApConfiguration#BAND_2GHZ}, {@link SoftApConfiguration#BAND_5GHZ}, |
| * {@link SoftApConfiguration#BAND_6GHZ}, {@link SoftApConfiguration#BAND_60GHZ}. |
| * @return List of supported channels for the band. |
| * |
| * @throws IllegalArgumentException when band type is invalid. |
| */ |
| @NonNull |
| public int[] getSupportedChannelList(@BandType int band) { |
| switch (band) { |
| case SoftApConfiguration.BAND_2GHZ: |
| return mSupportedChannelListIn24g; |
| case SoftApConfiguration.BAND_5GHZ: |
| return mSupportedChannelListIn5g; |
| case SoftApConfiguration.BAND_6GHZ: |
| return mSupportedChannelListIn6g; |
| case SoftApConfiguration.BAND_60GHZ: |
| return mSupportedChannelListIn60g; |
| default: |
| throw new IllegalArgumentException("Invalid band: " + band); |
| } |
| } |
| |
| /** |
| * @hide |
| */ |
| public SoftApCapability(@Nullable SoftApCapability source) { |
| if (source != null) { |
| mSupportedFeatures = source.mSupportedFeatures; |
| mMaximumSupportedClientNumber = source.mMaximumSupportedClientNumber; |
| mSupportedChannelListIn24g = source.mSupportedChannelListIn24g; |
| mSupportedChannelListIn5g = source.mSupportedChannelListIn5g; |
| mSupportedChannelListIn6g = source.mSupportedChannelListIn6g; |
| mSupportedChannelListIn60g = source.mSupportedChannelListIn60g; |
| } |
| } |
| |
| /** |
| * Constructor with combination of the feature. |
| * Zero to no supported feature. |
| * |
| * @param features One or combination of {@code SOFTAP_FEATURE_}, for instance: |
| * {@link #SOFTAP_FEATURE_ACS_OFFLOAD}, {@link #SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT} or |
| * {@link #SOFTAP_FEATURE_WPA3_SAE}. |
| * @hide |
| */ |
| public SoftApCapability(@HotspotFeatures long features) { |
| mSupportedFeatures = features; |
| } |
| |
| @Override |
| /** Implement the Parcelable interface. */ |
| public int describeContents() { |
| return 0; |
| } |
| |
| @Override |
| /** Implement the Parcelable interface */ |
| public void writeToParcel(@NonNull Parcel dest, int flags) { |
| dest.writeLong(mSupportedFeatures); |
| dest.writeInt(mMaximumSupportedClientNumber); |
| dest.writeIntArray(mSupportedChannelListIn24g); |
| dest.writeIntArray(mSupportedChannelListIn5g); |
| dest.writeIntArray(mSupportedChannelListIn6g); |
| dest.writeIntArray(mSupportedChannelListIn60g); |
| } |
| |
| @NonNull |
| /** Implement the Parcelable interface */ |
| public static final Creator<SoftApCapability> CREATOR = new Creator<SoftApCapability>() { |
| public SoftApCapability createFromParcel(Parcel in) { |
| SoftApCapability capability = new SoftApCapability(in.readLong()); |
| capability.mMaximumSupportedClientNumber = in.readInt(); |
| capability.setSupportedChannelList(SoftApConfiguration.BAND_2GHZ, in.createIntArray()); |
| capability.setSupportedChannelList(SoftApConfiguration.BAND_5GHZ, in.createIntArray()); |
| capability.setSupportedChannelList(SoftApConfiguration.BAND_6GHZ, in.createIntArray()); |
| capability.setSupportedChannelList(SoftApConfiguration.BAND_60GHZ, in.createIntArray()); |
| return capability; |
| } |
| |
| public SoftApCapability[] newArray(int size) { |
| return new SoftApCapability[size]; |
| } |
| }; |
| |
| @NonNull |
| @Override |
| public String toString() { |
| StringBuilder sbuf = new StringBuilder(); |
| sbuf.append("SupportedFeatures=").append(mSupportedFeatures); |
| sbuf.append("MaximumSupportedClientNumber=").append(mMaximumSupportedClientNumber); |
| sbuf.append("SupportedChannelListIn24g") |
| .append(Arrays.toString(mSupportedChannelListIn24g)); |
| sbuf.append("SupportedChannelListIn5g").append(Arrays.toString(mSupportedChannelListIn5g)); |
| sbuf.append("SupportedChannelListIn6g").append(Arrays.toString(mSupportedChannelListIn6g)); |
| sbuf.append("SupportedChannelListIn60g") |
| .append(Arrays.toString(mSupportedChannelListIn60g)); |
| 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 mSupportedFeatures == capability.mSupportedFeatures |
| && mMaximumSupportedClientNumber == capability.mMaximumSupportedClientNumber |
| && Arrays.equals(mSupportedChannelListIn24g, capability.mSupportedChannelListIn24g) |
| && Arrays.equals(mSupportedChannelListIn5g, capability.mSupportedChannelListIn5g) |
| && Arrays.equals(mSupportedChannelListIn6g, capability.mSupportedChannelListIn6g) |
| && Arrays.equals(mSupportedChannelListIn60g, capability.mSupportedChannelListIn60g); |
| } |
| |
| @Override |
| public int hashCode() { |
| return Objects.hash(mSupportedFeatures, mMaximumSupportedClientNumber, |
| Arrays.hashCode(mSupportedChannelListIn24g), |
| Arrays.hashCode(mSupportedChannelListIn5g), |
| Arrays.hashCode(mSupportedChannelListIn6g), |
| Arrays.hashCode(mSupportedChannelListIn60g)); |
| } |
| } |