Loading api/system-current.txt +5 −0 Original line number Diff line number Diff line Loading @@ -5739,6 +5739,7 @@ package android.net.wifi { field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApCapability> CREATOR; field public static final int SOFTAP_FEATURE_ACS_OFFLOAD = 1; // 0x1 field public static final int SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT = 2; // 0x2 field public static final int SOFTAP_FEATURE_WPA3_SAE = 4; // 0x4 } public final class SoftApConfiguration implements android.os.Parcelable { Loading @@ -5747,6 +5748,7 @@ package android.net.wifi { method @Nullable public android.net.MacAddress getBssid(); method public int getChannel(); method public int getMaxNumberOfClients(); method @Nullable public String getPassphrase(); method public int getSecurityType(); method @Nullable public String getSsid(); method @Nullable public String getWpa2Passphrase(); Loading @@ -5759,6 +5761,8 @@ package android.net.wifi { field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApConfiguration> CREATOR; field public static final int SECURITY_TYPE_OPEN = 0; // 0x0 field public static final int SECURITY_TYPE_WPA2_PSK = 1; // 0x1 field public static final int SECURITY_TYPE_WPA3_SAE = 3; // 0x3 field public static final int SECURITY_TYPE_WPA3_SAE_TRANSITION = 2; // 0x2 } public static final class SoftApConfiguration.Builder { Loading @@ -5770,6 +5774,7 @@ package android.net.wifi { 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 setPassphrase(@Nullable String, int); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setSsid(@Nullable String); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setWpa2Passphrase(@Nullable String); } Loading wifi/java/android/net/wifi/SoftApCapability.java +9 −0 Original line number Diff line number Diff line Loading @@ -61,11 +61,20 @@ public final class SoftApCapability implements Parcelable { */ public static final int SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT = 1 << 1; /** * Support for WPA3 Simultaneous Authentication of Equals (WPA3-SAE). * * flag when {@link config_wifi_softap_sae_supported)} is true. */ public static final int SOFTAP_FEATURE_WPA3_SAE = 1 << 2; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(flag = true, prefix = { "SOFTAP_FEATURE_" }, value = { SOFTAP_FEATURE_ACS_OFFLOAD, SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT, SOFTAP_FEATURE_WPA3_SAE, }) public @interface HotspotFeatures {} Loading wifi/java/android/net/wifi/SoftApConfiguration.java +87 −33 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; Loading Loading @@ -55,6 +56,11 @@ import java.util.concurrent.Executor; @SystemApi public final class SoftApConfiguration implements Parcelable { @VisibleForTesting static final int PSK_MIN_LEN = 8; @VisibleForTesting static final int PSK_MAX_LEN = 63; /** * 2GHz band. * @hide Loading Loading @@ -142,9 +148,10 @@ public final class SoftApConfiguration implements Parcelable { private final @Nullable MacAddress mBssid; /** * Pre-shared key for WPA2-PSK encryption (non-null enables WPA2-PSK). * Pre-shared key for WPA2-PSK or WPA3-SAE-Transition or WPA3-SAE encryption which depends on * the security type. */ private final @Nullable String mWpa2Passphrase; private final @Nullable String mPassphrase; /** * This is a network that does not broadcast its SSID, so an Loading Loading @@ -185,21 +192,31 @@ public final class SoftApConfiguration implements Parcelable { @SystemApi public static final int SECURITY_TYPE_WPA2_PSK = 1; /** @hide */ @SystemApi public static final int SECURITY_TYPE_WPA3_SAE_TRANSITION = 2; /** @hide */ @SystemApi public static final int SECURITY_TYPE_WPA3_SAE = 3; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "SECURITY_TYPE" }, value = { @IntDef(prefix = { "SECURITY_TYPE_" }, value = { SECURITY_TYPE_OPEN, SECURITY_TYPE_WPA2_PSK, SECURITY_TYPE_WPA3_SAE_TRANSITION, SECURITY_TYPE_WPA3_SAE, }) public @interface SecurityType {} /** 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, @Nullable String passphrase, boolean hiddenSsid, @BandType int band, int channel, @SecurityType int securityType, int maxNumberOfClients) { mSsid = ssid; mBssid = bssid; mWpa2Passphrase = wpa2Passphrase; mPassphrase = passphrase; mHiddenSsid = hiddenSsid; mBand = band; mChannel = channel; Loading @@ -218,7 +235,7 @@ public final class SoftApConfiguration implements Parcelable { SoftApConfiguration other = (SoftApConfiguration) otherObj; return Objects.equals(mSsid, other.mSsid) && Objects.equals(mBssid, other.mBssid) && Objects.equals(mWpa2Passphrase, other.mWpa2Passphrase) && Objects.equals(mPassphrase, other.mPassphrase) && mHiddenSsid == other.mHiddenSsid && mBand == other.mBand && mChannel == other.mChannel Loading @@ -228,7 +245,7 @@ public final class SoftApConfiguration implements Parcelable { @Override public int hashCode() { return Objects.hash(mSsid, mBssid, mWpa2Passphrase, mHiddenSsid, return Objects.hash(mSsid, mBssid, mPassphrase, mHiddenSsid, mBand, mChannel, mSecurityType, mMaxNumberOfClients); } Loading @@ -237,8 +254,8 @@ public final class SoftApConfiguration implements Parcelable { StringBuilder sbuf = new StringBuilder(); sbuf.append("ssid=").append(mSsid); if (mBssid != null) sbuf.append(" \n bssid=").append(mBssid.toString()); sbuf.append(" \n Wpa2Passphrase =").append( TextUtils.isEmpty(mWpa2Passphrase) ? "<empty>" : "<non-empty>"); sbuf.append(" \n Passphrase =").append( TextUtils.isEmpty(mPassphrase) ? "<empty>" : "<non-empty>"); sbuf.append(" \n HiddenSsid =").append(mHiddenSsid); sbuf.append(" \n Band =").append(mBand); sbuf.append(" \n Channel =").append(mChannel); Loading @@ -251,7 +268,7 @@ public final class SoftApConfiguration implements Parcelable { public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeString(mSsid); dest.writeParcelable(mBssid, flags); dest.writeString(mWpa2Passphrase); dest.writeString(mPassphrase); dest.writeBoolean(mHiddenSsid); dest.writeInt(mBand); dest.writeInt(mChannel); Loading Loading @@ -299,13 +316,26 @@ public final class SoftApConfiguration implements Parcelable { return mBssid; } // TODO: Remove it after update the caller /** * Returns String set to be passphrase for the WPA2-PSK AP. * {@link Builder#setWpa2Passphrase(String)}. * {@link #setWpa2Passphrase(String)}. */ @Nullable public String getWpa2Passphrase() { return mWpa2Passphrase; if (mSecurityType == SECURITY_TYPE_WPA2_PSK) { return mPassphrase; } return null; } /** * Returns String set to be passphrase for current AP. * {@link #setPassphrase(String, @SecurityType int)}. */ @Nullable public String getPassphrase() { return mPassphrase; } /** Loading Loading @@ -360,23 +390,12 @@ public final class SoftApConfiguration implements Parcelable { public static final class Builder { private String mSsid; private MacAddress mBssid; private String mWpa2Passphrase; private String mPassphrase; private boolean mHiddenSsid; private int mBand; private int mChannel; private int mMaxNumberOfClients; private int setSecurityType() { int securityType = SECURITY_TYPE_OPEN; if (!TextUtils.isEmpty(mWpa2Passphrase)) { // WPA2-PSK network. securityType = SECURITY_TYPE_WPA2_PSK; } return securityType; } private void clearAllPassphrase() { mWpa2Passphrase = null; } private int mSecurityType; /** * Constructs a Builder with default values (see {@link Builder}). Loading @@ -384,11 +403,12 @@ public final class SoftApConfiguration implements Parcelable { public Builder() { mSsid = null; mBssid = null; mWpa2Passphrase = null; mPassphrase = null; mHiddenSsid = false; mBand = BAND_2GHZ; mChannel = 0; mMaxNumberOfClients = 0; mSecurityType = SECURITY_TYPE_OPEN; } /** Loading @@ -399,11 +419,12 @@ public final class SoftApConfiguration implements Parcelable { mSsid = other.mSsid; mBssid = other.mBssid; mWpa2Passphrase = other.mWpa2Passphrase; mPassphrase = other.mPassphrase; mHiddenSsid = other.mHiddenSsid; mBand = other.mBand; mChannel = other.mChannel; mMaxNumberOfClients = other.mMaxNumberOfClients; mSecurityType = other.mSecurityType; } /** Loading @@ -413,8 +434,8 @@ public final class SoftApConfiguration implements Parcelable { */ @NonNull public SoftApConfiguration build() { return new SoftApConfiguration(mSsid, mBssid, mWpa2Passphrase, mHiddenSsid, mBand, mChannel, setSecurityType(), mMaxNumberOfClients); return new SoftApConfiguration(mSsid, mBssid, mPassphrase, mHiddenSsid, mBand, mChannel, mSecurityType, mMaxNumberOfClients); } /** Loading Loading @@ -461,6 +482,7 @@ public final class SoftApConfiguration implements Parcelable { return this; } // TODO: Remove it after update the caller /** * Specifies that this AP should use WPA2-PSK with the given ASCII WPA2 passphrase. * When set to null, an open network is created. Loading @@ -473,15 +495,47 @@ public final class SoftApConfiguration implements Parcelable { */ @NonNull public Builder setWpa2Passphrase(@Nullable String passphrase) { return setPassphrase(passphrase, SECURITY_TYPE_WPA2_PSK); } /** * Specifies that this AP should use specific security type with the given ASCII passphrase. * * @param securityType one of the security types from {@link @SecurityType}. * @param passphrase The passphrase to use for sepcific {@link @SecurityType} configuration * or null with {@link @SecurityType#SECURITY_TYPE_OPEN}. * * @return Builder for chaining. * @throws IllegalArgumentException when the passphrase length is invalid and * {@code securityType} is not {@link @SecurityType#SECURITY_TYPE_OPEN} * or non-null passphrase and {@code securityType} is * {@link @SecurityType#SECURITY_TYPE_OPEN}. */ @NonNull public Builder setPassphrase(@Nullable String passphrase, @SecurityType int securityType) { if (securityType == SECURITY_TYPE_OPEN) { if (passphrase != null) { throw new IllegalArgumentException( "passphrase should be null when security type is open"); } } else { Preconditions.checkStringNotEmpty(passphrase); final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder(); if (!asciiEncoder.canEncode(passphrase)) { throw new IllegalArgumentException("passphrase not ASCII encodable"); } Preconditions.checkStringNotEmpty(passphrase); if (securityType == SECURITY_TYPE_WPA2_PSK || securityType == SECURITY_TYPE_WPA3_SAE_TRANSITION) { if (passphrase.length() < PSK_MIN_LEN || passphrase.length() > PSK_MAX_LEN) { throw new IllegalArgumentException( "Password size must be at least " + PSK_MIN_LEN + " and no more than " + PSK_MAX_LEN + " for WPA2_PSK and WPA3_SAE_TRANSITION Mode"); } } clearAllPassphrase(); mWpa2Passphrase = passphrase; } mSecurityType = securityType; mPassphrase = passphrase; return this; } Loading wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java +122 −6 Original line number Diff line number Diff line Loading @@ -25,8 +25,12 @@ import androidx.test.filters.SmallTest; import org.junit.Test; import java.util.Random; @SmallTest public class SoftApConfigurationTest { private static final String TEST_CHAR_SET_AS_STRING = "abcdefghijklmnopqrstuvwxyz0123456789"; private SoftApConfiguration parcelUnparcel(SoftApConfiguration configIn) { Parcel parcel = Parcel.obtain(); parcel.writeParcelable(configIn, 0); Loading @@ -37,6 +41,25 @@ public class SoftApConfigurationTest { return configOut; } /** * Helper method to generate random string. * * Note: this method has limited use as a random string generator. * The characters used in this method do no not cover all valid inputs. * @param length number of characters to generate for the string * @return String generated string of random characters */ private String generateRandomString(int length) { Random random = new Random(); StringBuilder stringBuilder = new StringBuilder(length); int index = -1; while (stringBuilder.length() < length) { index = random.nextInt(TEST_CHAR_SET_AS_STRING.length()); stringBuilder.append(TEST_CHAR_SET_AS_STRING.charAt(index)); } return stringBuilder.toString(); } @Test public void testBasicSettings() { SoftApConfiguration original = new SoftApConfiguration.Builder() Loading @@ -45,7 +68,7 @@ public class SoftApConfigurationTest { .build(); assertThat(original.getSsid()).isEqualTo("ssid"); assertThat(original.getBssid()).isEqualTo(MacAddress.fromString("11:22:33:44:55:66")); assertThat(original.getWpa2Passphrase()).isNull(); assertThat(original.getPassphrase()).isNull(); assertThat(original.getSecurityType()).isEqualTo(SoftApConfiguration.SECURITY_TYPE_OPEN); assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ); assertThat(original.getChannel()).isEqualTo(0); Loading @@ -66,9 +89,9 @@ public class SoftApConfigurationTest { @Test public void testWpa2() { SoftApConfiguration original = new SoftApConfiguration.Builder() .setWpa2Passphrase("secretsecret") .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) .build(); assertThat(original.getWpa2Passphrase()).isEqualTo("secretsecret"); assertThat(original.getPassphrase()).isEqualTo("secretsecret"); assertThat(original.getSecurityType()).isEqualTo( SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ); Loading @@ -90,13 +113,12 @@ public class SoftApConfigurationTest { @Test public void testWpa2WithAllFieldCustomized() { SoftApConfiguration original = new SoftApConfiguration.Builder() .setWpa2Passphrase("secretsecret") .setBand(SoftApConfiguration.BAND_ANY) .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) .setChannel(149, SoftApConfiguration.BAND_5GHZ) .setHiddenSsid(true) .setMaxNumberOfClients(10) .build(); assertThat(original.getWpa2Passphrase()).isEqualTo("secretsecret"); assertThat(original.getPassphrase()).isEqualTo("secretsecret"); assertThat(original.getSecurityType()).isEqualTo( SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ); Loading @@ -114,4 +136,98 @@ public class SoftApConfigurationTest { assertThat(copy).isEqualTo(original); assertThat(copy.hashCode()).isEqualTo(original.hashCode()); } @Test public void testWpa3Sae() { SoftApConfiguration original = new SoftApConfiguration.Builder() .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE) .setChannel(149, SoftApConfiguration.BAND_5GHZ) .setHiddenSsid(true) .build(); assertThat(original.getPassphrase()).isEqualTo("secretsecret"); assertThat(original.getSecurityType()).isEqualTo( SoftApConfiguration.SECURITY_TYPE_WPA3_SAE); assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ); assertThat(original.getChannel()).isEqualTo(149); assertThat(original.isHiddenSsid()).isEqualTo(true); SoftApConfiguration unparceled = parcelUnparcel(original); assertThat(unparceled).isNotSameAs(original); assertThat(unparceled).isEqualTo(original); assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); assertThat(copy).isNotSameAs(original); assertThat(copy).isEqualTo(original); assertThat(copy.hashCode()).isEqualTo(original.hashCode()); } @Test public void testWpa3SaeTransition() { SoftApConfiguration original = new SoftApConfiguration.Builder() .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION) .setChannel(149, SoftApConfiguration.BAND_5GHZ) .setHiddenSsid(true) .build(); assertThat(original.getSecurityType()).isEqualTo( SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION); assertThat(original.getPassphrase()).isEqualTo("secretsecret"); assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ); assertThat(original.getChannel()).isEqualTo(149); assertThat(original.isHiddenSsid()).isEqualTo(true); SoftApConfiguration unparceled = parcelUnparcel(original); assertThat(unparceled).isNotSameAs(original); assertThat(unparceled).isEqualTo(original); assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); assertThat(copy).isNotSameAs(original); assertThat(copy).isEqualTo(original); assertThat(copy.hashCode()).isEqualTo(original.hashCode()); } @Test(expected = IllegalArgumentException.class) public void testInvalidShortPasswordLengthForWpa2() { SoftApConfiguration original = new SoftApConfiguration.Builder() .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MIN_LEN - 1), SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) .setChannel(149, SoftApConfiguration.BAND_5GHZ) .setHiddenSsid(true) .build(); } @Test(expected = IllegalArgumentException.class) public void testInvalidLongPasswordLengthForWpa2() { SoftApConfiguration original = new SoftApConfiguration.Builder() .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MAX_LEN + 1), SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) .setChannel(149, SoftApConfiguration.BAND_5GHZ) .setHiddenSsid(true) .build(); } @Test(expected = IllegalArgumentException.class) public void testInvalidShortPasswordLengthForWpa3SaeTransition() { SoftApConfiguration original = new SoftApConfiguration.Builder() .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MIN_LEN - 1), SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION) .setChannel(149, SoftApConfiguration.BAND_5GHZ) .setHiddenSsid(true) .build(); } @Test(expected = IllegalArgumentException.class) public void testInvalidLongPasswordLengthForWpa3SaeTransition() { SoftApConfiguration original = new SoftApConfiguration.Builder() .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MAX_LEN + 1), SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION) .setChannel(149, SoftApConfiguration.BAND_5GHZ) .setHiddenSsid(true) .build(); } } Loading
api/system-current.txt +5 −0 Original line number Diff line number Diff line Loading @@ -5739,6 +5739,7 @@ package android.net.wifi { field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApCapability> CREATOR; field public static final int SOFTAP_FEATURE_ACS_OFFLOAD = 1; // 0x1 field public static final int SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT = 2; // 0x2 field public static final int SOFTAP_FEATURE_WPA3_SAE = 4; // 0x4 } public final class SoftApConfiguration implements android.os.Parcelable { Loading @@ -5747,6 +5748,7 @@ package android.net.wifi { method @Nullable public android.net.MacAddress getBssid(); method public int getChannel(); method public int getMaxNumberOfClients(); method @Nullable public String getPassphrase(); method public int getSecurityType(); method @Nullable public String getSsid(); method @Nullable public String getWpa2Passphrase(); Loading @@ -5759,6 +5761,8 @@ package android.net.wifi { field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApConfiguration> CREATOR; field public static final int SECURITY_TYPE_OPEN = 0; // 0x0 field public static final int SECURITY_TYPE_WPA2_PSK = 1; // 0x1 field public static final int SECURITY_TYPE_WPA3_SAE = 3; // 0x3 field public static final int SECURITY_TYPE_WPA3_SAE_TRANSITION = 2; // 0x2 } public static final class SoftApConfiguration.Builder { Loading @@ -5770,6 +5774,7 @@ package android.net.wifi { 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 setPassphrase(@Nullable String, int); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setSsid(@Nullable String); method @NonNull public android.net.wifi.SoftApConfiguration.Builder setWpa2Passphrase(@Nullable String); } Loading
wifi/java/android/net/wifi/SoftApCapability.java +9 −0 Original line number Diff line number Diff line Loading @@ -61,11 +61,20 @@ public final class SoftApCapability implements Parcelable { */ public static final int SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT = 1 << 1; /** * Support for WPA3 Simultaneous Authentication of Equals (WPA3-SAE). * * flag when {@link config_wifi_softap_sae_supported)} is true. */ public static final int SOFTAP_FEATURE_WPA3_SAE = 1 << 2; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(flag = true, prefix = { "SOFTAP_FEATURE_" }, value = { SOFTAP_FEATURE_ACS_OFFLOAD, SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT, SOFTAP_FEATURE_WPA3_SAE, }) public @interface HotspotFeatures {} Loading
wifi/java/android/net/wifi/SoftApConfiguration.java +87 −33 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; Loading Loading @@ -55,6 +56,11 @@ import java.util.concurrent.Executor; @SystemApi public final class SoftApConfiguration implements Parcelable { @VisibleForTesting static final int PSK_MIN_LEN = 8; @VisibleForTesting static final int PSK_MAX_LEN = 63; /** * 2GHz band. * @hide Loading Loading @@ -142,9 +148,10 @@ public final class SoftApConfiguration implements Parcelable { private final @Nullable MacAddress mBssid; /** * Pre-shared key for WPA2-PSK encryption (non-null enables WPA2-PSK). * Pre-shared key for WPA2-PSK or WPA3-SAE-Transition or WPA3-SAE encryption which depends on * the security type. */ private final @Nullable String mWpa2Passphrase; private final @Nullable String mPassphrase; /** * This is a network that does not broadcast its SSID, so an Loading Loading @@ -185,21 +192,31 @@ public final class SoftApConfiguration implements Parcelable { @SystemApi public static final int SECURITY_TYPE_WPA2_PSK = 1; /** @hide */ @SystemApi public static final int SECURITY_TYPE_WPA3_SAE_TRANSITION = 2; /** @hide */ @SystemApi public static final int SECURITY_TYPE_WPA3_SAE = 3; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "SECURITY_TYPE" }, value = { @IntDef(prefix = { "SECURITY_TYPE_" }, value = { SECURITY_TYPE_OPEN, SECURITY_TYPE_WPA2_PSK, SECURITY_TYPE_WPA3_SAE_TRANSITION, SECURITY_TYPE_WPA3_SAE, }) public @interface SecurityType {} /** 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, @Nullable String passphrase, boolean hiddenSsid, @BandType int band, int channel, @SecurityType int securityType, int maxNumberOfClients) { mSsid = ssid; mBssid = bssid; mWpa2Passphrase = wpa2Passphrase; mPassphrase = passphrase; mHiddenSsid = hiddenSsid; mBand = band; mChannel = channel; Loading @@ -218,7 +235,7 @@ public final class SoftApConfiguration implements Parcelable { SoftApConfiguration other = (SoftApConfiguration) otherObj; return Objects.equals(mSsid, other.mSsid) && Objects.equals(mBssid, other.mBssid) && Objects.equals(mWpa2Passphrase, other.mWpa2Passphrase) && Objects.equals(mPassphrase, other.mPassphrase) && mHiddenSsid == other.mHiddenSsid && mBand == other.mBand && mChannel == other.mChannel Loading @@ -228,7 +245,7 @@ public final class SoftApConfiguration implements Parcelable { @Override public int hashCode() { return Objects.hash(mSsid, mBssid, mWpa2Passphrase, mHiddenSsid, return Objects.hash(mSsid, mBssid, mPassphrase, mHiddenSsid, mBand, mChannel, mSecurityType, mMaxNumberOfClients); } Loading @@ -237,8 +254,8 @@ public final class SoftApConfiguration implements Parcelable { StringBuilder sbuf = new StringBuilder(); sbuf.append("ssid=").append(mSsid); if (mBssid != null) sbuf.append(" \n bssid=").append(mBssid.toString()); sbuf.append(" \n Wpa2Passphrase =").append( TextUtils.isEmpty(mWpa2Passphrase) ? "<empty>" : "<non-empty>"); sbuf.append(" \n Passphrase =").append( TextUtils.isEmpty(mPassphrase) ? "<empty>" : "<non-empty>"); sbuf.append(" \n HiddenSsid =").append(mHiddenSsid); sbuf.append(" \n Band =").append(mBand); sbuf.append(" \n Channel =").append(mChannel); Loading @@ -251,7 +268,7 @@ public final class SoftApConfiguration implements Parcelable { public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeString(mSsid); dest.writeParcelable(mBssid, flags); dest.writeString(mWpa2Passphrase); dest.writeString(mPassphrase); dest.writeBoolean(mHiddenSsid); dest.writeInt(mBand); dest.writeInt(mChannel); Loading Loading @@ -299,13 +316,26 @@ public final class SoftApConfiguration implements Parcelable { return mBssid; } // TODO: Remove it after update the caller /** * Returns String set to be passphrase for the WPA2-PSK AP. * {@link Builder#setWpa2Passphrase(String)}. * {@link #setWpa2Passphrase(String)}. */ @Nullable public String getWpa2Passphrase() { return mWpa2Passphrase; if (mSecurityType == SECURITY_TYPE_WPA2_PSK) { return mPassphrase; } return null; } /** * Returns String set to be passphrase for current AP. * {@link #setPassphrase(String, @SecurityType int)}. */ @Nullable public String getPassphrase() { return mPassphrase; } /** Loading Loading @@ -360,23 +390,12 @@ public final class SoftApConfiguration implements Parcelable { public static final class Builder { private String mSsid; private MacAddress mBssid; private String mWpa2Passphrase; private String mPassphrase; private boolean mHiddenSsid; private int mBand; private int mChannel; private int mMaxNumberOfClients; private int setSecurityType() { int securityType = SECURITY_TYPE_OPEN; if (!TextUtils.isEmpty(mWpa2Passphrase)) { // WPA2-PSK network. securityType = SECURITY_TYPE_WPA2_PSK; } return securityType; } private void clearAllPassphrase() { mWpa2Passphrase = null; } private int mSecurityType; /** * Constructs a Builder with default values (see {@link Builder}). Loading @@ -384,11 +403,12 @@ public final class SoftApConfiguration implements Parcelable { public Builder() { mSsid = null; mBssid = null; mWpa2Passphrase = null; mPassphrase = null; mHiddenSsid = false; mBand = BAND_2GHZ; mChannel = 0; mMaxNumberOfClients = 0; mSecurityType = SECURITY_TYPE_OPEN; } /** Loading @@ -399,11 +419,12 @@ public final class SoftApConfiguration implements Parcelable { mSsid = other.mSsid; mBssid = other.mBssid; mWpa2Passphrase = other.mWpa2Passphrase; mPassphrase = other.mPassphrase; mHiddenSsid = other.mHiddenSsid; mBand = other.mBand; mChannel = other.mChannel; mMaxNumberOfClients = other.mMaxNumberOfClients; mSecurityType = other.mSecurityType; } /** Loading @@ -413,8 +434,8 @@ public final class SoftApConfiguration implements Parcelable { */ @NonNull public SoftApConfiguration build() { return new SoftApConfiguration(mSsid, mBssid, mWpa2Passphrase, mHiddenSsid, mBand, mChannel, setSecurityType(), mMaxNumberOfClients); return new SoftApConfiguration(mSsid, mBssid, mPassphrase, mHiddenSsid, mBand, mChannel, mSecurityType, mMaxNumberOfClients); } /** Loading Loading @@ -461,6 +482,7 @@ public final class SoftApConfiguration implements Parcelable { return this; } // TODO: Remove it after update the caller /** * Specifies that this AP should use WPA2-PSK with the given ASCII WPA2 passphrase. * When set to null, an open network is created. Loading @@ -473,15 +495,47 @@ public final class SoftApConfiguration implements Parcelable { */ @NonNull public Builder setWpa2Passphrase(@Nullable String passphrase) { return setPassphrase(passphrase, SECURITY_TYPE_WPA2_PSK); } /** * Specifies that this AP should use specific security type with the given ASCII passphrase. * * @param securityType one of the security types from {@link @SecurityType}. * @param passphrase The passphrase to use for sepcific {@link @SecurityType} configuration * or null with {@link @SecurityType#SECURITY_TYPE_OPEN}. * * @return Builder for chaining. * @throws IllegalArgumentException when the passphrase length is invalid and * {@code securityType} is not {@link @SecurityType#SECURITY_TYPE_OPEN} * or non-null passphrase and {@code securityType} is * {@link @SecurityType#SECURITY_TYPE_OPEN}. */ @NonNull public Builder setPassphrase(@Nullable String passphrase, @SecurityType int securityType) { if (securityType == SECURITY_TYPE_OPEN) { if (passphrase != null) { throw new IllegalArgumentException( "passphrase should be null when security type is open"); } } else { Preconditions.checkStringNotEmpty(passphrase); final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder(); if (!asciiEncoder.canEncode(passphrase)) { throw new IllegalArgumentException("passphrase not ASCII encodable"); } Preconditions.checkStringNotEmpty(passphrase); if (securityType == SECURITY_TYPE_WPA2_PSK || securityType == SECURITY_TYPE_WPA3_SAE_TRANSITION) { if (passphrase.length() < PSK_MIN_LEN || passphrase.length() > PSK_MAX_LEN) { throw new IllegalArgumentException( "Password size must be at least " + PSK_MIN_LEN + " and no more than " + PSK_MAX_LEN + " for WPA2_PSK and WPA3_SAE_TRANSITION Mode"); } } clearAllPassphrase(); mWpa2Passphrase = passphrase; } mSecurityType = securityType; mPassphrase = passphrase; return this; } Loading
wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java +122 −6 Original line number Diff line number Diff line Loading @@ -25,8 +25,12 @@ import androidx.test.filters.SmallTest; import org.junit.Test; import java.util.Random; @SmallTest public class SoftApConfigurationTest { private static final String TEST_CHAR_SET_AS_STRING = "abcdefghijklmnopqrstuvwxyz0123456789"; private SoftApConfiguration parcelUnparcel(SoftApConfiguration configIn) { Parcel parcel = Parcel.obtain(); parcel.writeParcelable(configIn, 0); Loading @@ -37,6 +41,25 @@ public class SoftApConfigurationTest { return configOut; } /** * Helper method to generate random string. * * Note: this method has limited use as a random string generator. * The characters used in this method do no not cover all valid inputs. * @param length number of characters to generate for the string * @return String generated string of random characters */ private String generateRandomString(int length) { Random random = new Random(); StringBuilder stringBuilder = new StringBuilder(length); int index = -1; while (stringBuilder.length() < length) { index = random.nextInt(TEST_CHAR_SET_AS_STRING.length()); stringBuilder.append(TEST_CHAR_SET_AS_STRING.charAt(index)); } return stringBuilder.toString(); } @Test public void testBasicSettings() { SoftApConfiguration original = new SoftApConfiguration.Builder() Loading @@ -45,7 +68,7 @@ public class SoftApConfigurationTest { .build(); assertThat(original.getSsid()).isEqualTo("ssid"); assertThat(original.getBssid()).isEqualTo(MacAddress.fromString("11:22:33:44:55:66")); assertThat(original.getWpa2Passphrase()).isNull(); assertThat(original.getPassphrase()).isNull(); assertThat(original.getSecurityType()).isEqualTo(SoftApConfiguration.SECURITY_TYPE_OPEN); assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ); assertThat(original.getChannel()).isEqualTo(0); Loading @@ -66,9 +89,9 @@ public class SoftApConfigurationTest { @Test public void testWpa2() { SoftApConfiguration original = new SoftApConfiguration.Builder() .setWpa2Passphrase("secretsecret") .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) .build(); assertThat(original.getWpa2Passphrase()).isEqualTo("secretsecret"); assertThat(original.getPassphrase()).isEqualTo("secretsecret"); assertThat(original.getSecurityType()).isEqualTo( SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ); Loading @@ -90,13 +113,12 @@ public class SoftApConfigurationTest { @Test public void testWpa2WithAllFieldCustomized() { SoftApConfiguration original = new SoftApConfiguration.Builder() .setWpa2Passphrase("secretsecret") .setBand(SoftApConfiguration.BAND_ANY) .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) .setChannel(149, SoftApConfiguration.BAND_5GHZ) .setHiddenSsid(true) .setMaxNumberOfClients(10) .build(); assertThat(original.getWpa2Passphrase()).isEqualTo("secretsecret"); assertThat(original.getPassphrase()).isEqualTo("secretsecret"); assertThat(original.getSecurityType()).isEqualTo( SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ); Loading @@ -114,4 +136,98 @@ public class SoftApConfigurationTest { assertThat(copy).isEqualTo(original); assertThat(copy.hashCode()).isEqualTo(original.hashCode()); } @Test public void testWpa3Sae() { SoftApConfiguration original = new SoftApConfiguration.Builder() .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE) .setChannel(149, SoftApConfiguration.BAND_5GHZ) .setHiddenSsid(true) .build(); assertThat(original.getPassphrase()).isEqualTo("secretsecret"); assertThat(original.getSecurityType()).isEqualTo( SoftApConfiguration.SECURITY_TYPE_WPA3_SAE); assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ); assertThat(original.getChannel()).isEqualTo(149); assertThat(original.isHiddenSsid()).isEqualTo(true); SoftApConfiguration unparceled = parcelUnparcel(original); assertThat(unparceled).isNotSameAs(original); assertThat(unparceled).isEqualTo(original); assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); assertThat(copy).isNotSameAs(original); assertThat(copy).isEqualTo(original); assertThat(copy.hashCode()).isEqualTo(original.hashCode()); } @Test public void testWpa3SaeTransition() { SoftApConfiguration original = new SoftApConfiguration.Builder() .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION) .setChannel(149, SoftApConfiguration.BAND_5GHZ) .setHiddenSsid(true) .build(); assertThat(original.getSecurityType()).isEqualTo( SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION); assertThat(original.getPassphrase()).isEqualTo("secretsecret"); assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ); assertThat(original.getChannel()).isEqualTo(149); assertThat(original.isHiddenSsid()).isEqualTo(true); SoftApConfiguration unparceled = parcelUnparcel(original); assertThat(unparceled).isNotSameAs(original); assertThat(unparceled).isEqualTo(original); assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); assertThat(copy).isNotSameAs(original); assertThat(copy).isEqualTo(original); assertThat(copy.hashCode()).isEqualTo(original.hashCode()); } @Test(expected = IllegalArgumentException.class) public void testInvalidShortPasswordLengthForWpa2() { SoftApConfiguration original = new SoftApConfiguration.Builder() .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MIN_LEN - 1), SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) .setChannel(149, SoftApConfiguration.BAND_5GHZ) .setHiddenSsid(true) .build(); } @Test(expected = IllegalArgumentException.class) public void testInvalidLongPasswordLengthForWpa2() { SoftApConfiguration original = new SoftApConfiguration.Builder() .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MAX_LEN + 1), SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) .setChannel(149, SoftApConfiguration.BAND_5GHZ) .setHiddenSsid(true) .build(); } @Test(expected = IllegalArgumentException.class) public void testInvalidShortPasswordLengthForWpa3SaeTransition() { SoftApConfiguration original = new SoftApConfiguration.Builder() .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MIN_LEN - 1), SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION) .setChannel(149, SoftApConfiguration.BAND_5GHZ) .setHiddenSsid(true) .build(); } @Test(expected = IllegalArgumentException.class) public void testInvalidLongPasswordLengthForWpa3SaeTransition() { SoftApConfiguration original = new SoftApConfiguration.Builder() .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MAX_LEN + 1), SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION) .setChannel(149, SoftApConfiguration.BAND_5GHZ) .setHiddenSsid(true) .build(); } }