diff options
| -rwxr-xr-x | api/current.txt | 13 | ||||
| -rw-r--r-- | wifi/java/android/net/wifi/WifiManager.java | 60 | ||||
| -rw-r--r-- | wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java | 145 | ||||
| -rw-r--r-- | wifi/java/android/net/wifi/WifiNetworkSuggestion.java | 143 | ||||
| -rw-r--r-- | wifi/tests/src/android/net/wifi/WifiNetworkConfigBuilderTest.java | 191 | ||||
| -rw-r--r-- | wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java | 146 |
6 files changed, 690 insertions, 8 deletions
diff --git a/api/current.txt b/api/current.txt index 953859fbc2dd..6a2740f8b606 100755 --- a/api/current.txt +++ b/api/current.txt @@ -28753,6 +28753,7 @@ package android.net.wifi { public class WifiManager { method public int addNetwork(android.net.wifi.WifiConfiguration); + method public boolean addNetworkSuggestions(java.util.List<android.net.wifi.WifiNetworkSuggestion>, android.app.PendingIntent); method public void addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration); method public static int calculateSignalLevel(int, int); method public deprecated void cancelWps(android.net.wifi.WifiManager.WpsCallback); @@ -28781,6 +28782,7 @@ package android.net.wifi { method public boolean reassociate(); method public boolean reconnect(); method public boolean removeNetwork(int); + method public boolean removeNetworkSuggestions(java.util.List<android.net.wifi.WifiNetworkSuggestion>); method public void removePasspointConfiguration(java.lang.String); method public deprecated boolean saveConfiguration(); method public void setTdlsEnabled(java.net.InetAddress, boolean); @@ -28866,15 +28868,26 @@ package android.net.wifi { 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(android.net.MacAddress); method public android.net.wifi.WifiNetworkConfigBuilder setBssidPattern(android.net.MacAddress, android.net.MacAddress); method public android.net.wifi.WifiNetworkConfigBuilder setEnterpriseConfig(android.net.wifi.WifiEnterpriseConfig); + method public android.net.wifi.WifiNetworkConfigBuilder setIsAppInteractionRequired(); 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 setPskPassphrase(java.lang.String); method public android.net.wifi.WifiNetworkConfigBuilder setSsid(java.lang.String); method public android.net.wifi.WifiNetworkConfigBuilder setSsidPattern(android.os.PatternMatcher); } + public final class WifiNetworkSuggestion 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.WifiNetworkSuggestion> CREATOR; + } + public deprecated class WpsInfo implements android.os.Parcelable { ctor public deprecated WpsInfo(); ctor public deprecated WpsInfo(android.net.wifi.WpsInfo); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 9adbe67c1553..d4b98879f752 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -25,6 +25,7 @@ import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.UnsupportedAppUsage; +import android.app.PendingIntent; import android.content.Context; import android.content.pm.ParceledListSlice; import android.net.ConnectivityManager; @@ -1185,6 +1186,65 @@ public class WifiManager { } /** + * Provide a list of network suggestions to the device. See {@link WifiNetworkSuggestion} + * for a detailed explanation of the parameters. + *<p> + * When the device decides to connect to one of the provided network suggestions, platform fires + * the associated {@code pendingIntent} if + * {@link WifiNetworkSuggestion#isAppInteractionRequired} is {@code true} and the + * provided {@code pendingIntent} is non-null. + *<p> + * Registration of a non-null pending intent {@code pendingIntent} requires + * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or + * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission. + *<p> + * NOTE: + * <li> These networks are just a suggestion to the platform. The platform will ultimately + * decide on which network the device connects to. </li> + * <li> When an app is uninstalled, all its suggested networks are discarded. If the device is + * currently connected to a suggested network which is being removed then the device will + * disconnect from that network.</li> + * <li> No in-place modification of existing suggestions are allowed. Apps are expected to + * remove suggestions using {@link #removeNetworkSuggestions(List)} and then add the modified + * suggestion back using this API.</li> + * + * @param networkSuggestions List of network suggestions provided by the app. + * @param pendingIntent Pending intent to be fired post connection for networks. These will be + * fired only when connecting to a network which has the + * {@link WifiNetworkSuggestion#isAppInteractionRequired} flag set. + * Pending intent must hold a foreground service, else will be rejected. + * (i.e {@link PendingIntent#isForegroundService()} should return true) + * @return true on success, false if any of the suggestions match (See + * {@link WifiNetworkSuggestion#equals(Object)} any previously provided suggestions by the app. + * @throws {@link SecurityException} if the caller is missing required permissions. + */ + public boolean addNetworkSuggestions( + @NonNull List<WifiNetworkSuggestion> networkSuggestions, + @Nullable PendingIntent pendingIntent) { + // TODO(b/115504887): Implementation + return false; + } + + + /** + * Remove a subset of or all of networks from previously provided suggestions by the app to the + * device. + * See {@link WifiNetworkSuggestion} for a detailed explanation of the parameters. + * See {@link WifiNetworkSuggestion#equals(Object)} for the equivalence evaluation used. + * + * @param networkSuggestions List of network suggestions to be removed. Pass an empty list + * to remove all the previous suggestions provided by the app. + * @return true on success, false if any of the suggestions do not match any suggestions + * previously provided by the app. Any matching suggestions are removed from the device and + * will not be considered for any further connection attempts. + */ + public boolean removeNetworkSuggestions( + @NonNull List<WifiNetworkSuggestion> networkSuggestions) { + // TODO(b/115504887): Implementation + return false; + } + + /** * Add or update a Passpoint configuration. The configuration provides a credential * for connecting to Passpoint networks that are operated by the Passpoint * service provider specified in the configuration. diff --git a/wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java b/wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java index ed15e07c7a81..ae4f40511b58 100644 --- a/wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java +++ b/wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java @@ -20,6 +20,7 @@ import static com.android.internal.util.Preconditions.checkNotNull; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.PendingIntent; import android.net.MacAddress; import android.net.NetworkRequest; import android.net.NetworkSpecifier; @@ -30,11 +31,14 @@ 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, PendingIntent)}.</li> */ public class WifiNetworkConfigBuilder { private static final String MATCH_ALL_SSID_PATTERN_PATH = ".*"; @@ -45,6 +49,7 @@ public class WifiNetworkConfigBuilder { 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. @@ -69,6 +74,23 @@ public class WifiNetworkConfigBuilder { * 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; @@ -76,6 +98,10 @@ public class WifiNetworkConfigBuilder { mPskPassphrase = null; mEnterpriseConfig = null; mIsHiddenSSID = false; + mIsAppInteractionRequired = false; + mIsUserInteractionRequired = false; + mIsMetered = false; + mPriority = UNASSIGNED_PRIORITY; } /** @@ -103,6 +129,8 @@ public class WifiNetworkConfigBuilder { * {@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> * @@ -195,7 +223,7 @@ public class WifiNetworkConfigBuilder { } /** - * Whether this represents a hidden network. + * 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 @@ -212,6 +240,77 @@ public class WifiNetworkConfigBuilder { } /** + * Specifies whether the app needs to log in to a captive portal to obtain Internet access. + * <p> + * This will dictate if the associated pending intent in + * {@link WifiManager#addNetworkSuggestions(List, PendingIntent)} will be sent 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. + * This setting will be ignored if the {@code PendingIntent} used to add this network + * suggestion is null. + * <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. * @@ -260,6 +359,10 @@ public class WifiNetworkConfigBuilder { } wifiConfiguration.enterpriseConfig = mEnterpriseConfig; wifiConfiguration.hiddenSSID = mIsHiddenSSID; + wifiConfiguration.priority = mPriority; + wifiConfiguration.meteredOverride = + mIsMetered ? WifiConfiguration.METERED_OVERRIDE_METERED + : WifiConfiguration.METERED_OVERRIDE_NONE; return wifiConfiguration; } @@ -358,9 +461,15 @@ public class WifiNetworkConfigBuilder { 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"); + } if (!TextUtils.isEmpty(mPskPassphrase) && mEnterpriseConfig != null) { - throw new IllegalStateException("only one of setPskPassphrase or setEnterpriseConfig " - + "can be invoked for network specifier"); + throw new IllegalStateException("only one of setPreSharedKey or setEnterpriseConfig can" + + " be invoked for network specifier"); } return new WifiNetworkSpecifier( @@ -369,4 +478,34 @@ public class WifiNetworkConfigBuilder { buildWifiConfiguration(), Process.myUid()); } + + /** + * Create a network suggestion object use in + * {@link WifiManager#addNetworkSuggestions(List, PendingIntent)}. + * See {@link WifiNetworkSuggestion}. + * + * @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"); + } + if (mSsidPatternMatcher.getType() != PatternMatcher.PATTERN_LITERAL + || mBssidPatternMatcher != null) { + throw new IllegalStateException("none of setSsidPattern/setBssidPattern/setBssid are" + + " allowed for suggestion"); + } + if (!TextUtils.isEmpty(mPskPassphrase) && mEnterpriseConfig != null) { + throw new IllegalStateException("only one of setPreSharedKey or setEnterpriseConfig can" + + "be invoked for suggestion"); + } + + return new WifiNetworkSuggestion( + buildWifiConfiguration(), + mIsAppInteractionRequired, + mIsUserInteractionRequired, + Process.myUid()); + + } } diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java new file mode 100644 index 000000000000..04b9cb5dfb8d --- /dev/null +++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java @@ -0,0 +1,143 @@ +/* + * 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.app.PendingIntent; +import android.os.Parcel; +import android.os.Parcelable; + +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. + *<p> + * Apps can provide a list of such networks to the platform using + * {@link WifiManager#addNetworkSuggestions(List, PendingIntent)}. + */ +public final class WifiNetworkSuggestion implements Parcelable { + /** + * Network configuration for the provided network. + * @hide + */ + public final WifiConfiguration wifiConfiguration; + + /** + * Whether app needs to log in to captive portal to obtain Internet access. + * This will dictate if the associated pending intent in + * {@link WifiManager#addNetworkSuggestions(List, PendingIntent)} needs to be sent after + * successfully connecting to the network. + * @hide + */ + public final boolean isAppInteractionRequired; + + /** + * Whether user needs to log in to captive portal to obtain Internet access. + * @hide + */ + public final boolean isUserInteractionRequired; + + /** + * The UID of the process initializing this network suggestion. + * @hide + */ + public final int suggestorUid; + + /** @hide */ + public WifiNetworkSuggestion(WifiConfiguration wifiConfiguration, + boolean isAppInteractionRequired, + boolean isUserInteractionRequired, + int suggestorUid) { + checkNotNull(wifiConfiguration); + + this.wifiConfiguration = wifiConfiguration; + this.isAppInteractionRequired = isAppInteractionRequired; + this.isUserInteractionRequired = isUserInteractionRequired; + this.suggestorUid = suggestorUid; + } + + public static final Creator<WifiNetworkSuggestion> CREATOR = + new Creator<WifiNetworkSuggestion>() { + @Override + public WifiNetworkSuggestion createFromParcel(Parcel in) { + return new WifiNetworkSuggestion( + in.readParcelable(null), // wifiConfiguration + in.readBoolean(), // isAppInteractionRequired + in.readBoolean(), // isUserInteractionRequired + in.readInt() // suggestorUid + ); + } + + @Override + public WifiNetworkSuggestion[] newArray(int size) { + return new WifiNetworkSuggestion[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeParcelable(wifiConfiguration, flags); + dest.writeBoolean(isAppInteractionRequired); + dest.writeBoolean(isUserInteractionRequired); + dest.writeInt(suggestorUid); + } + + @Override + public int hashCode() { + return Objects.hash(wifiConfiguration.SSID, wifiConfiguration.allowedKeyManagement, + suggestorUid); + } + + /** + * Equals for network suggestions. + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof WifiNetworkSuggestion)) { + return false; + } + WifiNetworkSuggestion lhs = (WifiNetworkSuggestion) obj; + return Objects.equals(this.wifiConfiguration.SSID, lhs.wifiConfiguration.SSID) + && Objects.equals(this.wifiConfiguration.allowedKeyManagement, + lhs.wifiConfiguration.allowedKeyManagement) + && suggestorUid == lhs.suggestorUid; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("WifiNetworkSuggestion [") + .append(", WifiConfiguration=").append(wifiConfiguration) + .append(", isAppInteractionRequired=").append(isAppInteractionRequired) + .append(", isUserInteractionRequired=").append(isUserInteractionRequired) + .append(", suggestorUid=").append(suggestorUid) + .append("]"); + return sb.toString(); + } +} diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkConfigBuilderTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkConfigBuilderTest.java index 6615727f533e..8980ddba238b 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkConfigBuilderTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkConfigBuilderTest.java @@ -21,6 +21,7 @@ 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.assertTrue; import android.net.MacAddress; @@ -261,6 +262,19 @@ public class WifiNetworkConfigBuilderTest { /** * 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#setPskPassphrase(String)} and * {@link WifiNetworkConfigBuilder#setEnterpriseConfig(WifiEnterpriseConfig)} are invoked. */ @@ -287,14 +301,181 @@ public class WifiNetworkConfigBuilderTest { /** * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception - * when SSID pattern is set for hidden network. + * when {@link WifiNetworkConfigBuilder#setIsAppInteractionRequired()} is set. */ @Test(expected = IllegalStateException.class) - public void testWifiNetworkSpecifierBuilderWithBssidMatchPatternForHiddenNetwork() { + public void testWifiNetworkSpecifierBuilderWithRequiredAppInteraction() { new WifiNetworkConfigBuilder() - .setBssidPattern(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), - MacAddress.fromString(TEST_BSSID_OUI_MASK)) - .setIsHiddenSsid() + .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 testWifiNetworkSuggestionBuilderForWpaEapNetworkWithPriorityAndReqAppInteraction() { + WifiNetworkSuggestion suggestion = new WifiNetworkConfigBuilder() + .setSsid(TEST_SSID) + .setPskPassphrase(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 testWifiNetworkSuggestionBuilderForWpaPskNetworkWithMeteredAndReqUserInteraction() { + WifiNetworkSuggestion suggestion = new WifiNetworkConfigBuilder() + .setSsid(TEST_SSID) + .setPskPassphrase(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); + } + + /** + * 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#setBssid(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#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. + */ + @Test(expected = IllegalStateException.class) + public void testWifiNetworkSuggestionBuilderWithNoSsid() { + new WifiNetworkConfigBuilder() + .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(); + } } diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java new file mode 100644 index 000000000000..6bab60dd480b --- /dev/null +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java @@ -0,0 +1,146 @@ +/* + * 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 org.junit.Assert.*; + +import android.os.Parcel; +import android.support.test.filters.SmallTest; + +import org.junit.Test; + +/** + * Unit tests for {@link android.net.wifi.WifiNetworkSuggestion}. + */ +@SmallTest +public class WifiNetworkSuggestionTest { + private static final String TEST_SSID = "\"Test123\""; + private static final String TEST_SSID_1 = "\"Test1234\""; + + /** + * Check that parcel marshalling/unmarshalling works + */ + @Test + public void testWifiNetworkSuggestionParcel() { + WifiConfiguration configuration = new WifiConfiguration(); + configuration.SSID = TEST_SSID; + configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); + WifiNetworkSuggestion suggestion = + new WifiNetworkSuggestion(configuration, false, true, 0); + + Parcel parcelW = Parcel.obtain(); + suggestion.writeToParcel(parcelW, 0); + byte[] bytes = parcelW.marshall(); + parcelW.recycle(); + + Parcel parcelR = Parcel.obtain(); + parcelR.unmarshall(bytes, 0, bytes.length); + parcelR.setDataPosition(0); + WifiNetworkSuggestion parcelSuggestion = + WifiNetworkSuggestion.CREATOR.createFromParcel(parcelR); + + // Two suggestion objects are considered equal if they point to the same network (i.e same + // SSID + keyMgmt + same UID). |isAppInteractionRequired| & |isUserInteractionRequired| are + // not considered for equality and hence needs to be checked for explicitly below. + assertEquals(suggestion, parcelSuggestion); + assertEquals(suggestion.isAppInteractionRequired, + parcelSuggestion.isAppInteractionRequired); + assertEquals(suggestion.isUserInteractionRequired, + parcelSuggestion.isUserInteractionRequired); + } + + /** + * Check NetworkSuggestion equals returns {@code true} for 2 network suggestions with the same + * SSID, key mgmt and UID. + */ + @Test + public void testWifiNetworkSuggestionEqualsSame() { + WifiConfiguration configuration = new WifiConfiguration(); + configuration.SSID = TEST_SSID; + configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); + WifiNetworkSuggestion suggestion = + new WifiNetworkSuggestion(configuration, true, false, 0); + + WifiConfiguration configuration1 = new WifiConfiguration(); + configuration1.SSID = TEST_SSID; + configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); + WifiNetworkSuggestion suggestion1 = + new WifiNetworkSuggestion(configuration1, false, true, 0); + + assertEquals(suggestion, suggestion1); + } + + /** + * Check NetworkSuggestion equals returns {@code false} for 2 network suggestions with the same + * key mgmt and UID, but different SSID. + */ + @Test + public void testWifiNetworkSuggestionEqualsFailsWhenSsidIsDifferent() { + WifiConfiguration configuration = new WifiConfiguration(); + configuration.SSID = TEST_SSID; + configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); + WifiNetworkSuggestion suggestion = + new WifiNetworkSuggestion(configuration, false, false, 0); + + WifiConfiguration configuration1 = new WifiConfiguration(); + configuration1.SSID = TEST_SSID_1; + configuration.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 and UID, but different key mgmt. + */ + @Test + public void testWifiNetworkSuggestionEqualsFailsWhenKeyMgmtIsDifferent() { + WifiConfiguration configuration = new WifiConfiguration(); + configuration.SSID = TEST_SSID; + 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.WPA_PSK); + 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 and key mgmt, but different UID. + */ + @Test + public void testWifiNetworkSuggestionEqualsFailsWhenUidIsDifferent() { + WifiConfiguration configuration = new WifiConfiguration(); + configuration.SSID = TEST_SSID; + configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); + WifiNetworkSuggestion suggestion = + new WifiNetworkSuggestion(configuration, false, false, 0); + + WifiNetworkSuggestion suggestion1 = + new WifiNetworkSuggestion(configuration, false, false, 1); + + assertNotEquals(suggestion, suggestion1); + } +} |