Merge "WifiNetworkConfigBuilder: Split into 2 separate builders"
diff --git a/api/current.txt b/api/current.txt
index e7018d2..fa147db 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -28949,6 +28949,7 @@
}
public abstract class NetworkSpecifier {
+ ctor public NetworkSpecifier();
}
public class ParseException extends java.lang.RuntimeException {
@@ -29972,24 +29973,25 @@
method @Deprecated public abstract void onSucceeded();
}
- public class WifiNetworkConfigBuilder {
- ctor public WifiNetworkConfigBuilder();
- method public android.net.NetworkSpecifier buildNetworkSpecifier();
- method public android.net.wifi.WifiNetworkSuggestion buildNetworkSuggestion();
- method public android.net.wifi.WifiNetworkConfigBuilder setBssid(@NonNull android.net.MacAddress);
- method public android.net.wifi.WifiNetworkConfigBuilder setBssidPattern(@NonNull android.net.MacAddress, @NonNull android.net.MacAddress);
- method public android.net.wifi.WifiNetworkConfigBuilder setIsAppInteractionRequired();
- method public android.net.wifi.WifiNetworkConfigBuilder setIsEnhancedOpen();
- method public android.net.wifi.WifiNetworkConfigBuilder setIsHiddenSsid();
- method public android.net.wifi.WifiNetworkConfigBuilder setIsMetered();
- method public android.net.wifi.WifiNetworkConfigBuilder setIsUserInteractionRequired();
- method public android.net.wifi.WifiNetworkConfigBuilder setPriority(int);
- method public android.net.wifi.WifiNetworkConfigBuilder setSsid(@NonNull String);
- method public android.net.wifi.WifiNetworkConfigBuilder setSsidPattern(@NonNull android.os.PatternMatcher);
- method public android.net.wifi.WifiNetworkConfigBuilder setWpa2EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
- method public android.net.wifi.WifiNetworkConfigBuilder setWpa2Passphrase(@NonNull String);
- method public android.net.wifi.WifiNetworkConfigBuilder setWpa3EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
- method public android.net.wifi.WifiNetworkConfigBuilder setWpa3Passphrase(@NonNull String);
+ public final class WifiNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.WifiNetworkSpecifier> CREATOR;
+ }
+
+ public static class WifiNetworkSpecifier.Builder {
+ ctor public WifiNetworkSpecifier.Builder();
+ method public android.net.NetworkSpecifier build();
+ method public android.net.wifi.WifiNetworkSpecifier.Builder setBssid(@NonNull android.net.MacAddress);
+ method public android.net.wifi.WifiNetworkSpecifier.Builder setBssidPattern(@NonNull android.net.MacAddress, @NonNull android.net.MacAddress);
+ method public android.net.wifi.WifiNetworkSpecifier.Builder setIsEnhancedOpen();
+ method public android.net.wifi.WifiNetworkSpecifier.Builder setIsHiddenSsid();
+ method public android.net.wifi.WifiNetworkSpecifier.Builder setSsid(@NonNull String);
+ method public android.net.wifi.WifiNetworkSpecifier.Builder setSsidPattern(@NonNull android.os.PatternMatcher);
+ method public android.net.wifi.WifiNetworkSpecifier.Builder setWpa2EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
+ method public android.net.wifi.WifiNetworkSpecifier.Builder setWpa2Passphrase(@NonNull String);
+ method public android.net.wifi.WifiNetworkSpecifier.Builder setWpa3EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
+ method public android.net.wifi.WifiNetworkSpecifier.Builder setWpa3Passphrase(@NonNull String);
}
public final class WifiNetworkSuggestion implements android.os.Parcelable {
@@ -29998,6 +30000,23 @@
field public static final android.os.Parcelable.Creator<android.net.wifi.WifiNetworkSuggestion> CREATOR;
}
+ public static class WifiNetworkSuggestion.Builder {
+ ctor public WifiNetworkSuggestion.Builder();
+ method public android.net.wifi.WifiNetworkSuggestion build();
+ method public android.net.wifi.WifiNetworkSuggestion.Builder setBssid(@NonNull android.net.MacAddress);
+ method public android.net.wifi.WifiNetworkSuggestion.Builder setIsAppInteractionRequired();
+ method public android.net.wifi.WifiNetworkSuggestion.Builder setIsEnhancedOpen();
+ method public android.net.wifi.WifiNetworkSuggestion.Builder setIsHiddenSsid();
+ method public android.net.wifi.WifiNetworkSuggestion.Builder setIsMetered();
+ method public android.net.wifi.WifiNetworkSuggestion.Builder setIsUserInteractionRequired();
+ method public android.net.wifi.WifiNetworkSuggestion.Builder setPriority(int);
+ method public android.net.wifi.WifiNetworkSuggestion.Builder setSsid(@NonNull String);
+ method public android.net.wifi.WifiNetworkSuggestion.Builder setWpa2EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
+ method public android.net.wifi.WifiNetworkSuggestion.Builder setWpa2Passphrase(@NonNull String);
+ method public android.net.wifi.WifiNetworkSuggestion.Builder setWpa3EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
+ method public android.net.wifi.WifiNetworkSuggestion.Builder setWpa3Passphrase(@NonNull String);
+ }
+
public class WpsInfo implements android.os.Parcelable {
ctor public WpsInfo();
ctor public WpsInfo(android.net.wifi.WpsInfo);
diff --git a/core/java/android/net/NetworkSpecifier.java b/core/java/android/net/NetworkSpecifier.java
index fcfb720..2bc3eb5 100644
--- a/core/java/android/net/NetworkSpecifier.java
+++ b/core/java/android/net/NetworkSpecifier.java
@@ -23,7 +23,6 @@
* subclasses of this class via other APIs.
*/
public abstract class NetworkSpecifier {
- /** @hide */
public NetworkSpecifier() {}
/**
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 96493de..c50e6a7 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -49,8 +49,9 @@
* A class representing a configured Wi-Fi network, including the
* security configuration.
*
- * @deprecated Use {@link WifiNetworkConfigBuilder} to create {@link NetworkSpecifier} and
- * {@link WifiNetworkSuggestion}. This will become a system use only object in the future.
+ * @deprecated Use {@link WifiNetworkSpecifier.Builder} to create {@link NetworkSpecifier} and
+ * {@link WifiNetworkSuggestion.Builder} to create {@link WifiNetworkSuggestion}. This will become a
+ * system use only object in the future.
*/
@Deprecated
public class WifiConfiguration implements Parcelable {
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index e5733ed..289f99d 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -947,8 +947,8 @@
/**
* Directed broadcast intent action indicating that the device has connected to one of the
* network suggestions provided by the app. This will be sent post connection to a network
- * which was created with {@link WifiNetworkConfigBuilder#setIsAppInteractionRequired()} flag
- * set.
+ * which was created with {@link WifiNetworkSuggestion.Builder#setIsAppInteractionRequired()}
+ * flag set.
* <p>
* Note: The broadcast is sent to the app only if it holds
* {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission.
@@ -1171,7 +1171,7 @@
* of {@link WifiConfiguration} objects.
*
* @deprecated
- * a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
+ * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
* mechanism to trigger connection to a Wi-Fi network.
* b) See {@link #addNetworkSuggestions(List)},
* {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
@@ -1323,7 +1323,7 @@
* Returns {@code -1} on failure.
*
* @deprecated
- * a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
+ * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
* mechanism to trigger connection to a Wi-Fi network.
* b) See {@link #addNetworkSuggestions(List)},
* {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
@@ -1358,7 +1358,7 @@
* existing network.
*
* @deprecated
- * a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
+ * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
* mechanism to trigger connection to a Wi-Fi network.
* b) See {@link #addNetworkSuggestions(List)},
* {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
@@ -1647,8 +1647,8 @@
* for a detailed explanation of the parameters.
* When the device decides to connect to one of the provided network suggestions, platform sends
* a directed broadcast {@link #ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION} to the app if
- * the network was created with {@link WifiNetworkConfigBuilder#setIsAppInteractionRequired()}
- * flag set and the app holds
+ * the network was created with {@link WifiNetworkSuggestion.Builder
+ * #setIsAppInteractionRequired()} flag set and the app holds
* {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission.
*<p>
* NOTE:
@@ -1835,7 +1835,7 @@
* @return {@code true} if the operation succeeded
*
* @deprecated
- * a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
+ * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
* mechanism to trigger connection to a Wi-Fi network.
* b) See {@link #addNetworkSuggestions(List)},
* {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
@@ -1879,7 +1879,7 @@
* @return {@code true} if the operation succeeded
*
* @deprecated
- * a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
+ * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
* mechanism to trigger connection to a Wi-Fi network.
* b) See {@link #addNetworkSuggestions(List)},
* {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
@@ -1911,7 +1911,7 @@
* @return {@code true} if the operation succeeded
*
* @deprecated
- * a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
+ * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
* mechanism to trigger connection to a Wi-Fi network.
* b) See {@link #addNetworkSuggestions(List)},
* {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
@@ -1934,7 +1934,7 @@
* @return {@code true} if the operation succeeded
*
* @deprecated
- * a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
+ * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
* mechanism to trigger connection to a Wi-Fi network.
* b) See {@link #addNetworkSuggestions(List)},
* {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
@@ -1958,7 +1958,7 @@
* @return {@code true} if the operation succeeded
*
* @deprecated
- * a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
+ * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
* mechanism to trigger connection to a Wi-Fi network.
* b) See {@link #addNetworkSuggestions(List)},
* {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
@@ -1982,7 +1982,7 @@
* @return {@code true} if the operation succeeded
*
* @deprecated
- * a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
+ * a) See {@link WifiNetworkSpecifier.Builder#build()} for new
* mechanism to trigger connection to a Wi-Fi network.
* b) See {@link #addNetworkSuggestions(List)},
* {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
diff --git a/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java
index 52ee742..9d87466 100644
--- a/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java
+++ b/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java
@@ -124,7 +124,7 @@
*/
public boolean satisfiesNetworkSpecifier(@NonNull WifiNetworkSpecifier ns) {
// None of these should be null by construction.
- // {@link WifiNetworkConfigBuilder} enforces non-null in {@link WifiNetworkSpecifier}.
+ // {@link WifiNetworkSpecifier.Builder} enforces non-null in {@link WifiNetworkSpecifier}.
// {@link WifiNetworkFactory} ensures non-null in {@link WifiNetworkAgentSpecifier}.
checkNotNull(ns);
checkNotNull(ns.ssidPatternMatcher);
diff --git a/wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java b/wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java
deleted file mode 100644
index 42d4393..0000000
--- a/wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java
+++ /dev/null
@@ -1,657 +0,0 @@
-/*
- * Copyright (C) 2018 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.internal.util.Preconditions.checkNotNull;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.ActivityThread;
-import android.net.MacAddress;
-import android.net.NetworkRequest;
-import android.net.NetworkSpecifier;
-import android.os.PatternMatcher;
-import android.os.Process;
-import android.text.TextUtils;
-import android.util.Pair;
-
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-
-/**
- * WifiNetworkConfigBuilder to use for creating Wi-Fi network configuration.
- * <li>See {@link #buildNetworkSpecifier()} for creating a network specifier to use in
- * {@link NetworkRequest}.</li>
- * <li>See {@link #buildNetworkSuggestion()} for creating a network suggestion to use in
- * {@link WifiManager#addNetworkSuggestions(List)}.</li>
- */
-public class WifiNetworkConfigBuilder {
- private static final String MATCH_ALL_SSID_PATTERN_PATH = ".*";
- private static final String MATCH_EMPTY_SSID_PATTERN_PATH = "";
- private static final Pair<MacAddress, MacAddress> MATCH_NO_BSSID_PATTERN1 =
- new Pair(MacAddress.BROADCAST_ADDRESS, MacAddress.BROADCAST_ADDRESS);
- private static final Pair<MacAddress, MacAddress> MATCH_NO_BSSID_PATTERN2 =
- new Pair(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.BROADCAST_ADDRESS);
- private static final Pair<MacAddress, MacAddress> MATCH_ALL_BSSID_PATTERN =
- new Pair(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
- private static final MacAddress MATCH_EXACT_BSSID_PATTERN_MASK =
- MacAddress.BROADCAST_ADDRESS;
- private static final int UNASSIGNED_PRIORITY = -1;
-
- /**
- * SSID pattern match specified by the app.
- */
- private @Nullable PatternMatcher mSsidPatternMatcher;
- /**
- * BSSID pattern match specified by the app.
- * Pair of <BaseAddress, Mask>.
- */
- private @Nullable Pair<MacAddress, MacAddress> mBssidPatternMatcher;
- /**
- * Whether this is an OWE network or not.
- */
- private boolean mIsEnhancedOpen;
- /**
- * Pre-shared key for use with WPA-PSK networks.
- */
- private @Nullable String mWpa2PskPassphrase;
- /**
- * Pre-shared key for use with WPA3-SAE networks.
- */
- private @Nullable String mWpa3SaePassphrase;
- /**
- * The enterprise configuration details specifying the EAP method,
- * certificates and other settings associated with the WPA-EAP networks.
- */
- private @Nullable WifiEnterpriseConfig mWpa2EnterpriseConfig;
- /**
- * The enterprise configuration details specifying the EAP method,
- * certificates and other settings associated with the SuiteB networks.
- */
- private @Nullable WifiEnterpriseConfig mWpa3EnterpriseConfig;
- /**
- * This is a network that does not broadcast its SSID, so an
- * SSID-specific probe request must be used for scans.
- */
- private boolean mIsHiddenSSID;
- /**
- * Whether app needs to log in to captive portal to obtain Internet access.
- */
- private boolean mIsAppInteractionRequired;
- /**
- * Whether user needs to log in to captive portal to obtain Internet access.
- */
- private boolean mIsUserInteractionRequired;
- /**
- * Whether this network is metered or not.
- */
- private boolean mIsMetered;
- /**
- * Priority of this network among other network suggestions provided by the app.
- * The lower the number, the higher the priority (i.e value of 0 = highest priority).
- */
- private int mPriority;
-
- public WifiNetworkConfigBuilder() {
- mSsidPatternMatcher = null;
- mBssidPatternMatcher = null;
- mIsEnhancedOpen = false;
- mWpa2PskPassphrase = null;
- mWpa3SaePassphrase = null;
- mWpa2EnterpriseConfig = null;
- mWpa3EnterpriseConfig = null;
- mIsHiddenSSID = false;
- mIsAppInteractionRequired = false;
- mIsUserInteractionRequired = false;
- mIsMetered = false;
- mPriority = UNASSIGNED_PRIORITY;
- }
-
- /**
- * Set the unicode SSID match pattern to use for filtering networks from scan results.
- * <p>
- * <li>Only allowed for creating network specifier, i.e {@link #buildNetworkSpecifier()}. </li>
- * <li>Overrides any previous value set using {@link #setSsid(String)} or
- * {@link #setSsidPattern(PatternMatcher)}.</li>
- *
- * @param ssidPattern Instance of {@link PatternMatcher} containing the UTF-8 encoded
- * string pattern to use for matching the network's SSID.
- * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
- * method.
- */
- public WifiNetworkConfigBuilder setSsidPattern(@NonNull PatternMatcher ssidPattern) {
- checkNotNull(ssidPattern);
- mSsidPatternMatcher = ssidPattern;
- return this;
- }
-
- /**
- * Set the unicode SSID for the network.
- * <p>
- * <li>For network requests ({@link NetworkSpecifier}), built using
- * {@link #buildNetworkSpecifier}, sets the SSID to use for filtering networks from scan
- * results. Will only match networks whose SSID is identical to the UTF-8 encoding of the
- * specified value.</li>
- * <li>For network suggestions ({@link WifiNetworkSuggestion}), built using
- * {@link #buildNetworkSuggestion()}, sets the SSID for the network.</li>
- * <li>Overrides any previous value set using {@link #setSsid(String)} or
- * {@link #setSsidPattern(PatternMatcher)}.</li>
- *
- * @param ssid The SSID of the network. It must be valid Unicode.
- * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
- * method.
- * @throws IllegalArgumentException if the SSID is not valid unicode.
- */
- public WifiNetworkConfigBuilder setSsid(@NonNull String ssid) {
- checkNotNull(ssid);
- final CharsetEncoder unicodeEncoder = StandardCharsets.UTF_8.newEncoder();
- if (!unicodeEncoder.canEncode(ssid)) {
- throw new IllegalArgumentException("SSID is not a valid unicode string");
- }
- mSsidPatternMatcher = new PatternMatcher(ssid, PatternMatcher.PATTERN_LITERAL);
- return this;
- }
-
- /**
- * Set the BSSID match pattern to use for filtering networks from scan results.
- * Will match all networks with BSSID which satisfies the following:
- * {@code BSSID & mask == baseAddress}.
- * <p>
- * <li>Only allowed for creating network specifier, i.e {@link #buildNetworkSpecifier()}. </li>
- * <li>Overrides any previous value set using {@link #setBssid(MacAddress)} or
- * {@link #setBssidPattern(MacAddress, MacAddress)}.</li>
- *
- * @param baseAddress Base address for BSSID pattern.
- * @param mask Mask for BSSID pattern.
- * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
- * method.
- */
- public WifiNetworkConfigBuilder setBssidPattern(
- @NonNull MacAddress baseAddress, @NonNull MacAddress mask) {
- checkNotNull(baseAddress, mask);
- mBssidPatternMatcher = Pair.create(baseAddress, mask);
- return this;
- }
-
- /**
- * Set the BSSID to use for filtering networks from scan results. Will only match network whose
- * BSSID is identical to the specified value.
- * <p>
- * <li>For network requests ({@link NetworkSpecifier}), built using
- * {@link #buildNetworkSpecifier}, sets the BSSID to use for filtering networks from scan
- * results. Will only match networks whose BSSID is identical to specified value.</li>
- * <li>For network suggestions ({@link WifiNetworkSuggestion}), built using
- * {@link #buildNetworkSuggestion()}, sets a specific BSSID for the network suggestion.
- * If set, only the specified BSSID with the specified SSID will be considered for connection.
- * If not set, all BSSIDs with the specified SSID will be considered for connection.</li>
- * <li>Overrides any previous value set using {@link #setBssid(MacAddress)} or
- * {@link #setBssidPattern(MacAddress, MacAddress)}.</li>
- *
- * @param bssid BSSID of the network.
- * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
- * method.
- */
- public WifiNetworkConfigBuilder setBssid(@NonNull MacAddress bssid) {
- checkNotNull(bssid);
- mBssidPatternMatcher = Pair.create(bssid, MATCH_EXACT_BSSID_PATTERN_MASK);
- return this;
- }
-
- /**
- * Specifies whether this represents an Enhanced Open (OWE) network.
- *
- * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
- * method.
- */
- public WifiNetworkConfigBuilder setIsEnhancedOpen() {
- mIsEnhancedOpen = true;
- return this;
- }
-
- /**
- * Set the ASCII WPA2 passphrase for this network. Needed for authenticating to
- * WPA2-PSK networks.
- *
- * @param passphrase passphrase of the network.
- * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
- * method.
- * @throws IllegalArgumentException if the passphrase is not ASCII encodable.
- */
- public WifiNetworkConfigBuilder setWpa2Passphrase(@NonNull String passphrase) {
- checkNotNull(passphrase);
- final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
- if (!asciiEncoder.canEncode(passphrase)) {
- throw new IllegalArgumentException("passphrase not ASCII encodable");
- }
- mWpa2PskPassphrase = passphrase;
- return this;
- }
-
- /**
- * Set the ASCII WPA3 passphrase for this network. Needed for authenticating to
- * WPA3-SAE networks.
- *
- * @param passphrase passphrase of the network.
- * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
- * method.
- * @throws IllegalArgumentException if the passphrase is not ASCII encodable.
- */
- public WifiNetworkConfigBuilder setWpa3Passphrase(@NonNull String passphrase) {
- checkNotNull(passphrase);
- final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
- if (!asciiEncoder.canEncode(passphrase)) {
- throw new IllegalArgumentException("passphrase not ASCII encodable");
- }
- mWpa3SaePassphrase = passphrase;
- return this;
- }
-
- /**
- * Set the associated enterprise configuration for this network. Needed for authenticating to
- * WPA2-EAP networks. See {@link WifiEnterpriseConfig} for description.
- *
- * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
- * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
- * method.
- */
- public WifiNetworkConfigBuilder setWpa2EnterpriseConfig(
- @NonNull WifiEnterpriseConfig enterpriseConfig) {
- checkNotNull(enterpriseConfig);
- mWpa2EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
- return this;
- }
-
- /**
- * Set the associated enterprise configuration for this network. Needed for authenticating to
- * WPA3-SuiteB networks. See {@link WifiEnterpriseConfig} for description.
- *
- * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
- * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
- * method.
- */
- public WifiNetworkConfigBuilder setWpa3EnterpriseConfig(
- @NonNull WifiEnterpriseConfig enterpriseConfig) {
- checkNotNull(enterpriseConfig);
- mWpa3EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
- return this;
- }
-
- /**
- * Specifies whether this represents a hidden network.
- * <p>
- * <li>For network requests (see {@link NetworkSpecifier}), built using
- * {@link #buildNetworkSpecifier}, setting this disallows the usage of
- * {@link #setSsidPattern(PatternMatcher)} since hidden networks need to be explicitly
- * probed for.</li>
- * <li>If not set, defaults to false (i.e not a hidden network).</li>
- *
- * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
- * method.
- */
- public WifiNetworkConfigBuilder setIsHiddenSsid() {
- mIsHiddenSSID = true;
- return this;
- }
-
- /**
- * Specifies whether the app needs to log in to a captive portal to obtain Internet access.
- * <p>
- * This will dictate if the directed broadcast
- * {@link WifiManager#ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION} will be sent to the app
- * after successfully connecting to the network.
- * Use this for captive portal type networks where the app needs to authenticate the user
- * before the device can access the network.
- * <p>
- * <li>Only allowed for creating network suggestion, i.e {@link #buildNetworkSuggestion()}.</li>
- * <li>If not set, defaults to false (i.e no app interaction required).</li>
- *
- * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
- * method.
- */
- public WifiNetworkConfigBuilder setIsAppInteractionRequired() {
- mIsAppInteractionRequired = true;
- return this;
- }
-
- /**
- * Specifies whether the user needs to log in to a captive portal to obtain Internet access.
- * <p>
- * <li>Only allowed for creating network suggestion, i.e {@link #buildNetworkSuggestion()}.</li>
- * <li>If not set, defaults to false (i.e no user interaction required).</li>
- *
- * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
- * method.
- */
- public WifiNetworkConfigBuilder setIsUserInteractionRequired() {
- mIsUserInteractionRequired = true;
- return this;
- }
-
- /**
- * Specify the priority of this network among other network suggestions provided by the same app
- * (priorities have no impact on suggestions by different apps). The lower the number, the
- * higher the priority (i.e value of 0 = highest priority).
- * <p>
- * <li>Only allowed for creating network suggestion, i.e {@link #buildNetworkSuggestion()}.</li>
- * <li>If not set, defaults to -1 (i.e unassigned priority).</li>
- *
- * @param priority Integer number representing the priority among suggestions by the app.
- * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
- * method.
- * @throws IllegalArgumentException if the priority value is negative.
- */
- public WifiNetworkConfigBuilder setPriority(int priority) {
- if (priority < 0) {
- throw new IllegalArgumentException("Invalid priority value " + priority);
- }
- mPriority = priority;
- return this;
- }
-
- /**
- * Specifies whether this network is metered.
- * <p>
- * <li>Only allowed for creating network suggestion, i.e {@link #buildNetworkSuggestion()}.</li>
- * <li>If not set, defaults to false (i.e not metered).</li>
- *
- * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
- * method.
- */
- public WifiNetworkConfigBuilder setIsMetered() {
- mIsMetered = true;
- return this;
- }
-
- /**
- * Set defaults for the various low level credential type fields in the newly created
- * WifiConfiguration object.
- *
- * See {@link com.android.server.wifi.WifiConfigManager#setDefaultsInWifiConfiguration(
- * WifiConfiguration)}.
- *
- * @param configuration provided WifiConfiguration object.
- */
- private static void setDefaultsInWifiConfiguration(@NonNull WifiConfiguration configuration) {
- configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
- configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
- configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
- configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
- configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
- }
-
- private void setSecurityParamsInWifiConfiguration(@NonNull WifiConfiguration configuration) {
- if (!TextUtils.isEmpty(mWpa2PskPassphrase)) { // WPA-PSK network.
- configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
- // WifiConfiguration.preSharedKey needs quotes around ASCII password.
- configuration.preSharedKey = "\"" + mWpa2PskPassphrase + "\"";
- } else if (!TextUtils.isEmpty(mWpa3SaePassphrase)) { // WPA3-SAE network.
- configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SAE);
- // PMF mandatory for SAE.
- configuration.requirePMF = true;
- // WifiConfiguration.preSharedKey needs quotes around ASCII password.
- configuration.preSharedKey = "\"" + mWpa3SaePassphrase + "\"";
- } else if (mWpa2EnterpriseConfig != null) { // WPA-EAP network
- configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
- configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
- configuration.enterpriseConfig = mWpa2EnterpriseConfig;
- } else if (mWpa3EnterpriseConfig != null) { // WPA3-SuiteB network
- configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192);
- configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
- // TODO (b/113878056): Verify these params once we verify SuiteB configuration.
- configuration.allowedGroupManagementCiphers.set(
- WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256);
- configuration.allowedSuiteBCiphers.set(
- WifiConfiguration.SuiteBCipher.ECDHE_ECDSA);
- configuration.allowedSuiteBCiphers.set(
- WifiConfiguration.SuiteBCipher.ECDHE_RSA);
- configuration.requirePMF = true;
- configuration.enterpriseConfig = mWpa3EnterpriseConfig;
- } else if (mIsEnhancedOpen) { // OWE network
- configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.OWE);
- // PMF mandatory.
- configuration.requirePMF = true;
- } else { // Open network
- configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
- }
- }
-
- /**
- * Helper method to build WifiConfiguration object from the builder.
- * @return Instance of {@link WifiConfiguration}.
- */
- private WifiConfiguration buildWifiConfiguration() {
- final WifiConfiguration wifiConfiguration = new WifiConfiguration();
- setDefaultsInWifiConfiguration(wifiConfiguration);
- // WifiConfiguration.SSID needs quotes around unicode SSID.
- if (mSsidPatternMatcher.getType() == PatternMatcher.PATTERN_LITERAL) {
- wifiConfiguration.SSID = "\"" + mSsidPatternMatcher.getPath() + "\"";
- }
- if (mBssidPatternMatcher.second == MATCH_EXACT_BSSID_PATTERN_MASK) {
- wifiConfiguration.BSSID = mBssidPatternMatcher.first.toString();
- }
- setSecurityParamsInWifiConfiguration(wifiConfiguration);
- wifiConfiguration.hiddenSSID = mIsHiddenSSID;
- wifiConfiguration.priority = mPriority;
- wifiConfiguration.meteredOverride =
- mIsMetered ? WifiConfiguration.METERED_OVERRIDE_METERED
- : WifiConfiguration.METERED_OVERRIDE_NONE;
- return wifiConfiguration;
- }
-
- private boolean hasSetAnyPattern() {
- return mSsidPatternMatcher != null || mBssidPatternMatcher != null;
- }
-
- private void setMatchAnyPatternIfUnset() {
- if (mSsidPatternMatcher == null) {
- mSsidPatternMatcher = new PatternMatcher(MATCH_ALL_SSID_PATTERN_PATH,
- PatternMatcher.PATTERN_SIMPLE_GLOB);
- }
- if (mBssidPatternMatcher == null) {
- mBssidPatternMatcher = MATCH_ALL_BSSID_PATTERN;
- }
- }
-
- private boolean hasSetMatchNonePattern() {
- if (mSsidPatternMatcher.getType() != PatternMatcher.PATTERN_PREFIX
- && mSsidPatternMatcher.getPath().equals(MATCH_EMPTY_SSID_PATTERN_PATH)) {
- return true;
- }
- if (mBssidPatternMatcher.equals(MATCH_NO_BSSID_PATTERN1)) {
- return true;
- }
- if (mBssidPatternMatcher.equals(MATCH_NO_BSSID_PATTERN2)) {
- return true;
- }
- return false;
- }
-
- private boolean hasSetMatchAllPattern() {
- if ((mSsidPatternMatcher.match(MATCH_EMPTY_SSID_PATTERN_PATH))
- && mBssidPatternMatcher.equals(MATCH_ALL_BSSID_PATTERN)) {
- return true;
- }
- return false;
- }
-
- private boolean hasSetMatchExactPattern() {
- // exact ssid match with either match-all bssid or match-exact bssid.
- if (mSsidPatternMatcher.getType() == PatternMatcher.PATTERN_LITERAL
- && (mBssidPatternMatcher.equals(MATCH_ALL_BSSID_PATTERN)
- || mBssidPatternMatcher.second.equals(MATCH_EXACT_BSSID_PATTERN_MASK))) {
- return true;
- }
- return false;
- }
-
- private void validateSecurityParams() {
- int numSecurityTypes = 0;
- numSecurityTypes += mIsEnhancedOpen ? 1 : 0;
- numSecurityTypes += !TextUtils.isEmpty(mWpa2PskPassphrase) ? 1 : 0;
- numSecurityTypes += !TextUtils.isEmpty(mWpa3SaePassphrase) ? 1 : 0;
- numSecurityTypes += mWpa2EnterpriseConfig != null ? 1 : 0;
- numSecurityTypes += mWpa3EnterpriseConfig != null ? 1 : 0;
- if (numSecurityTypes > 1) {
- throw new IllegalStateException("only one of setIsEnhancedOpen, setWpa2Passphrase,"
- + "setWpa3Passphrase, setWpa2EnterpriseConfig or setWpa3EnterpriseConfig"
- + " can be invoked for network specifier");
- }
- }
-
- /**
- * Create a specifier object used to request a Wi-Fi network. The generated
- * {@link NetworkSpecifier} should be used in
- * {@link NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} when building
- * the {@link NetworkRequest}.
- *<p>
- * Note: Apps can set a combination of network match params:
- * <li> SSID Pattern using {@link #setSsidPattern(PatternMatcher)} OR Specific SSID using
- * {@link #setSsid(String)}. </li>
- * AND/OR
- * <li> BSSID Pattern using {@link #setBssidPattern(MacAddress, MacAddress)} OR Specific BSSID
- * using {@link #setBssid(MacAddress)} </li>
- * to trigger connection to a network that matches the set params.
- * The system will find the set of networks matching the request and present the user
- * with a system dialog which will allow the user to select a specific Wi-Fi network to connect
- * to or to deny the request.
- *</p>
- *
- * For example:
- * To connect to an open network with a SSID prefix of "test" and a BSSID OUI of "10:03:23":
- * {@code
- * final NetworkSpecifier specifier =
- * new WifiNetworkConfigBuilder()
- * .setSsidPattern(new PatternMatcher("test", PatterMatcher.PATTERN_PREFIX))
- * .setBssidPattern(MacAddress.fromString("10:03:23:00:00:00"),
- * MacAddress.fromString("ff:ff:ff:00:00:00"))
- * .buildNetworkSpecifier()
- * final NetworkRequest request =
- * new NetworkRequest.Builder()
- * .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
- * .setNetworkSpecifier(specifier)
- * .build();
- * final ConnectivityManager connectivityManager =
- * context.getSystemService(Context.CONNECTIVITY_SERVICE);
- * final NetworkCallback networkCallback = new NetworkCallback() {
- * ...
- * {@literal @}Override
- * void onAvailable(...) {}
- * // etc.
- * };
- * connectivityManager.requestNetwork(request, networkCallback);
- * }
- *
- * @return Instance of {@link NetworkSpecifier}.
- * @throws IllegalStateException on invalid params set.
- */
- public NetworkSpecifier buildNetworkSpecifier() {
- if (!hasSetAnyPattern()) {
- throw new IllegalStateException("one of setSsidPattern/setSsid/setBssidPattern/setBssid"
- + " should be invoked for specifier");
- }
- setMatchAnyPatternIfUnset();
- if (hasSetMatchNonePattern()) {
- throw new IllegalStateException("cannot set match-none pattern for specifier");
- }
- if (hasSetMatchAllPattern()) {
- throw new IllegalStateException("cannot set match-all pattern for specifier");
- }
- if (mIsHiddenSSID && mSsidPatternMatcher.getType() != PatternMatcher.PATTERN_LITERAL) {
- throw new IllegalStateException("setSsid should also be invoked when "
- + "setIsHiddenSsid is invoked for network specifier");
- }
- if (mIsAppInteractionRequired || mIsUserInteractionRequired
- || mPriority != -1 || mIsMetered) {
- throw new IllegalStateException("none of setIsAppInteractionRequired/"
- + "setIsUserInteractionRequired/setPriority/setIsMetered are allowed for "
- + "specifier");
- }
- validateSecurityParams();
-
- return new WifiNetworkSpecifier(
- mSsidPatternMatcher,
- mBssidPatternMatcher,
- buildWifiConfiguration(),
- Process.myUid(),
- ActivityThread.currentApplication().getApplicationContext().getOpPackageName());
- }
-
- /**
- * Create a network suggestion object use in {@link WifiManager#addNetworkSuggestions(List)}.
- * See {@link WifiNetworkSuggestion}.
- *<p>
- * Note: Apps can set a combination of SSID using {@link #setSsid(String)} and BSSID
- * using {@link #setBssid(MacAddress)} to provide more fine grained network suggestions to the
- * platform.
- * </p>
- *
- * For example:
- * To provide credentials for one open, one WPA2 and one WPA3 network with their
- * corresponding SSID's:
- * {@code
- * final WifiNetworkSuggestion suggestion1 =
- * new WifiNetworkConfigBuilder()
- * .setSsid("test111111")
- * .buildNetworkSuggestion()
- * final WifiNetworkSuggestion suggestion2 =
- * new WifiNetworkConfigBuilder()
- * .setSsid("test222222")
- * .setWpa2Passphrase("test123456")
- * .buildNetworkSuggestion()
- * final WifiNetworkSuggestion suggestion3 =
- * new WifiNetworkConfigBuilder()
- * .setSsid("test333333")
- * .setWpa3Passphrase("test6789")
- * .buildNetworkSuggestion()
- * final List<WifiNetworkSuggestion> suggestionsList = new ArrayList<WifiNetworkSuggestion> {{
- * add(suggestion1);
- * add(suggestion2);
- * add(suggestion3);
- * }};
- * final WifiManager wifiManager =
- * context.getSystemService(Context.WIFI_SERVICE);
- * wifiManager.addNetworkSuggestions(suggestionsList);
- * ...
- * }
- *
- * @return Instance of {@link WifiNetworkSuggestion}.
- * @throws IllegalStateException on invalid params set.
- */
- public WifiNetworkSuggestion buildNetworkSuggestion() {
- if (mSsidPatternMatcher == null) {
- throw new IllegalStateException("setSsid should be invoked for suggestion");
- }
- setMatchAnyPatternIfUnset();
- if (!hasSetMatchExactPattern()) {
- throw new IllegalStateException("none of setSsidPattern/setBssidPattern are"
- + " allowed for suggestion");
- }
- if (hasSetMatchNonePattern()) {
- throw new IllegalStateException("cannot set match-none for suggestion");
- }
- validateSecurityParams();
-
- return new WifiNetworkSuggestion(
- buildWifiConfiguration(),
- mIsAppInteractionRequired,
- mIsUserInteractionRequired,
- Process.myUid(),
- ActivityThread.currentApplication().getApplicationContext().getOpPackageName());
-
- }
-}
diff --git a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
index a5f4675..a69c7a5 100644
--- a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
+++ b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
@@ -19,31 +19,466 @@
import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityThread;
import android.net.MacAddress;
import android.net.MatchAllNetworkSpecifier;
+import android.net.NetworkRequest;
import android.net.NetworkSpecifier;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.PatternMatcher;
+import android.os.Process;
import android.text.TextUtils;
import android.util.Pair;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.StandardCharsets;
import java.util.Objects;
/**
- * Network specifier object used to request a Wi-Fi network. Apps should use the
- * {@link WifiNetworkConfigBuilder} class to create an instance.
- * @hide
+ * Network specifier object used to request a local Wi-Fi network. Apps should use the
+ * {@link WifiNetworkSpecifier.Builder} class to create an instance.
*/
public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parcelable {
+
+ /**
+ * Builder used to create {@link WifiNetworkSpecifier} objects.
+ */
+ public static class Builder {
+ private static final String MATCH_ALL_SSID_PATTERN_PATH = ".*";
+ private static final String MATCH_EMPTY_SSID_PATTERN_PATH = "";
+ private static final Pair<MacAddress, MacAddress> MATCH_NO_BSSID_PATTERN1 =
+ new Pair(MacAddress.BROADCAST_ADDRESS, MacAddress.BROADCAST_ADDRESS);
+ private static final Pair<MacAddress, MacAddress> MATCH_NO_BSSID_PATTERN2 =
+ new Pair(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.BROADCAST_ADDRESS);
+ private static final Pair<MacAddress, MacAddress> MATCH_ALL_BSSID_PATTERN =
+ new Pair(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
+ private static final MacAddress MATCH_EXACT_BSSID_PATTERN_MASK =
+ MacAddress.BROADCAST_ADDRESS;
+
+ /**
+ * SSID pattern match specified by the app.
+ */
+ private @Nullable PatternMatcher mSsidPatternMatcher;
+ /**
+ * BSSID pattern match specified by the app.
+ * Pair of <BaseAddress, Mask>.
+ */
+ private @Nullable Pair<MacAddress, MacAddress> mBssidPatternMatcher;
+ /**
+ * Whether this is an OWE network or not.
+ */
+ private boolean mIsEnhancedOpen;
+ /**
+ * Pre-shared key for use with WPA-PSK networks.
+ */
+ private @Nullable String mWpa2PskPassphrase;
+ /**
+ * Pre-shared key for use with WPA3-SAE networks.
+ */
+ private @Nullable String mWpa3SaePassphrase;
+ /**
+ * The enterprise configuration details specifying the EAP method,
+ * certificates and other settings associated with the WPA-EAP networks.
+ */
+ private @Nullable WifiEnterpriseConfig mWpa2EnterpriseConfig;
+ /**
+ * The enterprise configuration details specifying the EAP method,
+ * certificates and other settings associated with the SuiteB networks.
+ */
+ private @Nullable WifiEnterpriseConfig mWpa3EnterpriseConfig;
+ /**
+ * This is a network that does not broadcast its SSID, so an
+ * SSID-specific probe request must be used for scans.
+ */
+ private boolean mIsHiddenSSID;
+
+ public Builder() {
+ mSsidPatternMatcher = null;
+ mBssidPatternMatcher = null;
+ mIsEnhancedOpen = false;
+ mWpa2PskPassphrase = null;
+ mWpa3SaePassphrase = null;
+ mWpa2EnterpriseConfig = null;
+ mWpa3EnterpriseConfig = null;
+ mIsHiddenSSID = false;
+ }
+
+ /**
+ * Set the unicode SSID match pattern to use for filtering networks from scan results.
+ * <p>
+ * <li>Overrides any previous value set using {@link #setSsid(String)} or
+ * {@link #setSsidPattern(PatternMatcher)}.</li>
+ *
+ * @param ssidPattern Instance of {@link PatternMatcher} containing the UTF-8 encoded
+ * string pattern to use for matching the network's SSID.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public Builder setSsidPattern(@NonNull PatternMatcher ssidPattern) {
+ checkNotNull(ssidPattern);
+ mSsidPatternMatcher = ssidPattern;
+ return this;
+ }
+
+ /**
+ * Set the unicode SSID for the network.
+ * <p>
+ * <li>Sets the SSID to use for filtering networks from scan results. Will only match
+ * networks whose SSID is identical to the UTF-8 encoding of the specified value.</li>
+ * <li>Overrides any previous value set using {@link #setSsid(String)} or
+ * {@link #setSsidPattern(PatternMatcher)}.</li>
+ *
+ * @param ssid The SSID of the network. It must be valid Unicode.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ * @throws IllegalArgumentException if the SSID is not valid unicode.
+ */
+ public Builder setSsid(@NonNull String ssid) {
+ checkNotNull(ssid);
+ final CharsetEncoder unicodeEncoder = StandardCharsets.UTF_8.newEncoder();
+ if (!unicodeEncoder.canEncode(ssid)) {
+ throw new IllegalArgumentException("SSID is not a valid unicode string");
+ }
+ mSsidPatternMatcher = new PatternMatcher(ssid, PatternMatcher.PATTERN_LITERAL);
+ return this;
+ }
+
+ /**
+ * Set the BSSID match pattern to use for filtering networks from scan results.
+ * Will match all networks with BSSID which satisfies the following:
+ * {@code BSSID & mask == baseAddress}.
+ * <p>
+ * <li>Overrides any previous value set using {@link #setBssid(MacAddress)} or
+ * {@link #setBssidPattern(MacAddress, MacAddress)}.</li>
+ *
+ * @param baseAddress Base address for BSSID pattern.
+ * @param mask Mask for BSSID pattern.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public Builder setBssidPattern(
+ @NonNull MacAddress baseAddress, @NonNull MacAddress mask) {
+ checkNotNull(baseAddress, mask);
+ mBssidPatternMatcher = Pair.create(baseAddress, mask);
+ return this;
+ }
+
+ /**
+ * Set the BSSID to use for filtering networks from scan results. Will only match network
+ * whose BSSID is identical to the specified value.
+ * <p>
+ * <li>Sets the BSSID to use for filtering networks from scan results. Will only match
+ * networks whose BSSID is identical to specified value.</li>
+ * <li>Overrides any previous value set using {@link #setBssid(MacAddress)} or
+ * {@link #setBssidPattern(MacAddress, MacAddress)}.</li>
+ *
+ * @param bssid BSSID of the network.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public Builder setBssid(@NonNull MacAddress bssid) {
+ checkNotNull(bssid);
+ mBssidPatternMatcher = Pair.create(bssid, MATCH_EXACT_BSSID_PATTERN_MASK);
+ return this;
+ }
+
+ /**
+ * Specifies whether this represents an Enhanced Open (OWE) network.
+ *
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public Builder setIsEnhancedOpen() {
+ mIsEnhancedOpen = true;
+ return this;
+ }
+
+ /**
+ * Set the ASCII WPA2 passphrase for this network. Needed for authenticating to
+ * WPA2-PSK networks.
+ *
+ * @param passphrase passphrase of the network.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ * @throws IllegalArgumentException if the passphrase is not ASCII encodable.
+ */
+ public Builder setWpa2Passphrase(@NonNull String passphrase) {
+ checkNotNull(passphrase);
+ final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
+ if (!asciiEncoder.canEncode(passphrase)) {
+ throw new IllegalArgumentException("passphrase not ASCII encodable");
+ }
+ mWpa2PskPassphrase = passphrase;
+ return this;
+ }
+
+ /**
+ * Set the ASCII WPA3 passphrase for this network. Needed for authenticating to WPA3-SAE
+ * networks.
+ *
+ * @param passphrase passphrase of the network.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ * @throws IllegalArgumentException if the passphrase is not ASCII encodable.
+ */
+ public Builder setWpa3Passphrase(@NonNull String passphrase) {
+ checkNotNull(passphrase);
+ final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
+ if (!asciiEncoder.canEncode(passphrase)) {
+ throw new IllegalArgumentException("passphrase not ASCII encodable");
+ }
+ mWpa3SaePassphrase = passphrase;
+ return this;
+ }
+
+ /**
+ * Set the associated enterprise configuration for this network. Needed for authenticating
+ * to WPA2-EAP networks. See {@link WifiEnterpriseConfig} for description.
+ *
+ * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public Builder setWpa2EnterpriseConfig(
+ @NonNull WifiEnterpriseConfig enterpriseConfig) {
+ checkNotNull(enterpriseConfig);
+ mWpa2EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
+ return this;
+ }
+
+ /**
+ * Set the associated enterprise configuration for this network. Needed for authenticating
+ * to WPA3-SuiteB networks. See {@link WifiEnterpriseConfig} for description.
+ *
+ * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public Builder setWpa3EnterpriseConfig(
+ @NonNull WifiEnterpriseConfig enterpriseConfig) {
+ checkNotNull(enterpriseConfig);
+ mWpa3EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
+ return this;
+ }
+
+ /**
+ * Specifies whether this represents a hidden network.
+ * <p>
+ * <li>Setting this disallows the usage of {@link #setSsidPattern(PatternMatcher)} since
+ * hidden networks need to be explicitly probed for.</li>
+ * <li>If not set, defaults to false (i.e not a hidden network).</li>
+ *
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public Builder setIsHiddenSsid() {
+ mIsHiddenSSID = true;
+ return this;
+ }
+
+
+ /**
+ * Set defaults for the various low level credential type fields in the newly created
+ * WifiConfiguration object.
+ *
+ * See {@link com.android.server.wifi.WifiConfigManager#setDefaultsInWifiConfiguration(
+ * WifiConfiguration)}.
+ *
+ * @param configuration provided WifiConfiguration object.
+ */
+ private static void setDefaultsInWifiConfiguration(
+ @NonNull WifiConfiguration configuration) {
+ configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
+ configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
+ configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
+ configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
+ configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
+ }
+
+ private void setSecurityParamsInWifiConfiguration(
+ @NonNull WifiConfiguration configuration) {
+ if (!TextUtils.isEmpty(mWpa2PskPassphrase)) { // WPA-PSK network.
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ // WifiConfiguration.preSharedKey needs quotes around ASCII password.
+ configuration.preSharedKey = "\"" + mWpa2PskPassphrase + "\"";
+ } else if (!TextUtils.isEmpty(mWpa3SaePassphrase)) { // WPA3-SAE network.
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SAE);
+ // PMF mandatory for SAE.
+ configuration.requirePMF = true;
+ // WifiConfiguration.preSharedKey needs quotes around ASCII password.
+ configuration.preSharedKey = "\"" + mWpa3SaePassphrase + "\"";
+ } else if (mWpa2EnterpriseConfig != null) { // WPA-EAP network
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
+ configuration.enterpriseConfig = mWpa2EnterpriseConfig;
+ } else if (mWpa3EnterpriseConfig != null) { // WPA3-SuiteB network
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192);
+ configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
+ // TODO (b/113878056): Verify these params once we verify SuiteB configuration.
+ configuration.allowedGroupManagementCiphers.set(
+ WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256);
+ configuration.allowedSuiteBCiphers.set(
+ WifiConfiguration.SuiteBCipher.ECDHE_ECDSA);
+ configuration.allowedSuiteBCiphers.set(
+ WifiConfiguration.SuiteBCipher.ECDHE_RSA);
+ configuration.requirePMF = true;
+ configuration.enterpriseConfig = mWpa3EnterpriseConfig;
+ } else if (mIsEnhancedOpen) { // OWE network
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.OWE);
+ // PMF mandatory.
+ configuration.requirePMF = true;
+ } else { // Open network
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+ }
+ }
+
+ /**
+ * Helper method to build WifiConfiguration object from the builder.
+ * @return Instance of {@link WifiConfiguration}.
+ */
+ private WifiConfiguration buildWifiConfiguration() {
+ final WifiConfiguration wifiConfiguration = new WifiConfiguration();
+ setDefaultsInWifiConfiguration(wifiConfiguration);
+ // WifiConfiguration.SSID needs quotes around unicode SSID.
+ if (mSsidPatternMatcher.getType() == PatternMatcher.PATTERN_LITERAL) {
+ wifiConfiguration.SSID = "\"" + mSsidPatternMatcher.getPath() + "\"";
+ }
+ if (mBssidPatternMatcher.second == MATCH_EXACT_BSSID_PATTERN_MASK) {
+ wifiConfiguration.BSSID = mBssidPatternMatcher.first.toString();
+ }
+ setSecurityParamsInWifiConfiguration(wifiConfiguration);
+ wifiConfiguration.hiddenSSID = mIsHiddenSSID;
+ return wifiConfiguration;
+ }
+
+ private boolean hasSetAnyPattern() {
+ return mSsidPatternMatcher != null || mBssidPatternMatcher != null;
+ }
+
+ private void setMatchAnyPatternIfUnset() {
+ if (mSsidPatternMatcher == null) {
+ mSsidPatternMatcher = new PatternMatcher(MATCH_ALL_SSID_PATTERN_PATH,
+ PatternMatcher.PATTERN_SIMPLE_GLOB);
+ }
+ if (mBssidPatternMatcher == null) {
+ mBssidPatternMatcher = MATCH_ALL_BSSID_PATTERN;
+ }
+ }
+
+ private boolean hasSetMatchNonePattern() {
+ if (mSsidPatternMatcher.getType() != PatternMatcher.PATTERN_PREFIX
+ && mSsidPatternMatcher.getPath().equals(MATCH_EMPTY_SSID_PATTERN_PATH)) {
+ return true;
+ }
+ if (mBssidPatternMatcher.equals(MATCH_NO_BSSID_PATTERN1)) {
+ return true;
+ }
+ if (mBssidPatternMatcher.equals(MATCH_NO_BSSID_PATTERN2)) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean hasSetMatchAllPattern() {
+ if ((mSsidPatternMatcher.match(MATCH_EMPTY_SSID_PATTERN_PATH))
+ && mBssidPatternMatcher.equals(MATCH_ALL_BSSID_PATTERN)) {
+ return true;
+ }
+ return false;
+ }
+
+ private void validateSecurityParams() {
+ int numSecurityTypes = 0;
+ numSecurityTypes += mIsEnhancedOpen ? 1 : 0;
+ numSecurityTypes += !TextUtils.isEmpty(mWpa2PskPassphrase) ? 1 : 0;
+ numSecurityTypes += !TextUtils.isEmpty(mWpa3SaePassphrase) ? 1 : 0;
+ numSecurityTypes += mWpa2EnterpriseConfig != null ? 1 : 0;
+ numSecurityTypes += mWpa3EnterpriseConfig != null ? 1 : 0;
+ if (numSecurityTypes > 1) {
+ throw new IllegalStateException("only one of setIsEnhancedOpen, setWpa2Passphrase,"
+ + "setWpa3Passphrase, setWpa2EnterpriseConfig or setWpa3EnterpriseConfig"
+ + " can be invoked for network specifier");
+ }
+ }
+
+ /**
+ * Create a specifier object used to request a local Wi-Fi network. The generated
+ * {@link NetworkSpecifier} should be used in
+ * {@link NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} when building
+ * the {@link NetworkRequest}. These specifiers can only be used to request a local wifi
+ * network (i.e no internet capability). So, the device will not switch it's default route
+ * to wifi if there are other transports (cellular for example) available.
+ *<p>
+ * Note: Apps can set a combination of network match params:
+ * <li> SSID Pattern using {@link #setSsidPattern(PatternMatcher)} OR Specific SSID using
+ * {@link #setSsid(String)}. </li>
+ * AND/OR
+ * <li> BSSID Pattern using {@link #setBssidPattern(MacAddress, MacAddress)} OR Specific
+ * BSSID using {@link #setBssid(MacAddress)} </li>
+ * to trigger connection to a network that matches the set params.
+ * The system will find the set of networks matching the request and present the user
+ * with a system dialog which will allow the user to select a specific Wi-Fi network to
+ * connect to or to deny the request.
+ *</p>
+ *
+ * For example:
+ * To connect to an open network with a SSID prefix of "test" and a BSSID OUI of "10:03:23":
+ * {@code
+ * final NetworkSpecifier specifier =
+ * new Builder()
+ * .setSsidPattern(new PatternMatcher("test", PatterMatcher.PATTERN_PREFIX))
+ * .setBssidPattern(MacAddress.fromString("10:03:23:00:00:00"),
+ * MacAddress.fromString("ff:ff:ff:00:00:00"))
+ * .buildNetworkSpecifier()
+ * final NetworkRequest request =
+ * new NetworkRequest.Builder()
+ * .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+ * .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+ * .setNetworkSpecifier(specifier)
+ * .build();
+ * final ConnectivityManager connectivityManager =
+ * context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ * final NetworkCallback networkCallback = new NetworkCallback() {
+ * ...
+ * {@literal @}Override
+ * void onAvailable(...) {}
+ * // etc.
+ * };
+ * connectivityManager.requestNetwork(request, networkCallback);
+ * }
+ *
+ * @return Instance of {@link NetworkSpecifier}.
+ * @throws IllegalStateException on invalid params set.
+ */
+ public NetworkSpecifier build() {
+ if (!hasSetAnyPattern()) {
+ throw new IllegalStateException("one of setSsidPattern/setSsid/setBssidPattern/"
+ + "setBssid should be invoked for specifier");
+ }
+ setMatchAnyPatternIfUnset();
+ if (hasSetMatchNonePattern()) {
+ throw new IllegalStateException("cannot set match-none pattern for specifier");
+ }
+ if (hasSetMatchAllPattern()) {
+ throw new IllegalStateException("cannot set match-all pattern for specifier");
+ }
+ if (mIsHiddenSSID && mSsidPatternMatcher.getType() != PatternMatcher.PATTERN_LITERAL) {
+ throw new IllegalStateException("setSsid should also be invoked when "
+ + "setIsHiddenSsid is invoked for network specifier");
+ }
+ validateSecurityParams();
+
+ return new WifiNetworkSpecifier(
+ mSsidPatternMatcher,
+ mBssidPatternMatcher,
+ buildWifiConfiguration(),
+ Process.myUid(),
+ ActivityThread.currentApplication().getApplicationContext().getOpPackageName());
+ }
+ }
+
/**
* SSID pattern match specified by the app.
+ * @hide
*/
public final PatternMatcher ssidPatternMatcher;
/**
* BSSID pattern match specified by the app.
* Pair of <BaseAddress, Mask>.
+ * @hide
*/
public final Pair<MacAddress, MacAddress> bssidPatternMatcher;
@@ -54,6 +489,7 @@
* WifiConfiguration are not used. Instead we use the {@link #ssidPatternMatcher} &
* {@link #bssidPatternMatcher} fields embedded directly
* within {@link WifiNetworkSpecifier}.
+ * @hide
*/
public final WifiConfiguration wifiConfiguration;
@@ -61,18 +497,26 @@
* The UID of the process initializing this network specifier. Validated by receiver using
* checkUidIfNecessary() and is used by satisfiedBy() to determine whether the specifier
* matches the offered network.
+ * @hide
*/
public final int requestorUid;
/**
* The package name of the app initializing this network specifier.
+ * @hide
*/
public final String requestorPackageName;
+ /** @hide */
+ public WifiNetworkSpecifier() throws IllegalAccessException {
+ throw new IllegalAccessException("Use the builder to create an instance");
+ }
+
+ /** @hide */
public WifiNetworkSpecifier(@NonNull PatternMatcher ssidPatternMatcher,
- @NonNull Pair<MacAddress, MacAddress> bssidPatternMatcher,
- @NonNull WifiConfiguration wifiConfiguration,
- int requestorUid, @NonNull String requestorPackageName) {
+ @NonNull Pair<MacAddress, MacAddress> bssidPatternMatcher,
+ @NonNull WifiConfiguration wifiConfiguration,
+ int requestorUid, @NonNull String requestorPackageName) {
checkNotNull(ssidPatternMatcher);
checkNotNull(bssidPatternMatcher);
checkNotNull(wifiConfiguration);
@@ -123,23 +567,6 @@
}
@Override
- public boolean satisfiedBy(NetworkSpecifier other) {
- if (this == other) {
- return true;
- }
- // Any generic requests should be satisifed by a specific wifi network.
- if (other == null || other instanceof MatchAllNetworkSpecifier) {
- return true;
- }
- if (other instanceof WifiNetworkAgentSpecifier) {
- return ((WifiNetworkAgentSpecifier) other).satisfiesNetworkSpecifier(this);
- }
- // Specific requests are checked for equality although testing for equality of 2 patterns do
- // not make much sense!
- return equals(other);
- }
-
- @Override
public int hashCode() {
return Objects.hash(
ssidPatternMatcher.getPath(),
@@ -184,6 +611,25 @@
.toString();
}
+ /** @hide */
+ @Override
+ public boolean satisfiedBy(NetworkSpecifier other) {
+ if (this == other) {
+ return true;
+ }
+ // Any generic requests should be satisifed by a specific wifi network.
+ if (other == null || other instanceof MatchAllNetworkSpecifier) {
+ return true;
+ }
+ if (other instanceof WifiNetworkAgentSpecifier) {
+ return ((WifiNetworkAgentSpecifier) other).satisfiesNetworkSpecifier(this);
+ }
+ // Specific requests are checked for equality although testing for equality of 2 patterns do
+ // not make much sense!
+ return equals(other);
+ }
+
+ /** @hide */
@Override
public void assertValidFromUid(int requestorUid) {
if (this.requestorUid != requestorUid) {
diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
index 6b05dfc..460c633 100644
--- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
+++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
@@ -19,23 +19,449 @@
import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityThread;
+import android.net.MacAddress;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.Process;
import android.text.TextUtils;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;
/**
* The Network Suggestion object is used to provide a Wi-Fi network for consideration when
* auto-connecting to networks. Apps cannot directly create this object, they must use
- * {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} to obtain an instance
- * of this object.
+ * {@link WifiNetworkSuggestion.Builder#build()} to obtain an instance of this object.
*<p>
* Apps can provide a list of such networks to the platform using
* {@link WifiManager#addNetworkSuggestions(List)}.
*/
public final class WifiNetworkSuggestion implements Parcelable {
+
+ /**
+ * Builder used to create {@link WifiNetworkSuggestion} objects.
+ */
+ public static class Builder {
+ private static final int UNASSIGNED_PRIORITY = -1;
+
+ /**
+ * SSID of the network.
+ */
+ private String mSsid;
+ /**
+ * Optional BSSID within the network.
+ */
+ private MacAddress mBssid;
+ /**
+ * Whether this is an OWE network or not.
+ */
+ private boolean mIsEnhancedOpen;
+ /**
+ * Pre-shared key for use with WPA-PSK networks.
+ */
+ private @Nullable String mWpa2PskPassphrase;
+ /**
+ * Pre-shared key for use with WPA3-SAE networks.
+ */
+ private @Nullable String mWpa3SaePassphrase;
+ /**
+ * The enterprise configuration details specifying the EAP method,
+ * certificates and other settings associated with the WPA-EAP networks.
+ */
+ private @Nullable WifiEnterpriseConfig mWpa2EnterpriseConfig;
+ /**
+ * The enterprise configuration details specifying the EAP method,
+ * certificates and other settings associated with the SuiteB networks.
+ */
+ private @Nullable WifiEnterpriseConfig mWpa3EnterpriseConfig;
+ /**
+ * This is a network that does not broadcast its SSID, so an
+ * SSID-specific probe request must be used for scans.
+ */
+ private boolean mIsHiddenSSID;
+ /**
+ * Whether app needs to log in to captive portal to obtain Internet access.
+ */
+ private boolean mIsAppInteractionRequired;
+ /**
+ * Whether user needs to log in to captive portal to obtain Internet access.
+ */
+ private boolean mIsUserInteractionRequired;
+ /**
+ * Whether this network is metered or not.
+ */
+ private boolean mIsMetered;
+ /**
+ * Priority of this network among other network suggestions provided by the app.
+ * The lower the number, the higher the priority (i.e value of 0 = highest priority).
+ */
+ private int mPriority;
+
+ public Builder() {
+ mSsid = null;
+ mBssid = null;
+ mIsEnhancedOpen = false;
+ mWpa2PskPassphrase = null;
+ mWpa3SaePassphrase = null;
+ mWpa2EnterpriseConfig = null;
+ mWpa3EnterpriseConfig = null;
+ mIsHiddenSSID = false;
+ mIsAppInteractionRequired = false;
+ mIsUserInteractionRequired = false;
+ mIsMetered = false;
+ mPriority = UNASSIGNED_PRIORITY;
+ }
+
+ /**
+ * Set the unicode SSID for the network.
+ * <p>
+ * <li>Overrides any previous value set using {@link #setSsid(String)}.</li>
+ *
+ * @param ssid The SSID of the network. It must be valid Unicode.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ * @throws IllegalArgumentException if the SSID is not valid unicode.
+ */
+ public Builder setSsid(@NonNull String ssid) {
+ checkNotNull(ssid);
+ final CharsetEncoder unicodeEncoder = StandardCharsets.UTF_8.newEncoder();
+ if (!unicodeEncoder.canEncode(ssid)) {
+ throw new IllegalArgumentException("SSID is not a valid unicode string");
+ }
+ mSsid = new String(ssid);
+ return this;
+ }
+
+ /**
+ * Set the BSSID to use for filtering networks from scan results. Will only match network
+ * whose BSSID is identical to the specified value.
+ * <p>
+ * <li Sets a specific BSSID for the network suggestion. If set, only the specified BSSID
+ * with the specified SSID will be considered for connection.
+ * <li>If set, only the specified BSSID with the specified SSID will be considered for
+ * connection.</li>
+ * <li>If not set, all BSSIDs with the specified SSID will be considered for connection.
+ * </li>
+ * <li>Overrides any previous value set using {@link #setBssid(MacAddress)}.</li>
+ *
+ * @param bssid BSSID of the network.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public Builder setBssid(@NonNull MacAddress bssid) {
+ checkNotNull(bssid);
+ mBssid = MacAddress.fromBytes(bssid.toByteArray());
+ return this;
+ }
+
+ /**
+ * Specifies whether this represents an Enhanced Open (OWE) network.
+ *
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public Builder setIsEnhancedOpen() {
+ mIsEnhancedOpen = true;
+ return this;
+ }
+
+ /**
+ * Set the ASCII WPA2 passphrase for this network. Needed for authenticating to
+ * WPA2-PSK networks.
+ *
+ * @param passphrase passphrase of the network.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ * @throws IllegalArgumentException if the passphrase is not ASCII encodable.
+ */
+ public Builder setWpa2Passphrase(@NonNull String passphrase) {
+ checkNotNull(passphrase);
+ final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
+ if (!asciiEncoder.canEncode(passphrase)) {
+ throw new IllegalArgumentException("passphrase not ASCII encodable");
+ }
+ mWpa2PskPassphrase = passphrase;
+ return this;
+ }
+
+ /**
+ * Set the ASCII WPA3 passphrase for this network. Needed for authenticating to WPA3-SAE
+ * networks.
+ *
+ * @param passphrase passphrase of the network.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ * @throws IllegalArgumentException if the passphrase is not ASCII encodable.
+ */
+ public Builder setWpa3Passphrase(@NonNull String passphrase) {
+ checkNotNull(passphrase);
+ final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
+ if (!asciiEncoder.canEncode(passphrase)) {
+ throw new IllegalArgumentException("passphrase not ASCII encodable");
+ }
+ mWpa3SaePassphrase = passphrase;
+ return this;
+ }
+
+ /**
+ * Set the associated enterprise configuration for this network. Needed for authenticating
+ * to WPA2-EAP networks. See {@link WifiEnterpriseConfig} for description.
+ *
+ * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public Builder setWpa2EnterpriseConfig(
+ @NonNull WifiEnterpriseConfig enterpriseConfig) {
+ checkNotNull(enterpriseConfig);
+ mWpa2EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
+ return this;
+ }
+
+ /**
+ * Set the associated enterprise configuration for this network. Needed for authenticating
+ * to WPA3-SuiteB networks. See {@link WifiEnterpriseConfig} for description.
+ *
+ * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public Builder setWpa3EnterpriseConfig(
+ @NonNull WifiEnterpriseConfig enterpriseConfig) {
+ checkNotNull(enterpriseConfig);
+ mWpa3EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
+ return this;
+ }
+
+ /**
+ * Specifies whether this represents a hidden network.
+ * <p>
+ * <li>If not set, defaults to false (i.e not a hidden network).</li>
+ *
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public Builder setIsHiddenSsid() {
+ mIsHiddenSSID = true;
+ return this;
+ }
+
+ /**
+ * Specifies whether the app needs to log in to a captive portal to obtain Internet access.
+ * <p>
+ * This will dictate if the directed broadcast
+ * {@link WifiManager#ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION} will be sent to the
+ * app after successfully connecting to the network.
+ * Use this for captive portal type networks where the app needs to authenticate the user
+ * before the device can access the network.
+ * <p>
+ * <li>If not set, defaults to false (i.e no app interaction required).</li>
+ *
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public Builder setIsAppInteractionRequired() {
+ mIsAppInteractionRequired = true;
+ return this;
+ }
+
+ /**
+ * Specifies whether the user needs to log in to a captive portal to obtain Internet access.
+ * <p>
+ * <li>If not set, defaults to false (i.e no user interaction required).</li>
+ *
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public Builder setIsUserInteractionRequired() {
+ mIsUserInteractionRequired = true;
+ return this;
+ }
+
+ /**
+ * Specify the priority of this network among other network suggestions provided by the same
+ * app (priorities have no impact on suggestions by different apps). The lower the number,
+ * the higher the priority (i.e value of 0 = highest priority).
+ * <p>
+ * <li>If not set, defaults to -1 (i.e unassigned priority).</li>
+ *
+ * @param priority Integer number representing the priority among suggestions by the app.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ * @throws IllegalArgumentException if the priority value is negative.
+ */
+ public Builder setPriority(int priority) {
+ if (priority < 0) {
+ throw new IllegalArgumentException("Invalid priority value " + priority);
+ }
+ mPriority = priority;
+ return this;
+ }
+
+ /**
+ * Specifies whether this network is metered.
+ * <p>
+ * <li>If not set, defaults to false (i.e not metered).</li>
+ *
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public Builder setIsMetered() {
+ mIsMetered = true;
+ return this;
+ }
+
+ /**
+ * Set defaults for the various low level credential type fields in the newly created
+ * WifiConfiguration object.
+ *
+ * See {@link com.android.server.wifi.WifiConfigManager#setDefaultsInWifiConfiguration(
+ * WifiConfiguration)}.
+ *
+ * @param configuration provided WifiConfiguration object.
+ */
+ private static void setDefaultsInWifiConfiguration(
+ @NonNull WifiConfiguration configuration) {
+ configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
+ configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
+ configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
+ configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
+ configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
+ }
+
+ private void setSecurityParamsInWifiConfiguration(
+ @NonNull WifiConfiguration configuration) {
+ if (!TextUtils.isEmpty(mWpa2PskPassphrase)) { // WPA-PSK network.
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ // WifiConfiguration.preSharedKey needs quotes around ASCII password.
+ configuration.preSharedKey = "\"" + mWpa2PskPassphrase + "\"";
+ } else if (!TextUtils.isEmpty(mWpa3SaePassphrase)) { // WPA3-SAE network.
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SAE);
+ // PMF mandatory for SAE.
+ configuration.requirePMF = true;
+ // WifiConfiguration.preSharedKey needs quotes around ASCII password.
+ configuration.preSharedKey = "\"" + mWpa3SaePassphrase + "\"";
+ } else if (mWpa2EnterpriseConfig != null) { // WPA-EAP network
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
+ configuration.enterpriseConfig = mWpa2EnterpriseConfig;
+ } else if (mWpa3EnterpriseConfig != null) { // WPA3-SuiteB network
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192);
+ configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
+ // TODO (b/113878056): Verify these params once we verify SuiteB configuration.
+ configuration.allowedGroupManagementCiphers.set(
+ WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256);
+ configuration.allowedSuiteBCiphers.set(
+ WifiConfiguration.SuiteBCipher.ECDHE_ECDSA);
+ configuration.allowedSuiteBCiphers.set(
+ WifiConfiguration.SuiteBCipher.ECDHE_RSA);
+ configuration.requirePMF = true;
+ configuration.enterpriseConfig = mWpa3EnterpriseConfig;
+ } else if (mIsEnhancedOpen) { // OWE network
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.OWE);
+ // PMF mandatory.
+ configuration.requirePMF = true;
+ } else { // Open network
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+ }
+ }
+
+ /**
+ * Helper method to build WifiConfiguration object from the builder.
+ * @return Instance of {@link WifiConfiguration}.
+ */
+ private WifiConfiguration buildWifiConfiguration() {
+ final WifiConfiguration wifiConfiguration = new WifiConfiguration();
+ setDefaultsInWifiConfiguration(wifiConfiguration);
+ // WifiConfiguration.SSID needs quotes around unicode SSID.
+ wifiConfiguration.SSID = "\"" + mSsid + "\"";
+ if (mBssid != null) {
+ wifiConfiguration.BSSID = mBssid.toString();
+ }
+
+ setSecurityParamsInWifiConfiguration(wifiConfiguration);
+
+ wifiConfiguration.hiddenSSID = mIsHiddenSSID;
+ wifiConfiguration.priority = mPriority;
+ wifiConfiguration.meteredOverride =
+ mIsMetered ? WifiConfiguration.METERED_OVERRIDE_METERED
+ : WifiConfiguration.METERED_OVERRIDE_NONE;
+ return wifiConfiguration;
+ }
+
+ private void validateSecurityParams() {
+ int numSecurityTypes = 0;
+ numSecurityTypes += mIsEnhancedOpen ? 1 : 0;
+ numSecurityTypes += !TextUtils.isEmpty(mWpa2PskPassphrase) ? 1 : 0;
+ numSecurityTypes += !TextUtils.isEmpty(mWpa3SaePassphrase) ? 1 : 0;
+ numSecurityTypes += mWpa2EnterpriseConfig != null ? 1 : 0;
+ numSecurityTypes += mWpa3EnterpriseConfig != null ? 1 : 0;
+ if (numSecurityTypes > 1) {
+ throw new IllegalStateException("only one of setIsEnhancedOpen, setWpa2Passphrase,"
+ + "setWpa3Passphrase, setWpa2EnterpriseConfig or setWpa3EnterpriseConfig"
+ + " can be invoked for network specifier");
+ }
+ }
+
+ /**
+ * Create a network suggestion object use in
+ * {@link WifiManager#addNetworkSuggestions(List)}.
+ *
+ * See {@link WifiNetworkSuggestion}.
+ *<p>
+ * Note: Apps can set a combination of SSID using {@link #setSsid(String)} and BSSID
+ * using {@link #setBssid(MacAddress)} to provide more fine grained network suggestions to
+ * the platform.
+ * </p>
+ *
+ * For example:
+ * To provide credentials for one open, one WPA2 and one WPA3 network with their
+ * corresponding SSID's:
+ * {@code
+ * final WifiNetworkSuggestion suggestion1 =
+ * new Builder()
+ * .setSsid("test111111")
+ * .buildNetworkSuggestion()
+ * final WifiNetworkSuggestion suggestion2 =
+ * new Builder()
+ * .setSsid("test222222")
+ * .setWpa2Passphrase("test123456")
+ * .buildNetworkSuggestion()
+ * final WifiNetworkSuggestion suggestion3 =
+ * new Builder()
+ * .setSsid("test333333")
+ * .setWpa3Passphrase("test6789")
+ * .buildNetworkSuggestion()
+ * final List<WifiNetworkSuggestion> suggestionsList =
+ * new ArrayList<WifiNetworkSuggestion> {{
+ * add(suggestion1);
+ * add(suggestion2);
+ * add(suggestion3);
+ * }};
+ * final WifiManager wifiManager =
+ * context.getSystemService(Context.WIFI_SERVICE);
+ * wifiManager.addNetworkSuggestions(suggestionsList);
+ * ...
+ * }
+ *
+ * @return Instance of {@link WifiNetworkSuggestion}.
+ * @throws IllegalStateException on invalid params set.
+ */
+ public WifiNetworkSuggestion build() {
+ if (mSsid == null) {
+ throw new IllegalStateException("setSsid should be invoked for suggestion");
+ }
+ if (TextUtils.isEmpty(mSsid)) {
+ throw new IllegalStateException("invalid ssid for suggestion");
+ }
+ if (mBssid != null
+ && (mBssid.equals(MacAddress.BROADCAST_ADDRESS)
+ || mBssid.equals(MacAddress.ALL_ZEROS_ADDRESS))) {
+ throw new IllegalStateException("invalid bssid for suggestion");
+ }
+ validateSecurityParams();
+
+ return new WifiNetworkSuggestion(
+ buildWifiConfiguration(),
+ mIsAppInteractionRequired,
+ mIsUserInteractionRequired,
+ Process.myUid(),
+ ActivityThread.currentApplication().getApplicationContext().getOpPackageName());
+ }
+ }
+
/**
* Network configuration for the provided network.
* @hide
@@ -67,6 +493,15 @@
public final String suggestorPackageName;
/** @hide */
+ public WifiNetworkSuggestion() {
+ this.wifiConfiguration = null;
+ this.isAppInteractionRequired = false;
+ this.isUserInteractionRequired = false;
+ this.suggestorUid = -1;
+ this.suggestorPackageName = null;
+ }
+
+ /** @hide */
public WifiNetworkSuggestion(@NonNull WifiConfiguration wifiConfiguration,
boolean isAppInteractionRequired,
boolean isUserInteractionRequired,
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkConfigBuilderTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkConfigBuilderTest.java
deleted file mode 100644
index dd6e2c9..0000000
--- a/wifi/tests/src/android/net/wifi/WifiNetworkConfigBuilderTest.java
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
- * Copyright (C) 2018 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 android.os.PatternMatcher.PATTERN_LITERAL;
-import static android.os.PatternMatcher.PATTERN_PREFIX;
-import static android.os.PatternMatcher.PATTERN_SIMPLE_GLOB;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import android.net.MacAddress;
-import android.net.NetworkSpecifier;
-import android.os.PatternMatcher;
-import android.os.Process;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Unit tests for {@link android.net.wifi.WifiNetworkConfigBuilder}.
- */
-@SmallTest
-public class WifiNetworkConfigBuilderTest {
- private static final String TEST_SSID = "Test123";
- private static final String TEST_BSSID_OUI_BASE_ADDRESS = "12:12:12:00:00:00";
- private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00";
- private static final String TEST_BSSID = "12:12:12:12:12:12";
- private static final String TEST_PRESHARED_KEY = "Test123";
-
- /**
- * Validate correctness of WifiNetworkSpecifier object created by
- * {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for open network with SSID pattern.
- */
- @Test
- public void testWifiNetworkSpecifierBuilderForOpenNetworkWithSsidPattern() {
- NetworkSpecifier specifier = new WifiNetworkConfigBuilder()
- .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_PREFIX))
- .buildNetworkSpecifier();
-
- assertTrue(specifier instanceof WifiNetworkSpecifier);
- WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
-
- assertEquals(Process.myUid(), wifiNetworkSpecifier.requestorUid);
- assertEquals(TEST_SSID, wifiNetworkSpecifier.ssidPatternMatcher.getPath());
- assertEquals(PATTERN_PREFIX, wifiNetworkSpecifier.ssidPatternMatcher.getType());
- assertEquals(MacAddress.ALL_ZEROS_ADDRESS, wifiNetworkSpecifier.bssidPatternMatcher.first);
- assertEquals(MacAddress.ALL_ZEROS_ADDRESS, wifiNetworkSpecifier.bssidPatternMatcher.second);
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.NONE));
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedProtocols
- .get(WifiConfiguration.Protocol.RSN));
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedAuthAlgorithms
- .get(WifiConfiguration.AuthAlgorithm.OPEN));
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedPairwiseCiphers
- .get(WifiConfiguration.PairwiseCipher.CCMP));
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
- .get(WifiConfiguration.GroupCipher.CCMP));
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
- .get(WifiConfiguration.GroupCipher.TKIP));
- }
-
- /**
- * Validate correctness of WifiNetworkSpecifier object created by
- * {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for WPA_PSK network with BSSID
- * pattern.
- */
- @Test
- public void testWifiNetworkSpecifierBuilderForWpa2PskNetworkWithBssidPattern() {
- NetworkSpecifier specifier = new WifiNetworkConfigBuilder()
- .setBssidPattern(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
- MacAddress.fromString(TEST_BSSID_OUI_MASK))
- .setWpa2Passphrase(TEST_PRESHARED_KEY)
- .buildNetworkSpecifier();
-
- assertTrue(specifier instanceof WifiNetworkSpecifier);
- WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
-
- assertEquals(".*", wifiNetworkSpecifier.ssidPatternMatcher.getPath());
- assertEquals(PATTERN_SIMPLE_GLOB, wifiNetworkSpecifier.ssidPatternMatcher.getType());
- assertEquals(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
- wifiNetworkSpecifier.bssidPatternMatcher.first);
- assertEquals(MacAddress.fromString(TEST_BSSID_OUI_MASK),
- wifiNetworkSpecifier.bssidPatternMatcher.second);
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.WPA_PSK));
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedProtocols
- .get(WifiConfiguration.Protocol.RSN));
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedAuthAlgorithms
- .get(WifiConfiguration.AuthAlgorithm.OPEN));
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedPairwiseCiphers
- .get(WifiConfiguration.PairwiseCipher.CCMP));
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
- .get(WifiConfiguration.GroupCipher.CCMP));
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
- .get(WifiConfiguration.GroupCipher.TKIP));
- assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
- wifiNetworkSpecifier.wifiConfiguration.preSharedKey);
- }
-
- /**
- * Validate correctness of WifiNetworkSpecifier object created by
- * {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for WPA_EAP network with
- * SSID and BSSID pattern.
- */
- @Test
- public void testWifiNetworkSpecifierBuilderForWpa2EapHiddenNetworkWithSsidAndBssid() {
- WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
- enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
- enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
-
- NetworkSpecifier specifier = new WifiNetworkConfigBuilder()
- .setSsid(TEST_SSID)
- .setBssid(MacAddress.fromString(TEST_BSSID))
- .setWpa2EnterpriseConfig(enterpriseConfig)
- .setIsHiddenSsid()
- .buildNetworkSpecifier();
-
- assertTrue(specifier instanceof WifiNetworkSpecifier);
- WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
-
- assertEquals(TEST_SSID, wifiNetworkSpecifier.ssidPatternMatcher.getPath());
- assertEquals(PATTERN_LITERAL, wifiNetworkSpecifier.ssidPatternMatcher.getType());
- assertEquals(MacAddress.fromString(TEST_BSSID),
- wifiNetworkSpecifier.bssidPatternMatcher.first);
- assertEquals(MacAddress.BROADCAST_ADDRESS,
- wifiNetworkSpecifier.bssidPatternMatcher.second);
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.WPA_EAP));
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.IEEE8021X));
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedProtocols
- .get(WifiConfiguration.Protocol.RSN));
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedAuthAlgorithms
- .get(WifiConfiguration.AuthAlgorithm.OPEN));
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedPairwiseCiphers
- .get(WifiConfiguration.PairwiseCipher.CCMP));
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
- .get(WifiConfiguration.GroupCipher.CCMP));
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
- .get(WifiConfiguration.GroupCipher.TKIP));
- assertTrue(wifiNetworkSpecifier.wifiConfiguration.hiddenSSID);
- assertEquals(enterpriseConfig.getEapMethod(),
- wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig.getEapMethod());
- assertEquals(enterpriseConfig.getPhase2Method(),
- wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig.getPhase2Method());
- }
-
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#setSsid(String)} throws an exception
- * when the string is not Unicode.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testSetSsidWithNonUnicodeString() {
- new WifiNetworkConfigBuilder()
- .setSsid("\ud800")
- .buildNetworkSpecifier();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#setWpa2Passphrase(String)} throws an exception
- * when the string is not ASCII encodable.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testSetWpa2PasphraseWithNonAsciiString() {
- new WifiNetworkConfigBuilder()
- .setSsid(TEST_SSID)
- .setWpa2Passphrase("salvē")
- .buildNetworkSpecifier();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
- * when neither SSID nor BSSID patterns were set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithNoSsidAndBssidPattern() {
- new WifiNetworkConfigBuilder().buildNetworkSpecifier();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
- * when match-all SSID pattern is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithMatchAllSsidPattern1() {
- new WifiNetworkConfigBuilder()
- .setSsidPattern(new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB))
- .buildNetworkSpecifier();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
- * when match-all SSID pattern is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithMatchAllSsidPattern2() {
- new WifiNetworkConfigBuilder()
- .setSsidPattern(new PatternMatcher(".*", PatternMatcher.PATTERN_ADVANCED_GLOB))
- .buildNetworkSpecifier();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
- * when match-all SSID pattern is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithMatchAllSsidPattern3() {
- new WifiNetworkConfigBuilder()
- .setSsidPattern(new PatternMatcher("", PatternMatcher.PATTERN_PREFIX))
- .buildNetworkSpecifier();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
- * when match-all BSSID pattern is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithMatchAllBssidPattern() {
- new WifiNetworkConfigBuilder()
- .setBssidPattern(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS)
- .buildNetworkSpecifier();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
- * when match-none SSID pattern is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithMatchNoneSsidPattern1() {
- new WifiNetworkConfigBuilder()
- .setSsidPattern(new PatternMatcher("", PatternMatcher.PATTERN_LITERAL))
- .buildNetworkSpecifier();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
- * when match-none SSID pattern is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithMatchNoneSsidPattern2() {
- new WifiNetworkConfigBuilder()
- .setSsid("")
- .buildNetworkSpecifier();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
- * when match-none BSSID pattern is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithMatchNoneBssidPattern1() {
- new WifiNetworkConfigBuilder()
- .setBssidPattern(MacAddress.BROADCAST_ADDRESS, MacAddress.BROADCAST_ADDRESS)
- .buildNetworkSpecifier();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
- * when match-none BSSID pattern is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithMatchNoneBssidPattern2() {
- new WifiNetworkConfigBuilder()
- .setBssid(MacAddress.BROADCAST_ADDRESS)
- .buildNetworkSpecifier();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
- * when match-none BSSID pattern is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithMatchNoneBssidPattern3() {
- new WifiNetworkConfigBuilder()
- .setBssid(MacAddress.ALL_ZEROS_ADDRESS)
- .buildNetworkSpecifier();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
- * when SSID pattern is set for hidden network.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithBssidMatchPatternForHiddenNetwork() {
- new WifiNetworkConfigBuilder()
- .setBssidPattern(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
- MacAddress.fromString(TEST_BSSID_OUI_MASK))
- .setIsHiddenSsid()
- .buildNetworkSpecifier();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
- * when both {@link WifiNetworkConfigBuilder#setWpa2Passphrase(String)} and
- * {@link WifiNetworkConfigBuilder#setWpa2EnterpriseConfig(WifiEnterpriseConfig)} are invoked.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithBothWpa2PasphraseAndEnterpriseConfig() {
- new WifiNetworkConfigBuilder()
- .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
- .setWpa2Passphrase(TEST_PRESHARED_KEY)
- .setWpa2EnterpriseConfig(new WifiEnterpriseConfig())
- .buildNetworkSpecifier();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
- * when SSID pattern is set for hidden network.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithSsidMatchPatternForHiddenNetwork() {
- new WifiNetworkConfigBuilder()
- .setSsidPattern(new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_PREFIX))
- .setIsHiddenSsid()
- .buildNetworkSpecifier();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
- * when {@link WifiNetworkConfigBuilder#setIsAppInteractionRequired()} is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithRequiredAppInteraction() {
- new WifiNetworkConfigBuilder()
- .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
- .setIsAppInteractionRequired()
- .buildNetworkSpecifier();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
- * when {@link WifiNetworkConfigBuilder#setIsUserInteractionRequired()} is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithRequiredUserInteraction() {
- new WifiNetworkConfigBuilder()
- .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
- .setIsUserInteractionRequired()
- .buildNetworkSpecifier();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
- * when {@link WifiNetworkConfigBuilder#setPriority(int)} is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithSetPriority() {
- new WifiNetworkConfigBuilder()
- .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
- .setPriority(4)
- .buildNetworkSpecifier();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
- * when {@link WifiNetworkConfigBuilder#setIsMetered()} is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithMetered() {
- new WifiNetworkConfigBuilder()
- .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
- .setIsMetered()
- .buildNetworkSpecifier();
- }
-
- /**
- * Validate correctness of WifiNetworkSuggestion object created by
- * {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} for Open network which requires
- * app interaction.
- */
- @Test
- public void testWifiNetworkSuggestionBuilderForOpenNetworkWithReqAppInteraction() {
- WifiNetworkSuggestion suggestion = new WifiNetworkConfigBuilder()
- .setSsid(TEST_SSID)
- .setIsAppInteractionRequired()
- .buildNetworkSuggestion();
-
- assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
- assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.NONE));
- assertTrue(suggestion.isAppInteractionRequired);
- assertFalse(suggestion.isUserInteractionRequired);
- assertEquals(WifiConfiguration.METERED_OVERRIDE_NONE,
- suggestion.wifiConfiguration.meteredOverride);
- assertEquals(-1, suggestion.wifiConfiguration.priority);
- }
-
- /**
- * Validate correctness of WifiNetworkSuggestion object created by
- * {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} for WPA_EAP network which requires
- * app interaction and has a priority of zero set.
- */
- @Test
- public void
- testWifiNetworkSuggestionBuilderForWpa2EapNetworkWithPriorityAndReqAppInteraction() {
- WifiNetworkSuggestion suggestion = new WifiNetworkConfigBuilder()
- .setSsid(TEST_SSID)
- .setWpa2Passphrase(TEST_PRESHARED_KEY)
- .setIsAppInteractionRequired()
- .setPriority(0)
- .buildNetworkSuggestion();
-
- assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
- assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.WPA_PSK));
- assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
- suggestion.wifiConfiguration.preSharedKey);
- assertTrue(suggestion.isAppInteractionRequired);
- assertFalse(suggestion.isUserInteractionRequired);
- assertEquals(WifiConfiguration.METERED_OVERRIDE_NONE,
- suggestion.wifiConfiguration.meteredOverride);
- assertEquals(0, suggestion.wifiConfiguration.priority);
- }
-
- /**
- * Validate correctness of WifiNetworkSuggestion object created by
- * {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} for WPA_PSK network which requires
- * user interaction and is metered.
- */
- @Test
- public void
- testWifiNetworkSuggestionBuilderForWpa2PskNetworkWithMeteredAndReqUserInteraction() {
- WifiNetworkSuggestion suggestion = new WifiNetworkConfigBuilder()
- .setSsid(TEST_SSID)
- .setWpa2Passphrase(TEST_PRESHARED_KEY)
- .setIsUserInteractionRequired()
- .setIsMetered()
- .buildNetworkSuggestion();
-
- assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
- assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.WPA_PSK));
- assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
- suggestion.wifiConfiguration.preSharedKey);
- assertFalse(suggestion.isAppInteractionRequired);
- assertTrue(suggestion.isUserInteractionRequired);
- assertEquals(WifiConfiguration.METERED_OVERRIDE_METERED,
- suggestion.wifiConfiguration.meteredOverride);
- assertEquals(-1, suggestion.wifiConfiguration.priority);
- }
-
- /**
- * Validate correctness of WifiNetworkSuggestion object created by
- * {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} for OWE network.
- */
- @Test
- public void testWifiNetworkSuggestionBuilderForEnhancedOpenNetworkWithBssid() {
- WifiNetworkSuggestion suggestion = new WifiNetworkConfigBuilder()
- .setSsid(TEST_SSID)
- .setBssid(MacAddress.fromString(TEST_BSSID))
- .setIsEnhancedOpen()
- .buildNetworkSuggestion();
-
- assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
- assertEquals(TEST_BSSID, suggestion.wifiConfiguration.BSSID);
- assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.OWE));
- assertNull(suggestion.wifiConfiguration.preSharedKey);
- assertTrue(suggestion.wifiConfiguration.requirePMF);
- }
-
- /**
- * Validate correctness of WifiNetworkSuggestion object created by
- * {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} for SAE network.
- */
- @Test
- public void testWifiNetworkSuggestionBuilderForWpa3PskNetwork() {
- WifiNetworkSuggestion suggestion = new WifiNetworkConfigBuilder()
- .setSsid(TEST_SSID)
- .setWpa3Passphrase(TEST_PRESHARED_KEY)
- .buildNetworkSuggestion();
-
- assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
- assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.SAE));
- assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
- suggestion.wifiConfiguration.preSharedKey);
- assertTrue(suggestion.wifiConfiguration.requirePMF);
- }
-
-
- /**
- * Validate correctness of WifiNetworkSuggestion object created by
- * {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} for SuiteB network.
- */
- @Test
- public void testWifiNetworkSuggestionBuilderForWpa3EapNetwork() {
- WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
- enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
- enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
-
- WifiNetworkSuggestion suggestion = new WifiNetworkConfigBuilder()
- .setSsid(TEST_SSID)
- .setWpa3EnterpriseConfig(enterpriseConfig)
- .buildNetworkSuggestion();
-
- assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
- assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.SUITE_B_192));
- assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers
- .get(WifiConfiguration.GroupCipher.GCMP_256));
- assertTrue(suggestion.wifiConfiguration.allowedGroupManagementCiphers
- .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256));
- assertTrue(suggestion.wifiConfiguration.allowedSuiteBCiphers
- .get(WifiConfiguration.SuiteBCipher.ECDHE_ECDSA));
- assertTrue(suggestion.wifiConfiguration.allowedSuiteBCiphers
- .get(WifiConfiguration.SuiteBCipher.ECDHE_RSA));
- assertTrue(suggestion.wifiConfiguration.requirePMF);
- assertNull(suggestion.wifiConfiguration.preSharedKey);
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} throws an exception
- * when {@link WifiNetworkConfigBuilder#setSsidPattern(PatternMatcher)} is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSuggestionBuilderWithSsidPattern() {
- new WifiNetworkConfigBuilder()
- .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_PREFIX))
- .buildNetworkSuggestion();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} throws an exception
- * when {@link WifiNetworkConfigBuilder#setBssidPattern(MacAddress, MacAddress)} is set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSuggestionBuilderWithBssidPattern() {
- new WifiNetworkConfigBuilder()
- .setSsid(TEST_SSID)
- .setBssidPattern(MacAddress.fromString(TEST_BSSID),
- MacAddress.fromString(TEST_BSSID))
- .buildNetworkSuggestion();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} throws an exception
- * when {@link WifiNetworkConfigBuilder#setSsid(String)} is not set.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSuggestionBuilderWithNoSsid() {
- new WifiNetworkConfigBuilder()
- .buildNetworkSuggestion();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} throws an exception
- * when {@link WifiNetworkConfigBuilder#setSsid(String)} is invoked with an invalid value.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSuggestionBuilderWithInvalidSsid() {
- new WifiNetworkConfigBuilder()
- .setSsid("")
- .buildNetworkSuggestion();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} throws an exception
- * when {@link WifiNetworkConfigBuilder#setBssid(MacAddress)} is invoked with an invalid value.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSuggestionBuilderWithInvalidBroadcastBssid() {
- new WifiNetworkConfigBuilder()
- .setSsid(TEST_SSID)
- .setBssid(MacAddress.BROADCAST_ADDRESS)
- .buildNetworkSuggestion();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} throws an exception
- * when {@link WifiNetworkConfigBuilder#setBssid(MacAddress)} is invoked with an invalid value.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSuggestionBuilderWithInvalidAllZeroBssid() {
- new WifiNetworkConfigBuilder()
- .setSsid(TEST_SSID)
- .setBssid(MacAddress.ALL_ZEROS_ADDRESS)
- .buildNetworkSuggestion();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#setPriority(int)} throws an exception
- * when the value is negative.
- */
- @Test(expected = IllegalArgumentException.class)
- public void testWifiNetworkSuggestionBuilderWithInvalidPriority() {
- new WifiNetworkConfigBuilder()
- .setSsid(TEST_SSID)
- .setPriority(-1)
- .buildNetworkSuggestion();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
- * when both {@link WifiNetworkConfigBuilder#setWpa2Passphrase(String)} and
- * {@link WifiNetworkConfigBuilder#setWpa3Passphrase(String)} are invoked.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithBothWpa2PasphraseAndWpa3Passphrase() {
- new WifiNetworkConfigBuilder()
- .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
- .setWpa2Passphrase(TEST_PRESHARED_KEY)
- .setWpa3Passphrase(TEST_PRESHARED_KEY)
- .buildNetworkSpecifier();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
- * when both {@link WifiNetworkConfigBuilder#setWpa3Passphrase(String)} and
- * {@link WifiNetworkConfigBuilder#setWpa3EnterpriseConfig(WifiEnterpriseConfig)} are invoked.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithBothWpa3PasphraseAndEnterprise() {
- new WifiNetworkConfigBuilder()
- .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
- .setWpa3Passphrase(TEST_PRESHARED_KEY)
- .setWpa3EnterpriseConfig(new WifiEnterpriseConfig())
- .buildNetworkSpecifier();
- }
-
- /**
- * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
- * when both {@link WifiNetworkConfigBuilder#setWpa3Passphrase(String)} and
- * {@link WifiNetworkConfigBuilder#setIsEnhancedOpen(} are invoked.
- */
- @Test(expected = IllegalStateException.class)
- public void testWifiNetworkSpecifierBuilderWithBothWpa3PasphraseAndEnhancedOpen() {
- new WifiNetworkConfigBuilder()
- .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
- .setWpa3Passphrase(TEST_PRESHARED_KEY)
- .setIsEnhancedOpen()
- .buildNetworkSpecifier();
- }
-}
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java
index fce247f..bef33b7 100644
--- a/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java
@@ -17,6 +17,8 @@
package android.net.wifi;
import static android.os.PatternMatcher.PATTERN_LITERAL;
+import static android.os.PatternMatcher.PATTERN_PREFIX;
+import static android.os.PatternMatcher.PATTERN_SIMPLE_GLOB;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -24,8 +26,10 @@
import android.net.MacAddress;
import android.net.MatchAllNetworkSpecifier;
+import android.net.NetworkSpecifier;
import android.os.Parcel;
import android.os.PatternMatcher;
+import android.os.Process;
import android.util.Pair;
import androidx.test.filters.SmallTest;
@@ -42,9 +46,343 @@
private static final String TEST_SSID = "Test123";
private static final String TEST_BSSID_OUI_BASE_ADDRESS = "12:12:12:00:00:00";
private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00";
+ private static final String TEST_BSSID = "12:12:12:12:12:12";
private static final String TEST_PRESHARED_KEY = "\"Test123\"";
/**
+ * Validate correctness of WifiNetworkSpecifier object created by
+ * {@link WifiNetworkSpecifier.Builder#build()} for open network with SSID pattern.
+ */
+ @Test
+ public void testWifiNetworkSpecifierBuilderForOpenNetworkWithSsidPattern() {
+ NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
+ .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_PREFIX))
+ .build();
+
+ assertTrue(specifier instanceof WifiNetworkSpecifier);
+ WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
+
+ assertEquals(Process.myUid(), wifiNetworkSpecifier.requestorUid);
+ assertEquals(TEST_SSID, wifiNetworkSpecifier.ssidPatternMatcher.getPath());
+ assertEquals(PATTERN_PREFIX, wifiNetworkSpecifier.ssidPatternMatcher.getType());
+ assertEquals(MacAddress.ALL_ZEROS_ADDRESS, wifiNetworkSpecifier.bssidPatternMatcher.first);
+ assertEquals(MacAddress.ALL_ZEROS_ADDRESS, wifiNetworkSpecifier.bssidPatternMatcher.second);
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.NONE));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedProtocols
+ .get(WifiConfiguration.Protocol.RSN));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedAuthAlgorithms
+ .get(WifiConfiguration.AuthAlgorithm.OPEN));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedPairwiseCiphers
+ .get(WifiConfiguration.PairwiseCipher.CCMP));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
+ .get(WifiConfiguration.GroupCipher.CCMP));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
+ .get(WifiConfiguration.GroupCipher.TKIP));
+ }
+
+ /**
+ * Validate correctness of WifiNetworkSpecifier object created by
+ * {@link WifiNetworkSpecifier.Builder#build()} for WPA_PSK network with BSSID
+ * pattern.
+ */
+ @Test
+ public void testWifiNetworkSpecifierBuilderForWpa2PskNetworkWithBssidPattern() {
+ NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
+ .setBssidPattern(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK))
+ .setWpa2Passphrase(TEST_PRESHARED_KEY)
+ .build();
+
+ assertTrue(specifier instanceof WifiNetworkSpecifier);
+ WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
+
+ assertEquals(".*", wifiNetworkSpecifier.ssidPatternMatcher.getPath());
+ assertEquals(PATTERN_SIMPLE_GLOB, wifiNetworkSpecifier.ssidPatternMatcher.getType());
+ assertEquals(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ wifiNetworkSpecifier.bssidPatternMatcher.first);
+ assertEquals(MacAddress.fromString(TEST_BSSID_OUI_MASK),
+ wifiNetworkSpecifier.bssidPatternMatcher.second);
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.WPA_PSK));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedProtocols
+ .get(WifiConfiguration.Protocol.RSN));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedAuthAlgorithms
+ .get(WifiConfiguration.AuthAlgorithm.OPEN));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedPairwiseCiphers
+ .get(WifiConfiguration.PairwiseCipher.CCMP));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
+ .get(WifiConfiguration.GroupCipher.CCMP));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
+ .get(WifiConfiguration.GroupCipher.TKIP));
+ assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
+ wifiNetworkSpecifier.wifiConfiguration.preSharedKey);
+ }
+
+ /**
+ * Validate correctness of WifiNetworkSpecifier object created by
+ * {@link WifiNetworkSpecifier.Builder#build()} for WPA_EAP network with
+ * SSID and BSSID pattern.
+ */
+ @Test
+ public void testWifiNetworkSpecifierBuilderForWpa2EapHiddenNetworkWithSsidAndBssid() {
+ WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
+ enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
+ enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
+
+ NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
+ .setSsid(TEST_SSID)
+ .setBssid(MacAddress.fromString(TEST_BSSID))
+ .setWpa2EnterpriseConfig(enterpriseConfig)
+ .setIsHiddenSsid()
+ .build();
+
+ assertTrue(specifier instanceof WifiNetworkSpecifier);
+ WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
+
+ assertEquals(TEST_SSID, wifiNetworkSpecifier.ssidPatternMatcher.getPath());
+ assertEquals(PATTERN_LITERAL, wifiNetworkSpecifier.ssidPatternMatcher.getType());
+ assertEquals(MacAddress.fromString(TEST_BSSID),
+ wifiNetworkSpecifier.bssidPatternMatcher.first);
+ assertEquals(MacAddress.BROADCAST_ADDRESS,
+ wifiNetworkSpecifier.bssidPatternMatcher.second);
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.WPA_EAP));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.IEEE8021X));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedProtocols
+ .get(WifiConfiguration.Protocol.RSN));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedAuthAlgorithms
+ .get(WifiConfiguration.AuthAlgorithm.OPEN));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedPairwiseCiphers
+ .get(WifiConfiguration.PairwiseCipher.CCMP));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
+ .get(WifiConfiguration.GroupCipher.CCMP));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
+ .get(WifiConfiguration.GroupCipher.TKIP));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.hiddenSSID);
+ assertEquals(enterpriseConfig.getEapMethod(),
+ wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig.getEapMethod());
+ assertEquals(enterpriseConfig.getPhase2Method(),
+ wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig.getPhase2Method());
+ }
+
+
+ /**
+ * Ensure {@link WifiNetworkSpecifier.Builder#setSsid(String)} throws an exception
+ * when the string is not Unicode.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testWifiNetworkSpecifierBuilderSetSsidWithNonUnicodeString() {
+ new WifiNetworkSpecifier.Builder()
+ .setSsid("\ud800")
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSpecifier.Builder#setWpa2Passphrase(String)} throws an exception
+ * when the string is not ASCII encodable.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testWifiNetworkSpecifierSetWpa2PasphraseWithNonAsciiString() {
+ new WifiNetworkSpecifier.Builder()
+ .setSsid(TEST_SSID)
+ .setWpa2Passphrase("salvē")
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
+ * when neither SSID nor BSSID patterns were set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithNoSsidAndBssidPattern() {
+ new WifiNetworkSpecifier.Builder().build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
+ * when match-all SSID pattern is set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithMatchAllSsidPattern1() {
+ new WifiNetworkSpecifier.Builder()
+ .setSsidPattern(new PatternMatcher(".*", PATTERN_SIMPLE_GLOB))
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
+ * when match-all SSID pattern is set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithMatchAllSsidPattern2() {
+ new WifiNetworkSpecifier.Builder()
+ .setSsidPattern(new PatternMatcher(".*", PatternMatcher.PATTERN_ADVANCED_GLOB))
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
+ * when match-all SSID pattern is set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithMatchAllSsidPattern3() {
+ new WifiNetworkSpecifier.Builder()
+ .setSsidPattern(new PatternMatcher("", PATTERN_PREFIX))
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
+ * when match-all BSSID pattern is set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithMatchAllBssidPattern() {
+ new WifiNetworkSpecifier.Builder()
+ .setBssidPattern(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS)
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
+ * when match-none SSID pattern is set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithMatchNoneSsidPattern1() {
+ new WifiNetworkSpecifier.Builder()
+ .setSsidPattern(new PatternMatcher("", PatternMatcher.PATTERN_LITERAL))
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
+ * when match-none SSID pattern is set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithMatchNoneSsidPattern2() {
+ new WifiNetworkSpecifier.Builder()
+ .setSsid("")
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
+ * when match-none BSSID pattern is set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithMatchNoneBssidPattern1() {
+ new WifiNetworkSpecifier.Builder()
+ .setBssidPattern(MacAddress.BROADCAST_ADDRESS, MacAddress.BROADCAST_ADDRESS)
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
+ * when match-none BSSID pattern is set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithMatchNoneBssidPattern2() {
+ new WifiNetworkSpecifier.Builder()
+ .setBssid(MacAddress.BROADCAST_ADDRESS)
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
+ * when match-none BSSID pattern is set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithMatchNoneBssidPattern3() {
+ new WifiNetworkSpecifier.Builder()
+ .setBssid(MacAddress.ALL_ZEROS_ADDRESS)
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
+ * when SSID pattern is set for hidden network.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithBssidMatchPatternForHiddenNetwork() {
+ new WifiNetworkSpecifier.Builder()
+ .setBssidPattern(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK))
+ .setIsHiddenSsid()
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
+ * when both {@link WifiNetworkSpecifier.Builder#setWpa2Passphrase(String)} and
+ * {@link WifiNetworkSpecifier.Builder#setWpa2EnterpriseConfig(WifiEnterpriseConfig)} are
+ * invoked.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithBothWpa2PasphraseAndEnterpriseConfig() {
+ new WifiNetworkSpecifier.Builder()
+ .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
+ .setWpa2Passphrase(TEST_PRESHARED_KEY)
+ .setWpa2EnterpriseConfig(new WifiEnterpriseConfig())
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
+ * when SSID pattern is set for hidden network.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithSsidMatchPatternForHiddenNetwork() {
+ new WifiNetworkSpecifier.Builder()
+ .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_PREFIX))
+ .setIsHiddenSsid()
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
+ * when both {@link WifiNetworkSpecifier.Builder#setWpa2Passphrase(String)} and
+ * {@link WifiNetworkSpecifier.Builder#setWpa3Passphrase(String)} are invoked.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithBothWpa2PasphraseAndWpa3Passphrase() {
+ new WifiNetworkSpecifier.Builder()
+ .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
+ .setWpa2Passphrase(TEST_PRESHARED_KEY)
+ .setWpa3Passphrase(TEST_PRESHARED_KEY)
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
+ * when both {@link WifiNetworkSpecifier.Builder#setWpa3Passphrase(String)} and
+ * {@link WifiNetworkSpecifier.Builder#setWpa3EnterpriseConfig(WifiEnterpriseConfig)} are
+ * invoked.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithBothWpa3PasphraseAndEnterprise() {
+ new WifiNetworkSpecifier.Builder()
+ .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
+ .setWpa3Passphrase(TEST_PRESHARED_KEY)
+ .setWpa3EnterpriseConfig(new WifiEnterpriseConfig())
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSpecifier.Builder#build()} throws an exception
+ * when both {@link WifiNetworkSpecifier.Builder#setWpa3Passphrase(String)} and
+ * {@link WifiNetworkSpecifier.Builder#setIsEnhancedOpen()} are invoked.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithBothWpa3PasphraseAndEnhancedOpen() {
+ new WifiNetworkSpecifier.Builder()
+ .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
+ .setWpa3Passphrase(TEST_PRESHARED_KEY)
+ .setIsEnhancedOpen()
+ .build();
+ }
+
+ /**
* Validate that parcel marshalling/unmarshalling works
*/
@Test
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
index 5f76055..05ee22c 100644
--- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
@@ -18,7 +18,9 @@
import static org.junit.Assert.*;
+import android.net.MacAddress;
import android.os.Parcel;
+import android.os.Process;
import androidx.test.filters.SmallTest;
@@ -36,6 +38,279 @@
private static final String TEST_SSID = "\"Test123\"";
private static final String TEST_BSSID = "12:12:12:12:12:12";
private static final String TEST_SSID_1 = "\"Test1234\"";
+ private static final String TEST_PRESHARED_KEY = "Test123";
+
+ /**
+ * Validate correctness of WifiNetworkSuggestion object created by
+ * {@link WifiNetworkSuggestion.Builder#build()} for Open network which requires
+ * app interaction.
+ */
+ @Test
+ public void testWifiNetworkSuggestionBuilderForOpenNetworkWithReqAppInteraction() {
+ WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
+ .setSsid(TEST_SSID)
+ .setIsAppInteractionRequired()
+ .build();
+
+ assertEquals(Process.myUid(), suggestion.suggestorUid);
+ assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
+ assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.NONE));
+ assertTrue(suggestion.isAppInteractionRequired);
+ assertFalse(suggestion.isUserInteractionRequired);
+ assertEquals(WifiConfiguration.METERED_OVERRIDE_NONE,
+ suggestion.wifiConfiguration.meteredOverride);
+ assertEquals(-1, suggestion.wifiConfiguration.priority);
+ }
+
+ /**
+ * Validate correctness of WifiNetworkSuggestion object created by
+ * {@link WifiNetworkSuggestion.Builder#build()} for WPA_EAP network which requires
+ * app interaction and has a priority of zero set.
+ */
+ @Test
+ public void
+ testWifiNetworkSuggestionBuilderForWpa2EapNetworkWithPriorityAndReqAppInteraction() {
+ WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
+ .setSsid(TEST_SSID)
+ .setWpa2Passphrase(TEST_PRESHARED_KEY)
+ .setIsAppInteractionRequired()
+ .setPriority(0)
+ .build();
+
+ assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
+ assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.WPA_PSK));
+ assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
+ suggestion.wifiConfiguration.preSharedKey);
+ assertTrue(suggestion.isAppInteractionRequired);
+ assertFalse(suggestion.isUserInteractionRequired);
+ assertEquals(WifiConfiguration.METERED_OVERRIDE_NONE,
+ suggestion.wifiConfiguration.meteredOverride);
+ assertEquals(0, suggestion.wifiConfiguration.priority);
+ }
+
+ /**
+ * Validate correctness of WifiNetworkSuggestion object created by
+ * {@link WifiNetworkSuggestion.Builder#build()} for WPA_PSK network which requires
+ * user interaction and is metered.
+ */
+ @Test
+ public void
+ testWifiNetworkSuggestionBuilderForWpa2PskNetworkWithMeteredAndReqUserInteraction() {
+ WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
+ .setSsid(TEST_SSID)
+ .setWpa2Passphrase(TEST_PRESHARED_KEY)
+ .setIsUserInteractionRequired()
+ .setIsMetered()
+ .build();
+
+ assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
+ assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.WPA_PSK));
+ assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
+ suggestion.wifiConfiguration.preSharedKey);
+ assertFalse(suggestion.isAppInteractionRequired);
+ assertTrue(suggestion.isUserInteractionRequired);
+ assertEquals(WifiConfiguration.METERED_OVERRIDE_METERED,
+ suggestion.wifiConfiguration.meteredOverride);
+ assertEquals(-1, suggestion.wifiConfiguration.priority);
+ }
+
+ /**
+ * Validate correctness of WifiNetworkSuggestion object created by
+ * {@link WifiNetworkSuggestion.Builder#build()} for OWE network.
+ */
+ @Test
+ public void testWifiNetworkSuggestionBuilderForEnhancedOpenNetworkWithBssid() {
+ WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
+ .setSsid(TEST_SSID)
+ .setBssid(MacAddress.fromString(TEST_BSSID))
+ .setIsEnhancedOpen()
+ .build();
+
+ assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
+ assertEquals(TEST_BSSID, suggestion.wifiConfiguration.BSSID);
+ assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.OWE));
+ assertNull(suggestion.wifiConfiguration.preSharedKey);
+ assertTrue(suggestion.wifiConfiguration.requirePMF);
+ }
+
+ /**
+ * Validate correctness of WifiNetworkSuggestion object created by
+ * {@link WifiNetworkSuggestion.Builder#build()} for SAE network.
+ */
+ @Test
+ public void testWifiNetworkSuggestionBuilderForWpa3PskNetwork() {
+ WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
+ .setSsid(TEST_SSID)
+ .setWpa3Passphrase(TEST_PRESHARED_KEY)
+ .build();
+
+ assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
+ assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.SAE));
+ assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
+ suggestion.wifiConfiguration.preSharedKey);
+ assertTrue(suggestion.wifiConfiguration.requirePMF);
+ }
+
+
+ /**
+ * Validate correctness of WifiNetworkSuggestion object created by
+ * {@link WifiNetworkSuggestion.Builder#build()} for SuiteB network.
+ */
+ @Test
+ public void testWifiNetworkSuggestionBuilderForWpa3EapNetwork() {
+ WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
+ enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
+ enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
+
+ WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
+ .setSsid(TEST_SSID)
+ .setWpa3EnterpriseConfig(enterpriseConfig)
+ .build();
+
+ assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
+ assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.SUITE_B_192));
+ assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers
+ .get(WifiConfiguration.GroupCipher.GCMP_256));
+ assertTrue(suggestion.wifiConfiguration.allowedGroupManagementCiphers
+ .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256));
+ assertTrue(suggestion.wifiConfiguration.allowedSuiteBCiphers
+ .get(WifiConfiguration.SuiteBCipher.ECDHE_ECDSA));
+ assertTrue(suggestion.wifiConfiguration.allowedSuiteBCiphers
+ .get(WifiConfiguration.SuiteBCipher.ECDHE_RSA));
+ assertTrue(suggestion.wifiConfiguration.requirePMF);
+ assertNull(suggestion.wifiConfiguration.preSharedKey);
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSuggestion.Builder#setSsid(String)} throws an exception
+ * when the string is not Unicode.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testWifiNetworkSuggestionBuilderSetSsidWithNonUnicodeString() {
+ new WifiNetworkSuggestion.Builder()
+ .setSsid("\ud800")
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSuggestion.Builder#setWpa2Passphrase(String)} throws an exception
+ * when the string is not ASCII encodable.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testWifiNetworkSuggestionBuilderSetWpa2PasphraseWithNonAsciiString() {
+ new WifiNetworkSuggestion.Builder()
+ .setSsid(TEST_SSID)
+ .setWpa2Passphrase("salvē")
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
+ * when {@link WifiNetworkSuggestion.Builder#setSsid(String)} is not set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSuggestionBuilderWithNoSsid() {
+ new WifiNetworkSuggestion.Builder()
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
+ * when {@link WifiNetworkSuggestion.Builder#setSsid(String)} is invoked with an invalid value.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSuggestionBuilderWithInvalidSsid() {
+ new WifiNetworkSuggestion.Builder()
+ .setSsid("")
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
+ * when {@link WifiNetworkSuggestion.Builder#setBssid(MacAddress)} is invoked with an invalid
+ * value.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSuggestionBuilderWithInvalidBroadcastBssid() {
+ new WifiNetworkSuggestion.Builder()
+ .setSsid(TEST_SSID)
+ .setBssid(MacAddress.BROADCAST_ADDRESS)
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
+ * when {@link WifiNetworkSuggestion.Builder#setBssid(MacAddress)} is invoked with an invalid
+ * value.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSuggestionBuilderWithInvalidAllZeroBssid() {
+ new WifiNetworkSuggestion.Builder()
+ .setSsid(TEST_SSID)
+ .setBssid(MacAddress.ALL_ZEROS_ADDRESS)
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSuggestion.Builder#setPriority(int)} throws an exception
+ * when the value is negative.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testWifiNetworkSuggestionBuilderWithInvalidPriority() {
+ new WifiNetworkSuggestion.Builder()
+ .setSsid(TEST_SSID)
+ .setPriority(-1)
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
+ * when both {@link WifiNetworkSuggestion.Builder#setWpa2Passphrase(String)} and
+ * {@link WifiNetworkSuggestion.Builder#setWpa3Passphrase(String)} are invoked.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSuggestionBuilderWithBothWpa2PasphraseAndWpa3Passphrase() {
+ new WifiNetworkSuggestion.Builder()
+ .setSsid(TEST_SSID)
+ .setWpa2Passphrase(TEST_PRESHARED_KEY)
+ .setWpa3Passphrase(TEST_PRESHARED_KEY)
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
+ * when both {@link WifiNetworkSuggestion.Builder#setWpa3Passphrase(String)} and
+ * {@link WifiNetworkSuggestion.Builder#setWpa3EnterpriseConfig(WifiEnterpriseConfig)} are
+ * invoked.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSuggestionBuilderWithBothWpa3PasphraseAndEnterprise() {
+ new WifiNetworkSuggestion.Builder()
+ .setSsid(TEST_SSID)
+ .setWpa3Passphrase(TEST_PRESHARED_KEY)
+ .setWpa3EnterpriseConfig(new WifiEnterpriseConfig())
+ .build();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
+ * when both {@link WifiNetworkSuggestion.Builder#setWpa3Passphrase(String)} and
+ * {@link WifiNetworkSuggestion.Builder#setIsEnhancedOpen()} are invoked.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSuggestionBuilderWithBothWpa3PasphraseAndEnhancedOpen() {
+ new WifiNetworkSuggestion.Builder()
+ .setSsid(TEST_SSID)
+ .setWpa3Passphrase(TEST_PRESHARED_KEY)
+ .setIsEnhancedOpen()
+ .build();
+ }
/**
* Check that parcel marshalling/unmarshalling works