diff --git a/wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java b/wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java index 87706b936f039..f73b9e5e2a00f 100644 --- a/wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java +++ b/wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java @@ -42,8 +42,10 @@ import java.util.List; 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 MATCH_NO_BSSID_PATTERN = + private static final Pair MATCH_NO_BSSID_PATTERN1 = new Pair(MacAddress.BROADCAST_ADDRESS, MacAddress.BROADCAST_ADDRESS); + private static final Pair MATCH_NO_BSSID_PATTERN2 = + new Pair(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.BROADCAST_ADDRESS); private static final Pair MATCH_ALL_BSSID_PATTERN = new Pair(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS); private static final MacAddress MATCH_EXACT_BSSID_PATTERN_MASK = @@ -189,7 +191,13 @@ public class WifiNetworkConfigBuilder { * Set the BSSID to use for filtering networks from scan results. Will only match network whose * BSSID is identical to the specified value. *

- *

  • Only allowed for creating network specifier, i.e {@link #buildNetworkSpecifier()}.
  • + *
  • 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.
  • + *
  • 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.
  • *
  • Overrides any previous value set using {@link #setBssid(MacAddress)} or * {@link #setBssidPattern(MacAddress, MacAddress)}.
  • * @@ -432,6 +440,9 @@ public class WifiNetworkConfigBuilder { 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; @@ -460,7 +471,10 @@ public class WifiNetworkConfigBuilder { && mSsidPatternMatcher.getPath().equals(MATCH_EMPTY_SSID_PATTERN_PATH)) { return true; } - if (mBssidPatternMatcher.equals(MATCH_NO_BSSID_PATTERN)) { + if (mBssidPatternMatcher.equals(MATCH_NO_BSSID_PATTERN1)) { + return true; + } + if (mBssidPatternMatcher.equals(MATCH_NO_BSSID_PATTERN2)) { return true; } return false; @@ -474,6 +488,16 @@ public class WifiNetworkConfigBuilder { 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; @@ -566,9 +590,42 @@ public class WifiNetworkConfigBuilder { } /** - * Create a network suggestion object use in - * {@link WifiManager#addNetworkSuggestions(List)}. + * Create a network suggestion object use in {@link WifiManager#addNetworkSuggestions(List)}. * See {@link WifiNetworkSuggestion}. + *

    + * 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. + *

    + * + * 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 suggestionsList = new ArrayList {{ + * 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. @@ -577,11 +634,14 @@ public class WifiNetworkConfigBuilder { if (mSsidPatternMatcher == null) { throw new IllegalStateException("setSsid should be invoked for suggestion"); } - if (mSsidPatternMatcher.getType() != PatternMatcher.PATTERN_LITERAL - || mBssidPatternMatcher != null) { - throw new IllegalStateException("none of setSsidPattern/setBssidPattern/setBssid are" + 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( diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java index 25121e2dc8c7d..760f1e6bc5e2a 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java +++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java @@ -104,8 +104,8 @@ public final class WifiNetworkSuggestion implements Parcelable { @Override public int hashCode() { - return Objects.hash(wifiConfiguration.SSID, wifiConfiguration.allowedKeyManagement, - suggestorUid); + return Objects.hash(wifiConfiguration.SSID, wifiConfiguration.BSSID, + wifiConfiguration.allowedKeyManagement, suggestorUid); } /** @@ -121,6 +121,7 @@ public final class WifiNetworkSuggestion implements Parcelable { } WifiNetworkSuggestion lhs = (WifiNetworkSuggestion) obj; return Objects.equals(this.wifiConfiguration.SSID, lhs.wifiConfiguration.SSID) + && Objects.equals(this.wifiConfiguration.BSSID, lhs.wifiConfiguration.BSSID) && Objects.equals(this.wifiConfiguration.allowedKeyManagement, lhs.wifiConfiguration.allowedKeyManagement) && suggestorUid == lhs.suggestorUid; diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkConfigBuilderTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkConfigBuilderTest.java index c455c6f0836db..2505499c85d78 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkConfigBuilderTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkConfigBuilderTest.java @@ -244,23 +244,56 @@ public class WifiNetworkConfigBuilderTest { * when match-none SSID pattern is set. */ @Test(expected = IllegalStateException.class) - public void testWifiNetworkSpecifierBuilderWithMatchNoneSsidPattern() { + 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 testWifiNetworkSpecifierBuilderWithMatchNoneBssidPattern() { + 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. @@ -429,13 +462,15 @@ public class WifiNetworkConfigBuilderTest { * {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} for OWE network. */ @Test - public void testWifiNetworkSuggestionBuilderForEnhancedOpenNetwork() { + 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); @@ -505,7 +540,7 @@ public class WifiNetworkConfigBuilderTest { /** * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} throws an exception - * when {@link WifiNetworkConfigBuilder#setBssid(MacAddress)} is set. + * when {@link WifiNetworkConfigBuilder#setBssidPattern(MacAddress, MacAddress)} is set. */ @Test(expected = IllegalStateException.class) public void testWifiNetworkSuggestionBuilderWithBssidPattern() { @@ -516,18 +551,6 @@ public class WifiNetworkConfigBuilderTest { .buildNetworkSuggestion(); } - /** - * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} throws an exception - * when {@link WifiNetworkConfigBuilder#setBssidPattern(MacAddress, MacAddress)} is set. - */ - @Test(expected = IllegalStateException.class) - public void testWifiNetworkSuggestionBuilderWithBssid() { - new WifiNetworkConfigBuilder() - .setSsid(TEST_SSID) - .setBssid(MacAddress.fromString(TEST_BSSID)) - .buildNetworkSuggestion(); - } - /** * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} throws an exception * when {@link WifiNetworkConfigBuilder#setSsid(String)} is not set. @@ -538,6 +561,41 @@ public class WifiNetworkConfigBuilderTest { .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. diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java index 6bab60dd480bd..5cc8217174622 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java @@ -29,6 +29,7 @@ import org.junit.Test; @SmallTest public class WifiNetworkSuggestionTest { 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\""; /** @@ -38,6 +39,7 @@ public class WifiNetworkSuggestionTest { public void testWifiNetworkSuggestionParcel() { WifiConfiguration configuration = new WifiConfiguration(); configuration.SSID = TEST_SSID; + configuration.BSSID = TEST_BSSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion(configuration, false, true, 0); @@ -65,18 +67,20 @@ public class WifiNetworkSuggestionTest { /** * Check NetworkSuggestion equals returns {@code true} for 2 network suggestions with the same - * SSID, key mgmt and UID. + * SSID, BSSID, key mgmt and UID. */ @Test public void testWifiNetworkSuggestionEqualsSame() { WifiConfiguration configuration = new WifiConfiguration(); configuration.SSID = TEST_SSID; + configuration.BSSID = TEST_BSSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion(configuration, true, false, 0); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID; + configuration1.BSSID = TEST_BSSID; configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); WifiNetworkSuggestion suggestion1 = new WifiNetworkSuggestion(configuration1, false, true, 0); @@ -86,7 +90,7 @@ public class WifiNetworkSuggestionTest { /** * Check NetworkSuggestion equals returns {@code false} for 2 network suggestions with the same - * key mgmt and UID, but different SSID. + * BSSID, key mgmt and UID, but different SSID. */ @Test public void testWifiNetworkSuggestionEqualsFailsWhenSsidIsDifferent() { @@ -107,7 +111,29 @@ public class WifiNetworkSuggestionTest { /** * Check NetworkSuggestion equals returns {@code false} for 2 network suggestions with the same - * SSID and UID, but different key mgmt. + * SSID, key mgmt and UID, but different BSSID. + */ + @Test + public void testWifiNetworkSuggestionEqualsFailsWhenBssidIsDifferent() { + WifiConfiguration configuration = new WifiConfiguration(); + configuration.SSID = TEST_SSID; + configuration.BSSID = TEST_BSSID; + configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); + WifiNetworkSuggestion suggestion = + new WifiNetworkSuggestion(configuration, false, false, 0); + + WifiConfiguration configuration1 = new WifiConfiguration(); + configuration1.SSID = TEST_SSID; + configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); + WifiNetworkSuggestion suggestion1 = + new WifiNetworkSuggestion(configuration1, false, false, 0); + + assertNotEquals(suggestion, suggestion1); + } + + /** + * Check NetworkSuggestion equals returns {@code false} for 2 network suggestions with the same + * SSID, BSSID and UID, but different key mgmt. */ @Test public void testWifiNetworkSuggestionEqualsFailsWhenKeyMgmtIsDifferent() { @@ -128,7 +154,7 @@ public class WifiNetworkSuggestionTest { /** * Check NetworkSuggestion equals returns {@code false} for 2 network suggestions with the same - * SSID and key mgmt, but different UID. + * SSID, BSSID and key mgmt, but different UID. */ @Test public void testWifiNetworkSuggestionEqualsFailsWhenUidIsDifferent() {