Add the ability to match a band on a WiFi network.
• Add API to set a band on WifiNetworkSpecifier
• Make sure all WiFi networks have a WifiNetworkAgentSpecifier
• Compute the band from WifiInfo and store it in WNASpecifier
• Make sure the specifiers match each other correctly
• Add a measure of protection against matching the (B)SSID
on regular WiFis
The intended use of this patch is for apps to be able to match
a WiFi network by its band. Also, while this is not supported
in stock Android, OEMs may replace parts of the stack to support
requesting a network by band, so that apps with appropriate
permissions can request the device connects to multiple bands
at the same time.
Bug: 181741503
Test: new test in cts/ConnectivityManagerTest
Change-Id: I1c2b023bcd53296c9aed221c74fcfb734aebdc6d
diff --git a/framework/api/current.txt b/framework/api/current.txt
index a8ee1dc..c5d9c2f 100644
--- a/framework/api/current.txt
+++ b/framework/api/current.txt
@@ -559,6 +559,7 @@
public final class WifiNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
method public int describeContents();
+ method public int getBand();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiNetworkSpecifier> CREATOR;
}
@@ -566,6 +567,7 @@
public static final class WifiNetworkSpecifier.Builder {
ctor public WifiNetworkSpecifier.Builder();
method @NonNull public android.net.wifi.WifiNetworkSpecifier build();
+ method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setBand(int);
method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setBssid(@NonNull android.net.MacAddress);
method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setBssidPattern(@NonNull android.net.MacAddress, @NonNull android.net.MacAddress);
method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setIsEnhancedOpen(boolean);
diff --git a/framework/java/android/net/wifi/ScanResult.java b/framework/java/android/net/wifi/ScanResult.java
index d124ac2..2a35874 100644
--- a/framework/java/android/net/wifi/ScanResult.java
+++ b/framework/java/android/net/wifi/ScanResult.java
@@ -389,6 +389,7 @@
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"WIFI_BAND_"}, value = {
+ UNSPECIFIED,
WIFI_BAND_24_GHZ,
WIFI_BAND_5_GHZ,
WIFI_BAND_6_GHZ,
diff --git a/framework/java/android/net/wifi/WifiNetworkAgentSpecifier.java b/framework/java/android/net/wifi/WifiNetworkAgentSpecifier.java
index 0d13805..5cdcc16 100644
--- a/framework/java/android/net/wifi/WifiNetworkAgentSpecifier.java
+++ b/framework/java/android/net/wifi/WifiNetworkAgentSpecifier.java
@@ -25,6 +25,7 @@
import android.net.MatchAllNetworkSpecifier;
import android.net.NetworkRequest;
import android.net.NetworkSpecifier;
+import android.net.wifi.ScanResult.WifiBand;
import android.os.Parcel;
import android.os.Parcelable;
@@ -40,10 +41,31 @@
*/
private final WifiConfiguration mWifiConfiguration;
- public WifiNetworkAgentSpecifier(@NonNull WifiConfiguration wifiConfiguration) {
+ /**
+ * Band, as one of the ScanResult.WIFI_BAND_* constants.
+ */
+ @WifiBand private final int mBand;
+
+ /**
+ * Whether to match P2P requests.
+ *
+ * When matching against an instance of WifiNetworkSpecifier, simply matching SSID or
+ * BSSID patterns would let apps know if a given WiFi network's (B)SSID matches a pattern
+ * by simply filing a NetworkCallback with that pattern. Also, apps asking for a match on
+ * (B)SSID are apps requesting a P2P network, which involves protection with UI shown by
+ * the system, and the WifiNetworkSpecifiers for these P2P networks should never match
+ * an Internet-providing network to avoid calling back these apps on a network that happens
+ * to match their requested pattern but has not been brought up for them.
+ */
+ private final boolean mMatchLocalOnlySpecifiers;
+
+ public WifiNetworkAgentSpecifier(@NonNull WifiConfiguration wifiConfiguration,
+ @WifiBand int band, boolean matchLocalOnlySpecifiers) {
checkNotNull(wifiConfiguration);
mWifiConfiguration = wifiConfiguration;
+ mBand = band;
+ mMatchLocalOnlySpecifiers = matchLocalOnlySpecifiers;
}
/**
@@ -54,7 +76,10 @@
@Override
public WifiNetworkAgentSpecifier createFromParcel(@NonNull Parcel in) {
WifiConfiguration wifiConfiguration = in.readParcelable(null);
- return new WifiNetworkAgentSpecifier(wifiConfiguration);
+ int band = in.readInt();
+ boolean matchLocationSensitiveFields = in.readBoolean();
+ return new WifiNetworkAgentSpecifier(wifiConfiguration, band,
+ matchLocationSensitiveFields);
}
@Override
@@ -71,6 +96,8 @@
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeParcelable(mWifiConfiguration, flags);
+ dest.writeInt(mBand);
+ dest.writeBoolean(mMatchLocalOnlySpecifiers);
}
@Override
@@ -104,6 +131,13 @@
checkNotNull(this.mWifiConfiguration.BSSID);
checkNotNull(this.mWifiConfiguration.allowedKeyManagement);
+ if (!mMatchLocalOnlySpecifiers) {
+ // Specifiers that match non-local-only networks only match against the band.
+ return ns.getBand() == mBand;
+ }
+ if (ns.getBand() != ScanResult.UNSPECIFIED && ns.getBand() != mBand) {
+ return false;
+ }
final String ssidWithQuotes = this.mWifiConfiguration.SSID;
checkState(ssidWithQuotes.startsWith("\"") && ssidWithQuotes.endsWith("\""));
final String ssidWithoutQuotes = ssidWithQuotes.substring(1, ssidWithQuotes.length() - 1);
@@ -128,7 +162,9 @@
return Objects.hash(
mWifiConfiguration.SSID,
mWifiConfiguration.BSSID,
- mWifiConfiguration.allowedKeyManagement);
+ mWifiConfiguration.allowedKeyManagement,
+ mBand,
+ mMatchLocalOnlySpecifiers);
}
@Override
@@ -143,7 +179,9 @@
return Objects.equals(this.mWifiConfiguration.SSID, lhs.mWifiConfiguration.SSID)
&& Objects.equals(this.mWifiConfiguration.BSSID, lhs.mWifiConfiguration.BSSID)
&& Objects.equals(this.mWifiConfiguration.allowedKeyManagement,
- lhs.mWifiConfiguration.allowedKeyManagement);
+ lhs.mWifiConfiguration.allowedKeyManagement)
+ && mBand == lhs.mBand
+ && mMatchLocalOnlySpecifiers == lhs.mMatchLocalOnlySpecifiers;
}
@Override
@@ -152,6 +190,8 @@
sb.append("WifiConfiguration=")
.append(", SSID=").append(mWifiConfiguration.SSID)
.append(", BSSID=").append(mWifiConfiguration.BSSID)
+ .append(", band=").append(mBand)
+ .append(", matchLocationSensitiveFields=").append(mMatchLocalOnlySpecifiers)
.append("]");
return sb.toString();
}
diff --git a/framework/java/android/net/wifi/WifiNetworkSpecifier.java b/framework/java/android/net/wifi/WifiNetworkSpecifier.java
index e4b23bf..0b0eaff 100644
--- a/framework/java/android/net/wifi/WifiNetworkSpecifier.java
+++ b/framework/java/android/net/wifi/WifiNetworkSpecifier.java
@@ -20,9 +20,13 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
import android.net.MacAddress;
+import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.NetworkSpecifier;
+import android.net.wifi.ScanResult.WifiBand;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.PatternMatcher;
@@ -34,20 +38,65 @@
import java.util.Objects;
/**
- * Network specifier object used to request a local Wi-Fi network. Apps should use the
+ * Network specifier object used to request a Wi-Fi network. Apps should use the
* {@link WifiNetworkSpecifier.Builder} class to create an instance.
* <p>
- * On devices which support concurrent connections (indicated via
+ * This specifier can be used to request a local-only connection on devices that support concurrent
+ * connections (indicated via
* {@link WifiManager#isStaConcurrencyForLocalOnlyConnectionsSupported()} and if the initiating app
- * targets SDK ≥ {@link android.os.Build.VERSION_CODES#S} or is a system app, these local only
+ * targets SDK ≥ {@link android.os.Build.VERSION_CODES#S} or is a system app. These local-only
* connections may be brought up as a secondary concurrent connection (primary connection will be
* used for networks with internet connectivity available to the user and all apps).
* </p>
+ * <p>
+ * This specifier can also be used to listen for connected Wi-Fi networks on a particular band.
+ * Additionally, some devices may support requesting a connection to a particular band. If the
+ * device does not support such a request, it will send {@link NetworkCallback#onUnavailable()}
+ * upon request to the callback passed to
+ * {@link ConnectivityManager#requestNetwork(NetworkRequest, NetworkCallback)} or equivalent.
+ * See {@link Builder#build()} for details.
+ * </p>
*/
public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parcelable {
private static final String TAG = "WifiNetworkSpecifier";
/**
+ * Returns the band for a given frequency in MHz.
+ * @hide
+ */
+ @WifiBand public static int getBand(final int freqMHz) {
+ if (ScanResult.is24GHz(freqMHz)) {
+ return ScanResult.WIFI_BAND_24_GHZ;
+ } else if (ScanResult.is5GHz(freqMHz)) {
+ return ScanResult.WIFI_BAND_5_GHZ;
+ } else if (ScanResult.is6GHz(freqMHz)) {
+ return ScanResult.WIFI_BAND_6_GHZ;
+ } else if (ScanResult.is60GHz(freqMHz)) {
+ return ScanResult.WIFI_BAND_60_GHZ;
+ }
+ return ScanResult.UNSPECIFIED;
+ }
+
+ /**
+ * Validates that the passed band is a valid band
+ * @param band the band to check
+ * @return true if the band is valid, false otherwise
+ * @hide
+ */
+ public static boolean validateBand(@WifiBand int band) {
+ switch (band) {
+ case ScanResult.UNSPECIFIED:
+ case ScanResult.WIFI_BAND_24_GHZ:
+ case ScanResult.WIFI_BAND_5_GHZ:
+ case ScanResult.WIFI_BAND_6_GHZ:
+ case ScanResult.WIFI_BAND_60_GHZ:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**
* Builder used to create {@link WifiNetworkSpecifier} objects.
*/
public static final class Builder {
@@ -112,6 +161,10 @@
* SSID-specific probe request must be used for scans.
*/
private boolean mIsHiddenSSID;
+ /**
+ * The requested band for this connection, or BAND_UNSPECIFIED.
+ */
+ @WifiBand private int mBand;
public Builder() {
mSsidPatternMatcher = null;
@@ -122,6 +175,7 @@
mWpa2EnterpriseConfig = null;
mWpa3EnterpriseConfig = null;
mIsHiddenSSID = false;
+ mBand = ScanResult.UNSPECIFIED;
}
/**
@@ -353,6 +407,23 @@
return this;
}
+ /**
+ * Specifies the band requested for this network.
+ *
+ * Only a single band can be requested. An app can file multiple callbacks concurrently
+ * if they need to know about multiple bands.
+ *
+ * @param band The requested band.
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ public @NonNull Builder setBand(@WifiBand int band) {
+ if (!validateBand(band)) {
+ throw new IllegalArgumentException("Unexpected band in setBand : " + band);
+ }
+ mBand = band;
+ return this;
+ }
+
private void setSecurityParamsInWifiConfiguration(
@NonNull WifiConfiguration configuration) {
if (!TextUtils.isEmpty(mWpa2PskPassphrase)) { // WPA-PSK network.
@@ -462,14 +533,27 @@
}
/**
- * Create a specifier object used to request a local Wi-Fi network. The generated
+ * 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}. 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.
+ * the {@link NetworkRequest}.
+ *
*<p>
- * Note: Apps can set a combination of network match params:
+ * When using with {@link ConnectivityManager#requestNetwork(NetworkRequest,
+ * NetworkCallback)} or variants, note that some devices may not support requesting a
+ * network with all combinations of specifier members. For example, some devices may only
+ * support requesting local-only networks (networks without the
+ * {@link NetworkCapabilities#NET_CAPABILITY_INTERNET} capability), or not support
+ * requesting a particular band. However, there are no restrictions when using
+ * {@link ConnectivityManager#registerNetworkCallback(NetworkRequest, NetworkCallback)}
+ * or other similar methods which monitor but do not request networks.
+ *
+ * If the device can't support a request, the app will receive a call to
+ * {@link NetworkCallback#onUnavailable()}.
+ *</p>
+ *
+ *<p>
+ * When requesting a local-only network, 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
@@ -479,6 +563,12 @@
* 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.
+ *
+ * To protect user privacy, some limitations to the ability of matching patterns apply.
+ * In particular, when the system brings up a network to satisfy a {@link NetworkRequest}
+ * from some app, the system reserves the right to decline matching the SSID pattern to
+ * the real SSID of the network for other apps than the app that requested the network, and
+ * not send those callbacks even if the SSID matches the requested pattern.
*</p>
*
* For example:
@@ -512,15 +602,15 @@
* @throws IllegalStateException on invalid params set.
*/
public @NonNull WifiNetworkSpecifier build() {
- if (!hasSetAnyPattern()) {
+ if (!hasSetAnyPattern() && mBand == ScanResult.UNSPECIFIED) {
throw new IllegalStateException("one of setSsidPattern/setSsid/setBssidPattern/"
- + "setBssid should be invoked for specifier");
+ + "setBssid/setBand should be invoked for specifier");
}
setMatchAnyPatternIfUnset();
if (hasSetMatchNonePattern()) {
throw new IllegalStateException("cannot set match-none pattern for specifier");
}
- if (hasSetMatchAllPattern()) {
+ if (hasSetMatchAllPattern() && mBand == ScanResult.UNSPECIFIED) {
throw new IllegalStateException("cannot set match-all pattern for specifier");
}
if (mIsHiddenSSID && mSsidPatternMatcher.getType() != PatternMatcher.PATTERN_LITERAL) {
@@ -532,6 +622,7 @@
return new WifiNetworkSpecifier(
mSsidPatternMatcher,
mBssidPatternMatcher,
+ mBand,
buildWifiConfiguration());
}
}
@@ -550,6 +641,11 @@
public final Pair<MacAddress, MacAddress> bssidPatternMatcher;
/**
+ * The band for this Wi-Fi network.
+ */
+ @WifiBand private final int mBand;
+
+ /**
* Security credentials for the network.
* <p>
* Note: {@link WifiConfiguration#SSID} & {@link WifiConfiguration#BSSID} fields from
@@ -568,6 +664,7 @@
/** @hide */
public WifiNetworkSpecifier(@NonNull PatternMatcher ssidPatternMatcher,
@NonNull Pair<MacAddress, MacAddress> bssidPatternMatcher,
+ @WifiBand int band,
@NonNull WifiConfiguration wifiConfiguration) {
checkNotNull(ssidPatternMatcher);
checkNotNull(bssidPatternMatcher);
@@ -575,9 +672,17 @@
this.ssidPatternMatcher = ssidPatternMatcher;
this.bssidPatternMatcher = bssidPatternMatcher;
+ this.mBand = band;
this.wifiConfiguration = wifiConfiguration;
}
+ /**
+ * The band for this Wi-Fi network specifier.
+ */
+ @WifiBand public int getBand() {
+ return mBand;
+ }
+
public static final @NonNull Creator<WifiNetworkSpecifier> CREATOR =
new Creator<WifiNetworkSpecifier>() {
@Override
@@ -587,8 +692,9 @@
MacAddress mask = in.readParcelable(null);
Pair<MacAddress, MacAddress> bssidPatternMatcher =
Pair.create(baseAddress, mask);
+ int band = in.readInt();
WifiConfiguration wifiConfiguration = in.readParcelable(null);
- return new WifiNetworkSpecifier(ssidPatternMatcher, bssidPatternMatcher,
+ return new WifiNetworkSpecifier(ssidPatternMatcher, bssidPatternMatcher, band,
wifiConfiguration);
}
@@ -608,6 +714,7 @@
dest.writeParcelable(ssidPatternMatcher, flags);
dest.writeParcelable(bssidPatternMatcher.first, flags);
dest.writeParcelable(bssidPatternMatcher.second, flags);
+ dest.writeInt(mBand);
dest.writeParcelable(wifiConfiguration, flags);
}
@@ -615,7 +722,7 @@
public int hashCode() {
return Objects.hash(
ssidPatternMatcher.getPath(), ssidPatternMatcher.getType(), bssidPatternMatcher,
- wifiConfiguration.allowedKeyManagement);
+ mBand, wifiConfiguration.allowedKeyManagement);
}
@Override
@@ -633,6 +740,7 @@
lhs.ssidPatternMatcher.getType())
&& Objects.equals(this.bssidPatternMatcher,
lhs.bssidPatternMatcher)
+ && this.mBand == lhs.mBand
&& Objects.equals(this.wifiConfiguration.allowedKeyManagement,
lhs.wifiConfiguration.allowedKeyManagement);
}
@@ -645,6 +753,7 @@
.append(", BSSID Match pattern=").append(bssidPatternMatcher)
.append(", SSID=").append(wifiConfiguration.SSID)
.append(", BSSID=").append(wifiConfiguration.BSSID)
+ .append(", band=").append(mBand)
.append("]")
.toString();
}
diff --git a/framework/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java b/framework/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java
index d479aac..c33cad8 100644
--- a/framework/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java
+++ b/framework/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java
@@ -90,13 +90,13 @@
WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration();
WifiNetworkAgentSpecifier specifier1 =
new WifiNetworkAgentSpecifier(
- wifiConfiguration1);
+ wifiConfiguration1, ScanResult.WIFI_BAND_24_GHZ, true);
WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1);
wifiConfiguration2.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
WifiNetworkAgentSpecifier specifier2 =
new WifiNetworkAgentSpecifier(
- wifiConfiguration2);
+ wifiConfiguration2, ScanResult.WIFI_BAND_24_GHZ, true);
assertFalse(specifier2.equals(specifier1));
}
@@ -112,13 +112,13 @@
WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration();
WifiNetworkAgentSpecifier specifier1 =
new WifiNetworkAgentSpecifier(
- wifiConfiguration1);
+ wifiConfiguration1, ScanResult.WIFI_BAND_5_GHZ, true);
WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1);
wifiConfiguration2.SSID = TEST_SSID_1;
WifiNetworkAgentSpecifier specifier2 =
new WifiNetworkAgentSpecifier(
- wifiConfiguration2);
+ wifiConfiguration2, ScanResult.WIFI_BAND_5_GHZ, true);
assertFalse(specifier2.equals(specifier1));
}
@@ -134,13 +134,13 @@
WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration();
WifiNetworkAgentSpecifier specifier1 =
new WifiNetworkAgentSpecifier(
- wifiConfiguration1);
+ wifiConfiguration1, ScanResult.WIFI_BAND_24_GHZ, false);
WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1);
wifiConfiguration2.BSSID = TEST_BSSID_1;
WifiNetworkAgentSpecifier specifier2 =
new WifiNetworkAgentSpecifier(
- wifiConfiguration2);
+ wifiConfiguration2, ScanResult.WIFI_BAND_24_GHZ, false);
assertFalse(specifier2.equals(specifier1));
}
@@ -194,6 +194,7 @@
WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
ssidPattern,
bssidPattern,
+ ScanResult.WIFI_BAND_5_GHZ,
wificonfigurationNetworkSpecifier);
assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
@@ -222,6 +223,7 @@
WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
ssidPattern,
bssidPattern,
+ ScanResult.WIFI_BAND_5_GHZ,
wificonfigurationNetworkSpecifier);
assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
@@ -250,6 +252,7 @@
WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
ssidPattern,
bssidPattern,
+ ScanResult.WIFI_BAND_5_GHZ,
wificonfigurationNetworkSpecifier);
assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
@@ -269,7 +272,7 @@
wifiConfigurationNetworkAgent.SSID = "\"" + TEST_SSID_1 + "\"";
WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
new WifiNetworkAgentSpecifier(
- wifiConfigurationNetworkAgent);
+ wifiConfigurationNetworkAgent, ScanResult.WIFI_BAND_24_GHZ, true);
PatternMatcher ssidPattern =
new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
@@ -281,6 +284,7 @@
WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
ssidPattern,
bssidPattern,
+ ScanResult.WIFI_BAND_24_GHZ,
wificonfigurationNetworkSpecifier);
assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
@@ -288,6 +292,113 @@
}
/**
+ * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} band matching.
+ */
+ @Test
+ public void testWifiNetworkAgentSpecifierBandMatching() {
+ WifiConfiguration wifiConfigurationNetworkAgent = createDefaultWifiConfiguration();
+ wifiConfigurationNetworkAgent.SSID = "\"" + TEST_SSID + "\"";
+ WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
+ new WifiNetworkAgentSpecifier(
+ wifiConfigurationNetworkAgent, ScanResult.WIFI_BAND_5_GHZ, true);
+
+ PatternMatcher ssidPattern =
+ new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
+ Pair<MacAddress, MacAddress> bssidPattern =
+ Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK));
+ WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
+ wificonfigurationNetworkSpecifier.allowedKeyManagement
+ .set(WifiConfiguration.KeyMgmt.WPA_PSK);
+
+ // Same band matches.
+ WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
+ ssidPattern,
+ bssidPattern,
+ ScanResult.WIFI_BAND_5_GHZ,
+ wificonfigurationNetworkSpecifier);
+ assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
+ assertTrue(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
+
+ // Different band does not match.
+ wifiNetworkSpecifier = new WifiNetworkSpecifier(
+ ssidPattern,
+ bssidPattern,
+ ScanResult.WIFI_BAND_24_GHZ,
+ wificonfigurationNetworkSpecifier);
+ assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
+ assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
+
+ // UNSPECIFIED matches a specified band.
+ wifiNetworkSpecifier = new WifiNetworkSpecifier(
+ ssidPattern,
+ bssidPattern,
+ ScanResult.UNSPECIFIED,
+ wificonfigurationNetworkSpecifier);
+ assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
+ assertTrue(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
+ }
+
+ /**
+ * Validate {@link WifiNetworkAgentSpecifier} local-only matching.
+ */
+ @Test
+ public void testWifiNetworkAgentSpecifierLocalOnlyMatching() {
+ WifiConfiguration wifiConfigurationNetworkAgent = createDefaultWifiConfiguration();
+ wifiConfigurationNetworkAgent.SSID = "\"" + TEST_SSID_1 + "\"";
+
+ PatternMatcher ssidPattern =
+ new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
+ Pair<MacAddress, MacAddress> bssidPattern =
+ Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK));
+ WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
+ wificonfigurationNetworkSpecifier.allowedKeyManagement
+ .set(WifiConfiguration.KeyMgmt.WPA_PSK);
+
+ // There is no match because the SSID pattern does not match.
+ WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
+ new WifiNetworkAgentSpecifier(
+ wifiConfigurationNetworkAgent, ScanResult.WIFI_BAND_5_GHZ, true);
+ WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
+ ssidPattern,
+ bssidPattern,
+ ScanResult.WIFI_BAND_5_GHZ,
+ wificonfigurationNetworkSpecifier);
+ assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
+ assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
+
+ // If the WifiNetworkAgentSpecifier is not a local-only specifier, then it matches, because
+ // the SSID pattern is ignored.
+ // TODO: this should also fail to match. An app setting a specifier with a SSID or BSSID
+ // pattern should not match any peer-to-peer network.
+ wifiNetworkAgentSpecifier =
+ new WifiNetworkAgentSpecifier(
+ wifiConfigurationNetworkAgent, ScanResult.WIFI_BAND_5_GHZ, false);
+ assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
+ assertTrue(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
+
+ // If the band doesn't match, then there is no match.
+ wifiNetworkSpecifier = new WifiNetworkSpecifier(
+ ssidPattern,
+ bssidPattern,
+ ScanResult.WIFI_BAND_24_GHZ,
+ wificonfigurationNetworkSpecifier);
+ assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
+ assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
+
+ // An UNSPECIFIED band also doesn't match anything.
+ // TODO: this is also likely incorrect.
+ wifiNetworkSpecifier = new WifiNetworkSpecifier(
+ ssidPattern,
+ bssidPattern,
+ ScanResult.UNSPECIFIED,
+ wificonfigurationNetworkSpecifier);
+ assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
+ assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
+ }
+
+ /**
* Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
* a) Create network agent specifier for WPA_PSK network
* b) Create network specifier with non-matching BSSID pattern.
@@ -300,7 +411,7 @@
wifiConfigurationNetworkAgent.BSSID = TEST_BSSID_1;
WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
new WifiNetworkAgentSpecifier(
- wifiConfigurationNetworkAgent);
+ wifiConfigurationNetworkAgent, ScanResult.WIFI_BAND_5_GHZ, true);
PatternMatcher ssidPattern =
new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB);
@@ -313,6 +424,7 @@
WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
ssidPattern,
bssidPattern,
+ ScanResult.WIFI_BAND_5_GHZ,
wificonfigurationNetworkSpecifier);
assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
@@ -332,7 +444,7 @@
wifiConfigurationNetworkAgent.BSSID = TEST_BSSID_1;
WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
new WifiNetworkAgentSpecifier(
- wifiConfigurationNetworkAgent);
+ wifiConfigurationNetworkAgent, ScanResult.WIFI_BAND_24_GHZ, true);
PatternMatcher ssidPattern =
new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
@@ -345,6 +457,7 @@
WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
ssidPattern,
bssidPattern,
+ ScanResult.WIFI_BAND_24_GHZ,
wificonfigurationNetworkSpecifier);
assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
@@ -372,13 +485,13 @@
WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
ssidPattern,
bssidPattern,
+ ScanResult.UNSPECIFIED,
wificonfigurationNetworkSpecifier);
assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
}
-
private WifiConfiguration createDefaultWifiConfiguration() {
WifiConfiguration wifiConfiguration = new WifiConfiguration();
wifiConfiguration.SSID = "\"" + TEST_SSID + "\"";
@@ -389,7 +502,8 @@
}
private WifiNetworkAgentSpecifier createDefaultNetworkAgentSpecifier() {
- return new WifiNetworkAgentSpecifier(createDefaultWifiConfiguration());
+ return new WifiNetworkAgentSpecifier(createDefaultWifiConfiguration(),
+ ScanResult.WIFI_BAND_5_GHZ, false);
}
}
diff --git a/framework/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java b/framework/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java
index 1383f72..87dd8c2 100644
--- a/framework/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java
+++ b/framework/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java
@@ -653,6 +653,7 @@
new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
+ ScanResult.WIFI_BAND_5_GHZ,
wifiConfiguration);
Parcel parcelW = Parcel.obtain();
@@ -684,6 +685,7 @@
new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
+ ScanResult.UNSPECIFIED, /* band */
wifiConfiguration);
assertFalse(specifier.canBeSatisfiedBy(null));
@@ -706,12 +708,14 @@
new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
+ ScanResult.WIFI_BAND_5_GHZ,
wifiConfiguration);
WifiNetworkSpecifier specifier2 =
new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
+ ScanResult.WIFI_BAND_5_GHZ,
wifiConfiguration);
assertTrue(specifier2.canBeSatisfiedBy(specifier1));
@@ -733,6 +737,7 @@
new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
+ ScanResult.WIFI_BAND_24_GHZ,
wifiConfiguration1);
WifiConfiguration wifiConfiguration2 = new WifiConfiguration();
@@ -741,6 +746,7 @@
new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
+ ScanResult.WIFI_BAND_24_GHZ,
wifiConfiguration2);
assertFalse(specifier2.canBeSatisfiedBy(specifier1));
@@ -762,12 +768,14 @@
new WifiNetworkSpecifier(new PatternMatcher("", PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
+ ScanResult.WIFI_BAND_5_GHZ,
wifiConfiguration);
WifiNetworkSpecifier specifier2 =
new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
+ ScanResult.WIFI_BAND_5_GHZ,
wifiConfiguration);
assertFalse(specifier2.canBeSatisfiedBy(specifier1));
@@ -789,14 +797,67 @@
new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
+ ScanResult.WIFI_BAND_24_GHZ,
wifiConfiguration);
WifiNetworkSpecifier specifier2 =
new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS,
WifiManager.ALL_ZEROS_MAC_ADDRESS),
+ ScanResult.WIFI_BAND_24_GHZ,
wifiConfiguration);
assertFalse(specifier2.canBeSatisfiedBy(specifier1));
}
+
+ /**
+ * Validate NetworkSpecifier band matching.
+ */
+ @Test
+ public void testWifiNetworkSpecifierBandMatching() {
+ WifiConfiguration wifiConfiguration = new WifiConfiguration();
+ wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
+
+ WifiNetworkSpecifier specifier1 =
+ new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
+ Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK)),
+ ScanResult.WIFI_BAND_24_GHZ,
+ wifiConfiguration);
+
+ WifiNetworkSpecifier specifier2 =
+ new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
+ Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK)),
+ ScanResult.WIFI_BAND_24_GHZ,
+ wifiConfiguration);
+
+ // Same band matches.
+ assertTrue(specifier2.canBeSatisfiedBy(specifier1));
+ assertTrue(specifier1.canBeSatisfiedBy(specifier2));
+
+ specifier2 =
+ new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
+ Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS,
+ WifiManager.ALL_ZEROS_MAC_ADDRESS),
+ ScanResult.WIFI_BAND_5_GHZ,
+ wifiConfiguration);
+
+ // Different band does not match.
+ assertFalse(specifier2.canBeSatisfiedBy(specifier1));
+ assertFalse(specifier1.canBeSatisfiedBy(specifier2));
+
+ specifier1 =
+ new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
+ Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS,
+ WifiManager.ALL_ZEROS_MAC_ADDRESS),
+ ScanResult.UNSPECIFIED,
+ wifiConfiguration);
+
+ // An UNSPECIFIED band does not match a specified band, because a WifiNetworkSpecifier
+ // satisfies another only if they are equal.
+ assertFalse(specifier2.canBeSatisfiedBy(specifier1));
+ assertFalse(specifier1.canBeSatisfiedBy(specifier2));
+ }
}
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index 679c8fc..31eac23 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -78,6 +78,7 @@
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiNetworkAgentSpecifier;
+import android.net.wifi.WifiNetworkSpecifier;
import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.wifi.hotspot2.OsuProvider;
import android.net.wifi.nl80211.DeviceWiphyCapabilities;
@@ -3847,10 +3848,15 @@
}
private WifiNetworkAgentSpecifier createNetworkAgentSpecifier(
- @NonNull WifiConfiguration currentWifiConfiguration, @Nullable String currentBssid) {
- currentWifiConfiguration.BSSID = currentBssid;
+ @NonNull WifiConfiguration currentWifiConfiguration, @Nullable String currentBssid,
+ boolean matchLocationSensitiveInformation) {
+ // Defensive copy to avoid mutating the passed argument
+ final WifiConfiguration conf = new WifiConfiguration(currentWifiConfiguration);
+ conf.BSSID = currentBssid;
WifiNetworkAgentSpecifier wns =
- new WifiNetworkAgentSpecifier(currentWifiConfiguration);
+ new WifiNetworkAgentSpecifier(conf,
+ WifiNetworkSpecifier.getBand(mWifiInfo.getFrequency()),
+ matchLocationSensitiveInformation);
return wns;
}
@@ -3922,10 +3928,18 @@
if (mNetworkFactory.isSpecificRequestInProgress(currentWifiConfiguration, currentBssid)) {
// Remove internet capability.
builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
- // Fill up the network agent specifier for this connection.
- builder.setNetworkSpecifier(createNetworkAgentSpecifier(
- currentWifiConfiguration, getConnectedBssidInternal()));
+ // Fill up the network agent specifier for this connection, allowing NetworkCallbacks
+ // to match local-only specifiers in requests. TODO(b/187921303): a third-party app can
+ // observe this location-sensitive information by registering a NetworkCallback.
+ builder.setNetworkSpecifier(createNetworkAgentSpecifier(currentWifiConfiguration,
+ getConnectedBssidInternal(), true /* matchLocalOnlySpecifiers */));
+ } else {
+ // Fill up the network agent specifier for this connection, without allowing
+ // NetworkCallbacks to match local-only specifiers in requests.
+ builder.setNetworkSpecifier(createNetworkAgentSpecifier(currentWifiConfiguration,
+ getConnectedBssidInternal(), false /* matchLocalOnlySpecifiers */));
}
+
updateLinkBandwidth(builder);
final NetworkCapabilities networkCapabilities = builder.build();
if (mVcnManager == null || !currentWifiConfiguration.carrierMerged) {
diff --git a/service/java/com/android/server/wifi/WifiConfigurationUtil.java b/service/java/com/android/server/wifi/WifiConfigurationUtil.java
index 50ec9c7..5bfae26 100644
--- a/service/java/com/android/server/wifi/WifiConfigurationUtil.java
+++ b/service/java/com/android/server/wifi/WifiConfigurationUtil.java
@@ -20,6 +20,7 @@
import static com.android.server.wifi.util.NativeUtil.addEnclosingQuotes;
+import android.annotation.SuppressLint;
import android.net.IpConfiguration;
import android.net.MacAddress;
import android.net.StaticIpConfiguration;
@@ -751,6 +752,12 @@
return false;
}
+ // TODO: b/177434707 calls inside same module are safe
+ @SuppressLint("NewApi")
+ private static int getBand(WifiNetworkSpecifier s) {
+ return s.getBand();
+ }
+
/**
* Validate the configuration received from an external application inside
* {@link WifiNetworkSpecifier}.
@@ -758,15 +765,16 @@
* This method checks for the following parameters:
* 1. {@link WifiNetworkSpecifier#ssidPatternMatcher}
* 2. {@link WifiNetworkSpecifier#bssidPatternMatcher}
- * 3. {@link WifiConfiguration#SSID}
- * 4. {@link WifiConfiguration#BSSID}
- * 5. {@link WifiConfiguration#preSharedKey}
- * 6. {@link WifiConfiguration#allowedKeyManagement}
- * 7. {@link WifiConfiguration#allowedProtocols}
- * 8. {@link WifiConfiguration#allowedAuthAlgorithms}
- * 9. {@link WifiConfiguration#allowedGroupCiphers}
- * 10. {@link WifiConfiguration#allowedPairwiseCiphers}
- * 11. {@link WifiConfiguration#getIpConfiguration()}
+ * 3. {@link WifiNetworkSpecifier#getBand()}
+ * 4. {@link WifiConfiguration#SSID}
+ * 5. {@link WifiConfiguration#BSSID}
+ * 6. {@link WifiConfiguration#preSharedKey}
+ * 7. {@link WifiConfiguration#allowedKeyManagement}
+ * 8. {@link WifiConfiguration#allowedProtocols}
+ * 9. {@link WifiConfiguration#allowedAuthAlgorithms}
+ * 10. {@link WifiConfiguration#allowedGroupCiphers}
+ * 11. {@link WifiConfiguration#allowedPairwiseCiphers}
+ * 12. {@link WifiConfiguration#getIpConfiguration()}
*
* @param specifier Instance of {@link WifiNetworkSpecifier}.
* @return true if the parameters are valid, false otherwise.
@@ -784,6 +792,9 @@
Log.e(TAG, "validateNetworkSpecifier failed : match-all specifier");
return false;
}
+ if (!WifiNetworkSpecifier.validateBand(getBand(specifier))) {
+ return false;
+ }
WifiConfiguration config = specifier.wifiConfiguration;
if (specifier.ssidPatternMatcher.getType() == PatternMatcher.PATTERN_LITERAL) {
// For literal SSID matches, the value should satisfy SSID requirements.
diff --git a/service/java/com/android/server/wifi/WifiNetworkFactory.java b/service/java/com/android/server/wifi/WifiNetworkFactory.java
index 9650be4..3f029bf 100644
--- a/service/java/com/android/server/wifi/WifiNetworkFactory.java
+++ b/service/java/com/android/server/wifi/WifiNetworkFactory.java
@@ -25,6 +25,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.AppOpsManager;
@@ -646,6 +647,12 @@
return false;
}
+ // TODO: b/177434707 calls inside same module are safe
+ @SuppressLint("NewApi")
+ private static int getBand(WifiNetworkSpecifier s) {
+ return s.getBand();
+ }
+
boolean isRequestWithWifiNetworkSpecifierValid(NetworkRequest networkRequest) {
// Request cannot have internet capability since such a request can never be fulfilled.
// (NetworkAgent for connection with WifiNetworkSpecifier will not have internet capability)
@@ -672,6 +679,10 @@
return false;
}
WifiNetworkSpecifier wns = (WifiNetworkSpecifier) networkRequest.getNetworkSpecifier();
+ if (getBand(wns) != ScanResult.UNSPECIFIED) {
+ Log.e(TAG, "Requesting specific frequency bands is not yet supported. Rejecting");
+ return false;
+ }
if (!WifiConfigurationUtil.validateNetworkSpecifier(wns)) {
Log.e(TAG, "Invalid wifi network specifier: " + wns + ". Rejecting ");
return false;
@@ -790,7 +801,8 @@
mActiveSpecificNetworkRequest = networkRequest;
WifiNetworkSpecifier wns = (WifiNetworkSpecifier) ns;
mActiveSpecificNetworkRequestSpecifier = new WifiNetworkSpecifier(
- wns.ssidPatternMatcher, wns.bssidPatternMatcher, wns.wifiConfiguration);
+ wns.ssidPatternMatcher, wns.bssidPatternMatcher, ScanResult.UNSPECIFIED,
+ wns.wifiConfiguration);
mWifiMetrics.incrementNetworkRequestApiNumRequest();
if (!triggerConnectIfUserApprovedMatchFound()) {
@@ -1000,6 +1012,9 @@
networkToConnect.shared = false;
networkToConnect.fromWifiNetworkSpecifier = true;
+ // TODO(b/188021807): Implement the band request from the specifier on the network to
+ // connect.
+
// Store the user selected network.
mUserSelectedNetwork = networkToConnect;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
index 1d43666..5fcf778 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
@@ -107,6 +107,7 @@
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiNetworkAgentSpecifier;
+import android.net.wifi.WifiNetworkSpecifier;
import android.net.wifi.WifiSsid;
import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.wifi.hotspot2.OsuProvider;
@@ -4333,6 +4334,7 @@
*/
@Test
public void verifyNetworkCapabilities() throws Exception {
+ mWifiInfo.setFrequency(5825);
when(mPerNetwork.getTxLinkBandwidthKbps()).thenReturn(40_000);
when(mPerNetwork.getRxLinkBandwidthKbps()).thenReturn(50_000);
// Simulate the first connection.
@@ -4348,7 +4350,6 @@
// Should have internet capability.
assertTrue(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET));
- assertNull(networkCapabilities.getNetworkSpecifier());
assertEquals(mConnectedNetwork.creatorUid, networkCapabilities.getOwnerUid());
assertArrayEquals(
@@ -4359,6 +4360,16 @@
assertEquals(-42, mWifiInfo.getRssi());
assertEquals(40_000, networkCapabilities.getLinkUpstreamBandwidthKbps());
assertEquals(50_000, networkCapabilities.getLinkDownstreamBandwidthKbps());
+
+ // Should set band correctly.
+ // There is no accessor to get the band from the WifiNetworkAgentSpecifier, so match against
+ // a WifiNetworkSpecifier.
+ // TODO: should there be?
+ final NetworkSpecifier spec = networkCapabilities.getNetworkSpecifier();
+ assertTrue(spec instanceof WifiNetworkAgentSpecifier);
+ final WifiNetworkAgentSpecifier wnas = (WifiNetworkAgentSpecifier) spec;
+ assertTrue(wnas.satisfiesNetworkSpecifier(
+ new WifiNetworkSpecifier.Builder().setBand(ScanResult.WIFI_BAND_5_GHZ).build()));
}
/**
@@ -4368,6 +4379,7 @@
*/
@Test
public void verifyNetworkCapabilitiesForSpecificRequest() throws Exception {
+ mWifiInfo.setFrequency(2437);
when(mPerNetwork.getTxLinkBandwidthKbps()).thenReturn(30_000);
when(mPerNetwork.getRxLinkBandwidthKbps()).thenReturn(40_000);
when(mWifiNetworkFactory.isSpecificRequestInProgress(any(), any())).thenReturn(true);
@@ -4389,8 +4401,14 @@
assertTrue(networkSpecifier instanceof WifiNetworkAgentSpecifier);
WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
(WifiNetworkAgentSpecifier) networkSpecifier;
+
+ // createNetworkAgentSpecifier does not write the BSSID to the current wifi configuration.
+ WifiConfiguration expectedConfig = new WifiConfiguration(
+ mCmi.getConnectedWifiConfiguration());
+ expectedConfig.BSSID = TEST_BSSID_STR;
WifiNetworkAgentSpecifier expectedWifiNetworkAgentSpecifier =
- new WifiNetworkAgentSpecifier(mCmi.getConnectedWifiConfiguration());
+ new WifiNetworkAgentSpecifier(expectedConfig, ScanResult.WIFI_BAND_24_GHZ,
+ true /* matchLocalOnlySpecifiers */);
assertEquals(expectedWifiNetworkAgentSpecifier, wifiNetworkAgentSpecifier);
assertEquals(30_000, networkCapabilities.getLinkUpstreamBandwidthKbps());
assertEquals(40_000, networkCapabilities.getLinkDownstreamBandwidthKbps());
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
index 15729c8..01e255f 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
@@ -24,6 +24,7 @@
import android.content.pm.UserInfo;
import android.net.IpConfiguration;
import android.net.MacAddress;
+import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiManager;
@@ -609,6 +610,7 @@
WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL),
Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS),
+ ScanResult.UNSPECIFIED,
WifiConfigurationTestUtil.createOpenNetwork());
assertTrue(WifiConfigurationUtil.validateNetworkSpecifier(specifier));
}
@@ -622,6 +624,7 @@
WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB),
Pair.create(MacAddress.fromString(TEST_BSSID), MacAddress.BROADCAST_ADDRESS),
+ ScanResult.UNSPECIFIED,
WifiConfigurationTestUtil.createOpenNetwork());
assertTrue(WifiConfigurationUtil.validateNetworkSpecifier(specifier));
}
@@ -635,11 +638,28 @@
WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID), MacAddress.BROADCAST_ADDRESS),
+ ScanResult.UNSPECIFIED,
WifiConfigurationTestUtil.createOpenNetwork());
assertTrue(WifiConfigurationUtil.validateNetworkSpecifier(specifier));
}
/**
+ * Verify that the validate method validates a WifiNetworkSpecifier that specifies ssid, bssid,
+ * and band. Note that such requests will currently still be rejected by WifiNetworkFactory, but
+ * requesting specific bands may be supported in future releases.
+ */
+ @Test
+ public void testValidateNetworkSpecifierPositiveCases_SsidPatternAndBssidPatternAndBand() {
+ WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
+ new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL),
+ Pair.create(MacAddress.fromString(TEST_BSSID), MacAddress.BROADCAST_ADDRESS),
+ ScanResult.WIFI_BAND_5_GHZ,
+ WifiConfigurationTestUtil.createOpenNetwork());
+ assertTrue(WifiConfigurationUtil.validateNetworkSpecifier(specifier));
+ }
+
+
+ /**
* Verify that the validate method fails to validate WifiNetworkSpecifier with no
* ssid/bssid info.
*/
@@ -648,6 +668,7 @@
WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB),
Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS),
+ ScanResult.UNSPECIFIED,
WifiConfigurationTestUtil.createOpenNetwork());
assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier));
}
@@ -661,6 +682,7 @@
WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
new PatternMatcher("", PatternMatcher.PATTERN_LITERAL),
Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS),
+ ScanResult.UNSPECIFIED,
WifiConfigurationTestUtil.createOpenNetwork());
assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier));
}
@@ -674,6 +696,7 @@
WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL),
Pair.create(MacAddress.BROADCAST_ADDRESS, MacAddress.BROADCAST_ADDRESS),
+ ScanResult.UNSPECIFIED,
WifiConfigurationTestUtil.createOpenNetwork());
assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier));
}
@@ -687,6 +710,7 @@
WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID), WifiManager.ALL_ZEROS_MAC_ADDRESS),
+ ScanResult.UNSPECIFIED,
WifiConfigurationTestUtil.createOpenNetwork());
assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier));
}
@@ -700,11 +724,25 @@
WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_PREFIX),
Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS),
+ ScanResult.UNSPECIFIED,
WifiConfigurationTestUtil.createOpenHiddenNetwork());
assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier));
}
/**
+ * Verify that the validate method fails to validate WifiNetworkSpecifier with an invalid band.
+ */
+ @Test
+ public void testValidateNetworkSpecifierNegativeCases_InvalidBand() {
+ WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
+ new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL),
+ Pair.create(MacAddress.fromString(TEST_BSSID), MacAddress.BROADCAST_ADDRESS),
+ 42, // invalid
+ WifiConfigurationTestUtil.createOpenNetwork());
+ assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier));
+ }
+
+ /**
* Verify the instance of {@link android.net.wifi.WifiScanner.PnoSettings.PnoNetwork} created
* for an open network using {@link WifiConfigurationUtil#createPnoNetwork(
* WifiConfiguration)}.
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
index fa27119..880037b 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
@@ -363,6 +363,25 @@
}
/**
+ * Validates that requests that specify a frequency band are rejected.
+ */
+ @Test
+ public void testHandleAcceptNetworkRequestWithBand() throws Exception {
+ WifiNetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
+ .setBand(ScanResult.WIFI_BAND_5_GHZ)
+ .build();
+ mNetworkCapabilities.setNetworkSpecifier(specifier);
+ mNetworkRequest = new NetworkRequest.Builder()
+ .setCapabilities(mNetworkCapabilities)
+ .build();
+
+ // request should be rejected and released.
+ assertFalse(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
+ mLooper.dispatchAll();
+ verify(mConnectivityManager).declareNetworkRequestUnfulfillable(any());
+ }
+
+ /**
* Validates handling of acceptNetwork with a network specifier with invalid uid/package name.
*/
@Test
@@ -3432,7 +3451,8 @@
mNetworkCapabilities.setRequestorUid(uid);
mNetworkCapabilities.setRequestorPackageName(packageName);
mNetworkCapabilities.setNetworkSpecifier(
- new WifiNetworkSpecifier(ssidPatternMatch, bssidPatternMatch, wifiConfiguration));
+ new WifiNetworkSpecifier(ssidPatternMatch, bssidPatternMatch,
+ ScanResult.UNSPECIFIED, wifiConfiguration));
mNetworkRequest = new NetworkRequest.Builder()
.setCapabilities(mNetworkCapabilities)
.build();