Merge changes from topic "network_request_match_callback"

* changes:
  WifiManager: Network request match callback registration
  wifi(API): NetworkSpecifier for Wifi NetworkAgent
  wifi(API): Mark old API's deprecated
  wifi(API): New API surface for network suggestion
  wifi(API): New API surface for connection via NetworkRequest
This commit is contained in:
Roshan Pius
2018-11-06 17:42:58 +00:00
committed by Android (Google) Code Review
19 changed files with 2974 additions and 37 deletions

View File

@@ -595,6 +595,8 @@ java_defaults {
"telephony/java/com/android/internal/telephony/euicc/ISetDefaultSmdpAddressCallback.aidl",
"telephony/java/com/android/internal/telephony/euicc/ISetNicknameCallback.aidl",
"telephony/java/com/android/internal/telephony/euicc/ISwitchToProfileCallback.aidl",
"wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl",
"wifi/java/android/net/wifi/INetworkRequestUserSelectionCallback.aidl",
"wifi/java/android/net/wifi/ISoftApCallback.aidl",
"wifi/java/android/net/wifi/ITrafficStateCallback.aidl",
"wifi/java/android/net/wifi/IWifiManager.aidl",

View File

@@ -28690,7 +28690,7 @@ package android.net.wifi {
enum_constant public static final android.net.wifi.SupplicantState UNINITIALIZED;
}
public class WifiConfiguration implements android.os.Parcelable {
public deprecated class WifiConfiguration implements android.os.Parcelable {
ctor public WifiConfiguration();
method public int describeContents();
method public android.net.ProxyInfo getHttpProxy();
@@ -28844,7 +28844,8 @@ package android.net.wifi {
}
public class WifiManager {
method public int addNetwork(android.net.wifi.WifiConfiguration);
method public deprecated 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);
@@ -28852,10 +28853,10 @@ package android.net.wifi {
method public android.net.wifi.WifiManager.MulticastLock createMulticastLock(java.lang.String);
method public android.net.wifi.WifiManager.WifiLock createWifiLock(int, java.lang.String);
method public android.net.wifi.WifiManager.WifiLock createWifiLock(java.lang.String);
method public boolean disableNetwork(int);
method public boolean disconnect();
method public boolean enableNetwork(int, boolean);
method public java.util.List<android.net.wifi.WifiConfiguration> getConfiguredNetworks();
method public deprecated boolean disableNetwork(int);
method public deprecated boolean disconnect();
method public deprecated boolean enableNetwork(int, boolean);
method public deprecated java.util.List<android.net.wifi.WifiConfiguration> getConfiguredNetworks();
method public android.net.wifi.WifiInfo getConnectionInfo();
method public android.net.DhcpInfo getDhcpInfo();
method public java.util.List<android.net.wifi.hotspot2.PasspointConfiguration> getPasspointConfigurations();
@@ -28870,18 +28871,19 @@ package android.net.wifi {
method public boolean isTdlsSupported();
method public boolean isWifiEnabled();
method public deprecated boolean pingSupplicant();
method public boolean reassociate();
method public boolean reconnect();
method public boolean removeNetwork(int);
method public deprecated boolean reassociate();
method public deprecated boolean reconnect();
method public deprecated 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);
method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
method public boolean setWifiEnabled(boolean);
method public deprecated boolean setWifiEnabled(boolean);
method public void startLocalOnlyHotspot(android.net.wifi.WifiManager.LocalOnlyHotspotCallback, android.os.Handler);
method public deprecated boolean startScan();
method public deprecated void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback);
method public int updateNetwork(android.net.wifi.WifiConfiguration);
method public deprecated int updateNetwork(android.net.wifi.WifiConfiguration);
field public static final java.lang.String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
field public static final java.lang.String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE = "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE";
field public static final deprecated int ERROR_AUTHENTICATING = 1; // 0x1
@@ -28955,6 +28957,29 @@ package android.net.wifi {
method public abstract deprecated void onSucceeded();
}
public class WifiNetworkConfigBuilder {
ctor public WifiNetworkConfigBuilder();
method public android.net.NetworkSpecifier buildNetworkSpecifier();
method public android.net.wifi.WifiNetworkSuggestion buildNetworkSuggestion();
method public android.net.wifi.WifiNetworkConfigBuilder setBssid(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);

View File

@@ -3615,7 +3615,7 @@ package android.net.wifi {
field public byte id;
}
public class WifiConfiguration implements android.os.Parcelable {
public deprecated class WifiConfiguration implements android.os.Parcelable {
method public boolean hasNoInternetAccess();
method public boolean isEphemeral();
method public boolean isNoInternetAccessExpected();
@@ -3644,8 +3644,10 @@ package android.net.wifi {
method public boolean isPortableHotspotSupported();
method public boolean isWifiApEnabled();
method public boolean isWifiScannerSupported();
method public void registerNetworkRequestMatchCallback(android.net.wifi.WifiManager.NetworkRequestMatchCallback, android.os.Handler);
method public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration);
method public boolean startScan(android.os.WorkSource);
method public void unregisterNetworkRequestMatchCallback(android.net.wifi.WifiManager.NetworkRequestMatchCallback);
field public static final int CHANGE_REASON_ADDED = 0; // 0x0
field public static final int CHANGE_REASON_CONFIG_CHANGE = 2; // 0x2
field public static final int CHANGE_REASON_REMOVED = 1; // 0x1
@@ -3673,6 +3675,18 @@ package android.net.wifi {
method public abstract void onSuccess();
}
public static abstract interface WifiManager.NetworkRequestMatchCallback {
method public abstract void onMatch(java.util.List<android.net.wifi.WifiConfiguration>);
method public abstract void onUserSelectionCallbackRegistration(android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback);
method public abstract void onUserSelectionConnectFailure(android.net.wifi.WifiConfiguration);
method public abstract void onUserSelectionConnectSuccess(android.net.wifi.WifiConfiguration);
}
public static abstract interface WifiManager.NetworkRequestUserSelectionCallback {
method public abstract void reject();
method public abstract void select(android.net.wifi.WifiConfiguration);
}
public class WifiNetworkConnectionStatistics implements android.os.Parcelable {
ctor public WifiNetworkConnectionStatistics(int, int);
ctor public WifiNetworkConnectionStatistics();

View File

@@ -393,4 +393,19 @@ public final class MacAddress implements Parcelable {
}
return out;
}
/**
* Checks if this MAC Address matches the provided range.
*
* @param baseAddress MacAddress representing the base address to compare with.
* @param mask MacAddress representing the mask to use during comparison.
* @return true if this MAC Address matches the given range.
*
* @hide
*/
public boolean matches(@NonNull MacAddress baseAddress, @NonNull MacAddress mask) {
Preconditions.checkNotNull(baseAddress);
Preconditions.checkNotNull(mask);
return (mAddr & mask.mAddr) == (baseAddress.mAddr & mask.mAddr);
}
}

View File

@@ -17,8 +17,8 @@
package android.net;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.support.test.filters.SmallTest;
@@ -252,6 +252,39 @@ public class MacAddressTest {
}
}
@Test
public void testMatches() {
// match 4 bytes prefix
assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
MacAddress.fromString("aa:bb:cc:dd:00:00"),
MacAddress.fromString("ff:ff:ff:ff:00:00")));
// match bytes 0,1,2 and 5
assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
MacAddress.fromString("aa:bb:cc:00:00:11"),
MacAddress.fromString("ff:ff:ff:00:00:ff")));
// match 34 bit prefix
assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
MacAddress.fromString("aa:bb:cc:dd:c0:00"),
MacAddress.fromString("ff:ff:ff:ff:c0:00")));
// fail to match 36 bit prefix
assertFalse(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
MacAddress.fromString("aa:bb:cc:dd:40:00"),
MacAddress.fromString("ff:ff:ff:ff:f0:00")));
// match all 6 bytes
assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
MacAddress.fromString("aa:bb:cc:dd:ee:11"),
MacAddress.fromString("ff:ff:ff:ff:ff:ff")));
// match none of 6 bytes
assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
MacAddress.fromString("00:00:00:00:00:00"),
MacAddress.fromString("00:00:00:00:00:00")));
}
static byte[] toByteArray(int... in) {
byte[] out = new byte[in.length];
for (int i = 0; i < in.length; i++) {

View File

@@ -0,0 +1,36 @@
/*
* 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 android.net.wifi.INetworkRequestUserSelectionCallback;
import android.net.wifi.WifiConfiguration;
/**
* Interface for network request match callback.
*
* @hide
*/
oneway interface INetworkRequestMatchCallback
{
void onUserSelectionCallbackRegistration(in INetworkRequestUserSelectionCallback userSelectionCallback);
void onMatch(in List<WifiConfiguration> wificonfigurations);
void onUserSelectionConnectSuccess(in WifiConfiguration wificonfiguration);
void onUserSelectionConnectFailure(in WifiConfiguration wificonfiguration);
}

View File

@@ -0,0 +1,31 @@
/*
* 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 android.net.wifi.WifiConfiguration;
/**
* Interface for providing user selection in response to
* network request match callback.
* @hide
*/
oneway interface INetworkRequestUserSelectionCallback
{
void select(in WifiConfiguration wificonfiguration);
void reject();
}

View File

@@ -25,6 +25,7 @@ import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.DhcpInfo;
import android.net.Network;
import android.net.wifi.INetworkRequestMatchCallback;
import android.net.wifi.ISoftApCallback;
import android.net.wifi.ITrafficStateCallback;
import android.net.wifi.PasspointManagementObjectDefinition;
@@ -185,5 +186,9 @@ interface IWifiManager
void registerTrafficStateCallback(in IBinder binder, in ITrafficStateCallback callback, int callbackIdentifier);
void unregisterTrafficStateCallback(int callbackIdentifier);
void registerNetworkRequestMatchCallback(in IBinder binder, in INetworkRequestMatchCallback callback, int callbackIdentifier);
void unregisterNetworkRequestMatchCallback(int callbackIdentifier);
}

View File

@@ -47,7 +47,11 @@ import java.util.HashMap;
/**
* A class representing a configured Wi-Fi network, including the
* security configuration.
*
* @deprecated Use {@link WifiNetworkConfigBuilder} to create {@link NetworkSpecifier} and
* {@link WifiNetworkSuggestion}. This will become a system use only object in the future.
*/
@Deprecated
public class WifiConfiguration implements Parcelable {
private static final String TAG = "WifiConfiguration";
/**

View File

@@ -25,19 +25,17 @@ 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;
import android.net.DhcpInfo;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.wifi.hotspot2.OsuProvider;
import android.net.wifi.hotspot2.PasspointConfiguration;
import android.net.wifi.hotspot2.ProvisioningCallback;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -52,7 +50,6 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
import com.android.server.net.NetworkPinner;
import dalvik.system.CloseGuard;
@@ -1035,7 +1032,17 @@ public class WifiManager {
* </ul>
* @return a list of network configurations in the form of a list
* of {@link WifiConfiguration} objects.
*
* @deprecated
* a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
* mechanism to trigger connection to a Wi-Fi network.
* b) See {@link #addNetworkSuggestions(List, PendingIntent)},
* {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
* when auto-connecting to wifi.
* <b>Compatibility Note:</b> For applications targeting
* {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return an empty list.
*/
@Deprecated
public List<WifiConfiguration> getConfiguredNetworks() {
try {
ParceledListSlice<WifiConfiguration> parceledList =
@@ -1135,7 +1142,17 @@ public class WifiManager {
* @return the ID of the newly created network description. This is used in
* other operations to specified the network to be acted upon.
* Returns {@code -1} on failure.
*
* @deprecated
* a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
* mechanism to trigger connection to a Wi-Fi network.
* b) See {@link #addNetworkSuggestions(List, PendingIntent)},
* {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
* when auto-connecting to wifi.
* <b>Compatibility Note:</b> For applications targeting
* {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return {@code -1}.
*/
@Deprecated
public int addNetwork(WifiConfiguration config) {
if (config == null) {
return -1;
@@ -1160,7 +1177,17 @@ public class WifiManager {
* Returns {@code -1} on failure, including when the {@code networkId}
* field of the {@code WifiConfiguration} does not refer to an
* existing network.
*
* @deprecated
* a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
* mechanism to trigger connection to a Wi-Fi network.
* b) See {@link #addNetworkSuggestions(List, PendingIntent)},
* {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
* when auto-connecting to wifi.
* <b>Compatibility Note:</b> For applications targeting
* {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return {@code -1}.
*/
@Deprecated
public int updateNetwork(WifiConfiguration config) {
if (config == null || config.networkId < 0) {
return -1;
@@ -1184,6 +1211,302 @@ public class WifiManager {
}
}
/**
* Interface for indicating user selection from the list of networks presented in the
* {@link NetworkRequestMatchCallback#onMatch(List)}.
*
* The platform will implement this callback and pass it along with the
* {@link NetworkRequestMatchCallback#onUserSelectionCallbackRegistration(
* NetworkRequestUserSelectionCallback)}. The UI component handling
* {@link NetworkRequestMatchCallback} will invoke {@link #select(WifiConfiguration)} or
* {@link #reject()} to return the user's selection back to the platform via this callback.
* @hide
*/
@SystemApi
public interface NetworkRequestUserSelectionCallback {
/**
* User selected this network to connect to.
* @param wifiConfiguration WifiConfiguration object corresponding to the network
* user selected.
*/
void select(@NonNull WifiConfiguration wifiConfiguration);
/**
* User rejected the app's request.
*/
void reject();
}
/**
* Interface for network request callback. Should be implemented by applications and passed when
* calling {@link #registerNetworkRequestMatchCallback(NetworkRequestMatchCallback, Handler)}.
*
* This is meant to be implemented by a UI component to present the user with a list of networks
* matching the app's request. The user is allowed to pick one of these networks to connect to
* or reject the request by the app.
* @hide
*/
@SystemApi
public interface NetworkRequestMatchCallback {
/**
* Invoked to register a callback to be invoked to convey user selection. The callback
* object paased in this method is to be invoked by the UI component after the service sends
* a list of matching scan networks using {@link #onMatch(List)} and user picks a network
* from that list.
*
* @param userSelectionCallback Callback object to send back the user selection.
*/
void onUserSelectionCallbackRegistration(
@NonNull NetworkRequestUserSelectionCallback userSelectionCallback);
/**
* Invoked when a network request initiated by an app matches some networks in scan results.
* This may be invoked multiple times for a single network request as the platform finds new
* networks in scan results.
*
* @param wifiConfigurations List of {@link WifiConfiguration} objects corresponding to the
* networks matching the request.
*/
void onMatch(@NonNull List<WifiConfiguration> wifiConfigurations);
/**
* Invoked on a successful connection with the network that the user selected
* via {@link NetworkRequestUserSelectionCallback}.
*
* @param wifiConfiguration WifiConfiguration object corresponding to the network that the
* user selected.
*/
void onUserSelectionConnectSuccess(@NonNull WifiConfiguration wifiConfiguration);
/**
* Invoked on failure to establish connection with the network that the user selected
* via {@link NetworkRequestUserSelectionCallback}.
*
* @param wifiConfiguration WifiConfiguration object corresponding to the network
* user selected.
*/
void onUserSelectionConnectFailure(@NonNull WifiConfiguration wifiConfiguration);
}
/**
* Callback proxy for NetworkRequestUserSelectionCallback objects.
* @hide
*/
private class NetworkRequestUserSelectionCallbackProxy implements
NetworkRequestUserSelectionCallback {
private final INetworkRequestUserSelectionCallback mCallback;
NetworkRequestUserSelectionCallbackProxy(
INetworkRequestUserSelectionCallback callback) {
mCallback = callback;
}
@Override
public void select(@NonNull WifiConfiguration wifiConfiguration) {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "NetworkRequestUserSelectionCallbackProxy: select "
+ "wificonfiguration: " + wifiConfiguration);
}
try {
mCallback.select(wifiConfiguration);
} catch (RemoteException e) {
Log.e(TAG, "Failed to invoke onSelected", e);
throw e.rethrowFromSystemServer();
}
}
@Override
public void reject() {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "NetworkRequestUserSelectionCallbackProxy: reject");
}
try {
mCallback.reject();
} catch (RemoteException e) {
Log.e(TAG, "Failed to invoke onRejected", e);
throw e.rethrowFromSystemServer();
}
}
}
/**
* Callback proxy for NetworkRequestMatchCallback objects.
* @hide
*/
private class NetworkRequestMatchCallbackProxy extends INetworkRequestMatchCallback.Stub {
private final Handler mHandler;
private final NetworkRequestMatchCallback mCallback;
NetworkRequestMatchCallbackProxy(Looper looper, NetworkRequestMatchCallback callback) {
mHandler = new Handler(looper);
mCallback = callback;
}
@Override
public void onUserSelectionCallbackRegistration(
INetworkRequestUserSelectionCallback userSelectionCallback) {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "NetworkRequestMatchCallbackProxy: "
+ "onUserSelectionCallbackRegistration callback: " + userSelectionCallback);
}
mHandler.post(() -> {
mCallback.onUserSelectionCallbackRegistration(
new NetworkRequestUserSelectionCallbackProxy(userSelectionCallback));
});
}
@Override
public void onMatch(List<WifiConfiguration> wifiConfigurations) {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "NetworkRequestMatchCallbackProxy: onMatch wificonfigurations: "
+ wifiConfigurations);
}
mHandler.post(() -> {
mCallback.onMatch(wifiConfigurations);
});
}
@Override
public void onUserSelectionConnectSuccess(WifiConfiguration wifiConfiguration) {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "NetworkRequestMatchCallbackProxy: onUserSelectionConnectSuccess "
+ " wificonfiguration: " + wifiConfiguration);
}
mHandler.post(() -> {
mCallback.onUserSelectionConnectSuccess(wifiConfiguration);
});
}
@Override
public void onUserSelectionConnectFailure(WifiConfiguration wifiConfiguration) {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "NetworkRequestMatchCallbackProxy: onUserSelectionConnectFailure"
+ " wificonfiguration: " + wifiConfiguration);
}
mHandler.post(() -> {
mCallback.onUserSelectionConnectFailure(wifiConfiguration);
});
}
}
/**
* Registers a callback for NetworkRequest matches. See {@link NetworkRequestMatchCallback}.
* Caller can unregister a previously registered callback using
* {@link #unregisterNetworkRequestMatchCallback(NetworkRequestMatchCallback)}
* <p>
* Applications should have the
* {@link android.Manifest.permission#NETWORK_SETTINGS} permission. Callers
* without the permission will trigger a {@link java.lang.SecurityException}.
* <p>
*
* @param callback Callback for network match events
* @param handler The Handler on whose thread to execute the callbacks of the {@code callback}
* object. If null, then the application's main thread will be used.
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
public void registerNetworkRequestMatchCallback(@NonNull NetworkRequestMatchCallback callback,
@Nullable Handler handler) {
if (callback == null) throw new IllegalArgumentException("callback cannot be null");
Log.v(TAG, "registerNetworkRequestMatchCallback: callback=" + callback
+ ", handler=" + handler);
Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper();
Binder binder = new Binder();
try {
mService.registerNetworkRequestMatchCallback(
binder, new NetworkRequestMatchCallbackProxy(looper, callback),
callback.hashCode());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Unregisters a callback for NetworkRequest matches. See {@link NetworkRequestMatchCallback}.
* <p>
* Applications should have the
* {@link android.Manifest.permission#NETWORK_SETTINGS} permission. Callers
* without the permission will trigger a {@link java.lang.SecurityException}.
* <p>
*
* @param callback Callback for network match events
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
public void unregisterNetworkRequestMatchCallback(
@NonNull NetworkRequestMatchCallback callback) {
if (callback == null) throw new IllegalArgumentException("callback cannot be null");
Log.v(TAG, "unregisterNetworkRequestMatchCallback: callback=" + callback);
try {
mService.unregisterNetworkRequestMatchCallback(callback.hashCode());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* 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
@@ -1299,7 +1622,17 @@ public class WifiManager {
* @param netId the ID of the network as returned by {@link #addNetwork} or {@link
* #getConfiguredNetworks}.
* @return {@code true} if the operation succeeded
*
* @deprecated
* a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
* mechanism to trigger connection to a Wi-Fi network.
* b) See {@link #addNetworkSuggestions(List, PendingIntent)},
* {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
* when auto-connecting to wifi.
* <b>Compatibility Note:</b> For applications targeting
* {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false.
*/
@Deprecated
public boolean removeNetwork(int netId) {
try {
return mService.removeNetwork(netId, mContext.getOpPackageName());
@@ -1314,10 +1647,8 @@ public class WifiManager {
* network is initiated. This may result in the asynchronous delivery
* of state change events.
* <p>
* <b>Note:</b> If an application's target SDK version is
* {@link android.os.Build.VERSION_CODES#LOLLIPOP} or newer, network
* communication may not use Wi-Fi even if Wi-Fi is connected; traffic may
* instead be sent through another network, such as cellular data,
* <b>Note:</b> Network communication may not use Wi-Fi even if Wi-Fi is connected;
* traffic may instead be sent through another network, such as cellular data,
* Bluetooth tethering, or Ethernet. For example, traffic will never use a
* Wi-Fi network that does not provide Internet access (e.g. a wireless
* printer), if another network that does offer Internet access (e.g.
@@ -1335,29 +1666,24 @@ public class WifiManager {
* @param attemptConnect The way to select a particular network to connect to is specify
* {@code true} for this parameter.
* @return {@code true} if the operation succeeded
*
* @deprecated
* a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
* mechanism to trigger connection to a Wi-Fi network.
* b) See {@link #addNetworkSuggestions(List, PendingIntent)},
* {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
* when auto-connecting to wifi.
* <b>Compatibility Note:</b> For applications targeting
* {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false.
*/
@Deprecated
public boolean enableNetwork(int netId, boolean attemptConnect) {
final boolean pin = attemptConnect && mTargetSdkVersion < Build.VERSION_CODES.LOLLIPOP;
if (pin) {
NetworkRequest request = new NetworkRequest.Builder()
.clearCapabilities()
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.build();
NetworkPinner.pin(mContext, request);
}
boolean success;
try {
success = mService.enableNetwork(netId, attemptConnect, mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
if (pin && !success) {
NetworkPinner.unpin();
}
return success;
}
@@ -1372,7 +1698,17 @@ public class WifiManager {
* @param netId the ID of the network as returned by {@link #addNetwork} or {@link
* #getConfiguredNetworks}.
* @return {@code true} if the operation succeeded
*
* @deprecated
* a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
* mechanism to trigger connection to a Wi-Fi network.
* b) See {@link #addNetworkSuggestions(List, PendingIntent)},
* {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
* when auto-connecting to wifi.
* <b>Compatibility Note:</b> For applications targeting
* {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false.
*/
@Deprecated
public boolean disableNetwork(int netId) {
try {
return mService.disableNetwork(netId, mContext.getOpPackageName());
@@ -1385,7 +1721,17 @@ public class WifiManager {
* Disassociate from the currently active access point. This may result
* in the asynchronous delivery of state change events.
* @return {@code true} if the operation succeeded
*
* @deprecated
* a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
* mechanism to trigger connection to a Wi-Fi network.
* b) See {@link #addNetworkSuggestions(List, PendingIntent)},
* {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
* when auto-connecting to wifi.
* <b>Compatibility Note:</b> For applications targeting
* {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false.
*/
@Deprecated
public boolean disconnect() {
try {
mService.disconnect(mContext.getOpPackageName());
@@ -1400,7 +1746,17 @@ public class WifiManager {
* disconnected. This may result in the asynchronous delivery of state
* change events.
* @return {@code true} if the operation succeeded
*
* @deprecated
* a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
* mechanism to trigger connection to a Wi-Fi network.
* b) See {@link #addNetworkSuggestions(List, PendingIntent)},
* {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
* when auto-connecting to wifi.
* <b>Compatibility Note:</b> For applications targeting
* {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false.
*/
@Deprecated
public boolean reconnect() {
try {
mService.reconnect(mContext.getOpPackageName());
@@ -1415,7 +1771,17 @@ public class WifiManager {
* connected. This may result in the asynchronous delivery of state
* change events.
* @return {@code true} if the operation succeeded
*
* @deprecated
* a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
* mechanism to trigger connection to a Wi-Fi network.
* b) See {@link #addNetworkSuggestions(List, PendingIntent)},
* {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
* when auto-connecting to wifi.
* <b>Compatibility Note:</b> For applications targeting
* {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false.
*/
@Deprecated
public boolean reassociate() {
try {
mService.reassociate(mContext.getOpPackageName());
@@ -1821,7 +2187,12 @@ public class WifiManager {
* @return {@code false} if the request cannot be satisfied; {@code true} indicates that wifi is
* either already in the requested state, or in progress toward the requested state.
* @throws {@link java.lang.SecurityException} if the caller is missing required permissions.
*
* @deprecated Starting with Build.VERSION_CODES#Q, applications are not allowed to
* enable/disable Wi-Fi regardless of application's target SDK. This API will have no effect
* and will always return false.
*/
@Deprecated
public boolean setWifiEnabled(boolean enabled) {
try {
return mService.setWifiEnabled(mContext.getOpPackageName(), enabled);

View File

@@ -0,0 +1,187 @@
/*
* 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 static com.android.internal.util.Preconditions.checkState;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.net.MacAddress;
import android.net.MatchAllNetworkSpecifier;
import android.net.NetworkAgent;
import android.net.NetworkRequest;
import android.net.NetworkSpecifier;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Objects;
/**
* Network specifier object used by wifi's {@link android.net.NetworkAgent}.
* @hide
*/
public final class WifiNetworkAgentSpecifier extends NetworkSpecifier implements Parcelable {
/**
* Security credentials for the currently connected network.
*/
private final WifiConfiguration mWifiConfiguration;
/**
* The UID of the app that requested a specific wifi network using {@link WifiNetworkSpecifier}.
*
* Will only be filled when the device connects to a wifi network as a result of a
* {@link NetworkRequest} with {@link WifiNetworkSpecifier}. Will be set to -1 if the device
* auto-connected to a wifi network.
*/
private final int mOriginalRequestorUid;
public WifiNetworkAgentSpecifier(@NonNull WifiConfiguration wifiConfiguration,
int originalRequestorUid) {
checkNotNull(wifiConfiguration);
mWifiConfiguration = wifiConfiguration;
mOriginalRequestorUid = originalRequestorUid;
}
/**
* @hide
*/
public static final Creator<WifiNetworkAgentSpecifier> CREATOR =
new Creator<WifiNetworkAgentSpecifier>() {
@Override
public WifiNetworkAgentSpecifier createFromParcel(@NonNull Parcel in) {
WifiConfiguration wifiConfiguration = in.readParcelable(null);
int originalRequestorUid = in.readInt();
return new WifiNetworkAgentSpecifier(wifiConfiguration, originalRequestorUid);
}
@Override
public WifiNetworkAgentSpecifier[] newArray(int size) {
return new WifiNetworkAgentSpecifier[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeParcelable(mWifiConfiguration, flags);
dest.writeInt(mOriginalRequestorUid);
}
@Override
public boolean satisfiedBy(@Nullable NetworkSpecifier other) {
if (this == other) {
return true;
}
// Any generic requests should be satisifed by a specific wifi network.
if (other == null || other instanceof MatchAllNetworkSpecifier) {
return true;
}
if (other instanceof WifiNetworkSpecifier) {
return satisfiesNetworkSpecifier((WifiNetworkSpecifier) other);
}
if (other instanceof WifiNetworkAgentSpecifier) {
throw new IllegalStateException("WifiNetworkAgentSpecifier instances should never be "
+ "compared");
}
return false;
}
/**
* Match {@link WifiNetworkSpecifier} in app's {@link NetworkRequest} with the
* {@link WifiNetworkAgentSpecifier} in wifi platform's {@link NetworkAgent}.
*/
public boolean satisfiesNetworkSpecifier(@NonNull WifiNetworkSpecifier ns) {
// None of these should be null by construction.
// {@link WifiNetworkConfigBuilder} enforces non-null in {@link WifiNetworkSpecifier}.
// {@link WifiNetworkFactory} ensures non-null in {@link WifiNetworkAgentSpecifier}.
checkNotNull(ns);
checkNotNull(ns.ssidPatternMatcher);
checkNotNull(ns.bssidPatternMatcher);
checkNotNull(ns.wifiConfiguration.allowedKeyManagement);
checkNotNull(this.mWifiConfiguration.SSID);
checkNotNull(this.mWifiConfiguration.BSSID);
checkNotNull(this.mWifiConfiguration.allowedKeyManagement);
final String ssidWithQuotes = this.mWifiConfiguration.SSID;
checkState(ssidWithQuotes.startsWith("\"") && ssidWithQuotes.endsWith("\""));
final String ssidWithoutQuotes = ssidWithQuotes.substring(1, ssidWithQuotes.length() - 1);
if (!ns.ssidPatternMatcher.match(ssidWithoutQuotes)) {
return false;
}
final MacAddress bssid = MacAddress.fromString(this.mWifiConfiguration.BSSID);
final MacAddress matchBaseAddress = ns.bssidPatternMatcher.first;
final MacAddress matchMask = ns.bssidPatternMatcher.second;
if (!bssid.matches(matchBaseAddress, matchMask)) {
return false;
}
if (!ns.wifiConfiguration.allowedKeyManagement.equals(
this.mWifiConfiguration.allowedKeyManagement)) {
return false;
}
if (ns.requestorUid != this.mOriginalRequestorUid) {
return false;
}
return true;
}
@Override
public int hashCode() {
return Objects.hash(
mWifiConfiguration.SSID,
mWifiConfiguration.BSSID,
mWifiConfiguration.allowedKeyManagement,
mOriginalRequestorUid);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof WifiNetworkAgentSpecifier)) {
return false;
}
WifiNetworkAgentSpecifier lhs = (WifiNetworkAgentSpecifier) obj;
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)
&& mOriginalRequestorUid == lhs.mOriginalRequestorUid;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("WifiNetworkAgentSpecifier [");
sb.append(", WifiConfiguration=").append(
mWifiConfiguration == null ? null : mWifiConfiguration.configKey())
.append(", mOriginalRequestorUid=").append(mOriginalRequestorUid)
.append("]");
return sb.toString();
}
@Override
public void assertValidFromUid(int requestorUid) {
throw new IllegalStateException("WifiNetworkAgentSpecifier should never be used "
+ "for requests.");
}
}

View File

@@ -0,0 +1,511 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net.wifi;
import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.PendingIntent;
import android.net.MacAddress;
import android.net.NetworkRequest;
import android.net.NetworkSpecifier;
import android.os.PatternMatcher;
import android.os.Process;
import android.text.TextUtils;
import android.util.Pair;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
/**
* WifiNetworkConfigBuilder to use for creating Wi-Fi network configuration.
* <li>See {@link #buildNetworkSpecifier()} for creating a network specifier to use in
* {@link NetworkRequest}.</li>
* <li>See {@link #buildNetworkSuggestion()} for creating a network suggestion to use in
* {@link WifiManager#addNetworkSuggestions(List, PendingIntent)}.</li>
*/
public class WifiNetworkConfigBuilder {
private static final String MATCH_ALL_SSID_PATTERN_PATH = ".*";
private static final String MATCH_EMPTY_SSID_PATTERN_PATH = "";
private static final Pair<MacAddress, MacAddress> MATCH_NO_BSSID_PATTERN =
new Pair(MacAddress.BROADCAST_ADDRESS, MacAddress.BROADCAST_ADDRESS);
private static final Pair<MacAddress, MacAddress> MATCH_ALL_BSSID_PATTERN =
new Pair(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
private static final MacAddress MATCH_EXACT_BSSID_PATTERN_MASK =
MacAddress.BROADCAST_ADDRESS;
private static final int UNASSIGNED_PRIORITY = -1;
/**
* SSID pattern match specified by the app.
*/
private @Nullable PatternMatcher mSsidPatternMatcher;
/**
* BSSID pattern match specified by the app.
* Pair of <BaseAddress, Mask>.
*/
private @Nullable Pair<MacAddress, MacAddress> mBssidPatternMatcher;
/**
* Pre-shared key for use with WPA-PSK networks.
*/
private @Nullable String mPskPassphrase;
/**
* The enterprise configuration details specifying the EAP method,
* certificates and other settings associated with the EAP.
*/
private @Nullable WifiEnterpriseConfig mEnterpriseConfig;
/**
* This is a network that does not broadcast its SSID, so an
* SSID-specific probe request must be used for scans.
*/
private boolean mIsHiddenSSID;
/**
* Whether app needs to log in to captive portal to obtain Internet access.
*/
private boolean mIsAppInteractionRequired;
/**
* Whether user needs to log in to captive portal to obtain Internet access.
*/
private boolean mIsUserInteractionRequired;
/**
* Whether this network is metered or not.
*/
private boolean mIsMetered;
/**
* Priority of this network among other network suggestions provided by the app.
* The lower the number, the higher the priority (i.e value of 0 = highest priority).
*/
private int mPriority;
public WifiNetworkConfigBuilder() {
mSsidPatternMatcher = null;
mBssidPatternMatcher = null;
mPskPassphrase = null;
mEnterpriseConfig = null;
mIsHiddenSSID = false;
mIsAppInteractionRequired = false;
mIsUserInteractionRequired = false;
mIsMetered = false;
mPriority = UNASSIGNED_PRIORITY;
}
/**
* Set the unicode SSID match pattern to use for filtering networks from scan results.
* <p>
* <li>Only allowed for creating network specifier, i.e {@link #buildNetworkSpecifier()}. </li>
* <li>Overrides any previous value set using {@link #setSsid(String)} or
* {@link #setSsidPattern(PatternMatcher)}.</li>
*
* @param ssidPattern Instance of {@link PatternMatcher} containing the UTF-8 encoded
* string pattern to use for matching the network's SSID.
* @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
* method.
*/
public WifiNetworkConfigBuilder setSsidPattern(@NonNull PatternMatcher ssidPattern) {
checkNotNull(ssidPattern);
mSsidPatternMatcher = ssidPattern;
return this;
}
/**
* Set the unicode SSID for the network.
* <p>
* <li>For network requests ({@link NetworkSpecifier}), built using
* {@link #buildNetworkSpecifier}, sets the SSID to use for filtering networks from scan
* results. Will only match networks whose SSID is identical to the UTF-8 encoding of the
* specified value.</li>
* <li>For network suggestions ({@link WifiNetworkSuggestion}), built using
* {@link #buildNetworkSuggestion()}, sets the SSID for the network.</li>
* <li>Overrides any previous value set using {@link #setSsid(String)} or
* {@link #setSsidPattern(PatternMatcher)}.</li>
*
* @param ssid The SSID of the network. It must be valid Unicode.
* @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
* method.
* @throws IllegalArgumentException if the SSID is not valid unicode.
*/
public WifiNetworkConfigBuilder setSsid(@NonNull String ssid) {
checkNotNull(ssid);
final CharsetEncoder unicodeEncoder = StandardCharsets.UTF_8.newEncoder();
if (!unicodeEncoder.canEncode(ssid)) {
throw new IllegalArgumentException("SSID is not a valid unicode string");
}
mSsidPatternMatcher = new PatternMatcher(ssid, PatternMatcher.PATTERN_LITERAL);
return this;
}
/**
* Set the BSSID match pattern to use for filtering networks from scan results.
* Will match all networks with BSSID which satisfies the following:
* {@code BSSID & mask == baseAddress}.
* <p>
* <li>Only allowed for creating network specifier, i.e {@link #buildNetworkSpecifier()}. </li>
* <li>Overrides any previous value set using {@link #setBssid(MacAddress)} or
* {@link #setBssidPattern(MacAddress, MacAddress)}.</li>
*
* @param baseAddress Base address for BSSID pattern.
* @param mask Mask for BSSID pattern.
* @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
* method.
*/
public WifiNetworkConfigBuilder setBssidPattern(
@NonNull MacAddress baseAddress, @NonNull MacAddress mask) {
checkNotNull(baseAddress, mask);
mBssidPatternMatcher = Pair.create(baseAddress, mask);
return this;
}
/**
* Set the BSSID to use for filtering networks from scan results. Will only match network whose
* BSSID is identical to the specified value.
* <p>
* <li>Only allowed for creating network specifier, i.e {@link #buildNetworkSpecifier()}. </li>
* <li>Overrides any previous value set using {@link #setBssid(MacAddress)} or
* {@link #setBssidPattern(MacAddress, MacAddress)}.</li>
*
* @param bssid BSSID of the network.
* @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
* method.
*/
public WifiNetworkConfigBuilder setBssid(@NonNull MacAddress bssid) {
checkNotNull(bssid);
mBssidPatternMatcher = Pair.create(bssid, MATCH_EXACT_BSSID_PATTERN_MASK);
return this;
}
/**
* Set the ASCII PSK passphrase for this network. Needed for authenticating to
* WPA_PSK networks.
*
* @param pskPassphrase PSK passphrase of the network.
* @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
* method.
* @throws IllegalArgumentException if the passphrase is not ASCII encodable.
*/
public WifiNetworkConfigBuilder setPskPassphrase(@NonNull String pskPassphrase) {
checkNotNull(pskPassphrase);
final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
if (!asciiEncoder.canEncode(pskPassphrase)) {
throw new IllegalArgumentException("passphrase not ASCII encodable");
}
mPskPassphrase = pskPassphrase;
return this;
}
/**
* Set the associated enterprise configuration for this network. Needed for authenticating to
* WPA_EAP networks. See {@link WifiEnterpriseConfig} for description.
*
* @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
* @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
* method.
*/
public WifiNetworkConfigBuilder setEnterpriseConfig(
@NonNull WifiEnterpriseConfig enterpriseConfig) {
checkNotNull(enterpriseConfig);
mEnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
return this;
}
/**
* Specifies whether this represents a hidden network.
* <p>
* <li>For network requests (see {@link NetworkSpecifier}), built using
* {@link #buildNetworkSpecifier}, setting this disallows the usage of
* {@link #setSsidPattern(PatternMatcher)} since hidden networks need to be explicitly
* probed for.</li>
* <li>If not set, defaults to false (i.e not a hidden network).</li>
*
* @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
* method.
*/
public WifiNetworkConfigBuilder setIsHiddenSsid() {
mIsHiddenSSID = true;
return this;
}
/**
* Specifies whether the app needs to log in to a captive portal to obtain Internet access.
* <p>
* This will dictate if the 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.
*
* See {@link com.android.server.wifi.WifiConfigManager#setDefaultsInWifiConfiguration(
* WifiConfiguration)}.
*
* @param configuration provided WifiConfiguration object.
*/
private static void setDefaultsInWifiConfiguration(@NonNull WifiConfiguration configuration) {
configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
}
private void setKeyMgmtInWifiConfiguration(@NonNull WifiConfiguration configuration) {
if (!TextUtils.isEmpty(mPskPassphrase)) {
// WPA_PSK network.
configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
} else if (mEnterpriseConfig != null) {
// WPA_EAP network
configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
} else {
// Open network
configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
}
}
/**
* Helper method to build WifiConfiguration object from the builder.
* @return Instance of {@link WifiConfiguration}.
*/
private WifiConfiguration buildWifiConfiguration() {
final WifiConfiguration wifiConfiguration = new WifiConfiguration();
setDefaultsInWifiConfiguration(wifiConfiguration);
// WifiConfiguration.SSID needs quotes around unicode SSID.
if (mSsidPatternMatcher.getType() == PatternMatcher.PATTERN_LITERAL) {
wifiConfiguration.SSID = "\"" + mSsidPatternMatcher.getPath() + "\"";
}
setKeyMgmtInWifiConfiguration(wifiConfiguration);
// WifiConfiguration.preSharedKey needs quotes around ASCII password.
if (mPskPassphrase != null) {
wifiConfiguration.preSharedKey = "\"" + mPskPassphrase + "\"";
}
wifiConfiguration.enterpriseConfig = mEnterpriseConfig;
wifiConfiguration.hiddenSSID = mIsHiddenSSID;
wifiConfiguration.priority = mPriority;
wifiConfiguration.meteredOverride =
mIsMetered ? WifiConfiguration.METERED_OVERRIDE_METERED
: WifiConfiguration.METERED_OVERRIDE_NONE;
return wifiConfiguration;
}
private boolean hasSetAnyPattern() {
return mSsidPatternMatcher != null || mBssidPatternMatcher != null;
}
private void setMatchAnyPatternIfUnset() {
if (mSsidPatternMatcher == null) {
mSsidPatternMatcher = new PatternMatcher(MATCH_ALL_SSID_PATTERN_PATH,
PatternMatcher.PATTERN_SIMPLE_GLOB);
}
if (mBssidPatternMatcher == null) {
mBssidPatternMatcher = MATCH_ALL_BSSID_PATTERN;
}
}
private boolean hasSetMatchNonePattern() {
if (mSsidPatternMatcher.getType() != PatternMatcher.PATTERN_PREFIX
&& mSsidPatternMatcher.getPath().equals(MATCH_EMPTY_SSID_PATTERN_PATH)) {
return true;
}
if (mBssidPatternMatcher.equals(MATCH_NO_BSSID_PATTERN)) {
return true;
}
return false;
}
private boolean hasSetMatchAllPattern() {
if ((mSsidPatternMatcher.match(MATCH_EMPTY_SSID_PATTERN_PATH))
&& mBssidPatternMatcher.equals(MATCH_ALL_BSSID_PATTERN)) {
return true;
}
return false;
}
/**
* Create a specifier object used to request a Wi-Fi network. The generated
* {@link NetworkSpecifier} should be used in
* {@link NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} when building
* the {@link NetworkRequest}.
*<p>
* Note: Apps can set a combination of network match params:
* <li> SSID Pattern using {@link #setSsidPattern(PatternMatcher)} OR Specific SSID using
* {@link #setSsid(String)}. </li>
* AND/OR
* <li> BSSID Pattern using {@link #setBssidPattern(MacAddress, MacAddress)} OR Specific BSSID
* using {@link #setBssid(MacAddress)} </li>
* to trigger connection to a network that matches the set params.
* The system will find the set of networks matching the request and present the user
* with a system dialog which will allow the user to select a specific Wi-Fi network to connect
* to or to deny the request.
*</p>
*
* For example:
* To connect to an open network with a SSID prefix of "test" and a BSSID OUI of "10:03:23":
* {@code
* final NetworkSpecifier specifier =
* new WifiNetworkConfigBuilder()
* .setSsidPattern(new PatternMatcher("test", PatterMatcher.PATTERN_PREFIX))
* .setBssidPattern(MacAddress.fromString("10:03:23:00:00:00"),
* MacAddress.fromString("ff:ff:ff:00:00:00"))
* .buildNetworkSpecifier()
* final NetworkRequest request =
* new NetworkRequest.Builder()
* .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
* .setNetworkSpecifier(specifier)
* .build();
* final ConnectivityManager connectivityManager =
* context.getSystemService(Context.CONNECTIVITY_SERVICE);
* final NetworkCallback networkCallback = new NetworkCallback() {
* ...
* @Override
* void onAvailable(...) {}
* // etc.
* };
* connectivityManager.requestNetwork(request, networkCallback);
* }
*
* @return Instance of {@link NetworkSpecifier}.
* @throws IllegalStateException on invalid params set.
*/
public NetworkSpecifier buildNetworkSpecifier() {
if (!hasSetAnyPattern()) {
throw new IllegalStateException("one of setSsidPattern/setSsid/setBssidPattern/setBssid"
+ " should be invoked for specifier");
}
setMatchAnyPatternIfUnset();
if (hasSetMatchNonePattern()) {
throw new IllegalStateException("cannot set match-none pattern for specifier");
}
if (hasSetMatchAllPattern()) {
throw new IllegalStateException("cannot set match-all pattern for specifier");
}
if (mIsHiddenSSID && mSsidPatternMatcher.getType() != PatternMatcher.PATTERN_LITERAL) {
throw new IllegalStateException("setSsid should also be invoked when "
+ "setIsHiddenSsid is invoked for network specifier");
}
if (mIsAppInteractionRequired || mIsUserInteractionRequired
|| mPriority != -1 || mIsMetered) {
throw new IllegalStateException("none of setIsAppInteractionRequired/"
+ "setIsUserInteractionRequired/setPriority/setIsMetered are allowed for "
+ "specifier");
}
if (!TextUtils.isEmpty(mPskPassphrase) && mEnterpriseConfig != null) {
throw new IllegalStateException("only one of setPreSharedKey or setEnterpriseConfig can"
+ " be invoked for network specifier");
}
return new WifiNetworkSpecifier(
mSsidPatternMatcher,
mBssidPatternMatcher,
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());
}
}

View File

@@ -0,0 +1,181 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net.wifi;
import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.NonNull;
import android.net.MacAddress;
import android.net.MatchAllNetworkSpecifier;
import android.net.NetworkSpecifier;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.PatternMatcher;
import android.util.Pair;
import java.util.Objects;
/**
* Network specifier object used to request a Wi-Fi network. Apps should use the
* {@link WifiNetworkConfigBuilder} class to create an instance.
* @hide
*/
public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parcelable {
/**
* SSID pattern match specified by the app.
*/
public final PatternMatcher ssidPatternMatcher;
/**
* BSSID pattern match specified by the app.
* Pair of <BaseAddress, Mask>.
*/
public final Pair<MacAddress, MacAddress> bssidPatternMatcher;
/**
* Security credentials for the network.
* <p>
* Note: {@link WifiConfiguration#SSID} & {@link WifiConfiguration#BSSID} fields from
* WifiConfiguration are not used. Instead we use the {@link #ssidPatternMatcher} &
* {@link #bssidPatternMatcher} fields embedded directly
* within {@link WifiNetworkSpecifier}.
*/
public final WifiConfiguration wifiConfiguration;
/**
* The UID of the process initializing this network specifier. Validated by receiver using
* checkUidIfNecessary() and is used by satisfiedBy() to determine whether the specifier
* matches the offered network.
*/
public final int requestorUid;
public WifiNetworkSpecifier(@NonNull PatternMatcher ssidPatternMatcher,
@NonNull Pair<MacAddress, MacAddress> bssidPatternMatcher,
@NonNull WifiConfiguration wifiConfiguration,
int requestorUid) {
checkNotNull(ssidPatternMatcher);
checkNotNull(bssidPatternMatcher);
checkNotNull(wifiConfiguration);
this.ssidPatternMatcher = ssidPatternMatcher;
this.bssidPatternMatcher = bssidPatternMatcher;
this.wifiConfiguration = wifiConfiguration;
this.requestorUid = requestorUid;
}
public static final Creator<WifiNetworkSpecifier> CREATOR =
new Creator<WifiNetworkSpecifier>() {
@Override
public WifiNetworkSpecifier createFromParcel(Parcel in) {
PatternMatcher ssidPatternMatcher = in.readParcelable(/* classLoader */null);
MacAddress baseAddress = in.readParcelable(null);
MacAddress mask = in.readParcelable(null);
Pair<MacAddress, MacAddress> bssidPatternMatcher =
Pair.create(baseAddress, mask);
WifiConfiguration wifiConfiguration = in.readParcelable(null);
int requestorUid = in.readInt();
return new WifiNetworkSpecifier(ssidPatternMatcher, bssidPatternMatcher,
wifiConfiguration, requestorUid);
}
@Override
public WifiNetworkSpecifier[] newArray(int size) {
return new WifiNetworkSpecifier[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(ssidPatternMatcher, flags);
dest.writeParcelable(bssidPatternMatcher.first, flags);
dest.writeParcelable(bssidPatternMatcher.second, flags);
dest.writeParcelable(wifiConfiguration, flags);
dest.writeInt(requestorUid);
}
@Override
public boolean satisfiedBy(NetworkSpecifier other) {
if (this == other) {
return true;
}
// Any generic requests should be satisifed by a specific wifi network.
if (other == null || other instanceof MatchAllNetworkSpecifier) {
return true;
}
if (other instanceof WifiNetworkAgentSpecifier) {
return ((WifiNetworkAgentSpecifier) other).satisfiesNetworkSpecifier(this);
}
// Specific requests are checked for equality although testing for equality of 2 patterns do
// not make much sense!
return equals(other);
}
@Override
public int hashCode() {
return Objects.hash(
ssidPatternMatcher.getPath(),
ssidPatternMatcher.getType(),
bssidPatternMatcher,
wifiConfiguration.allowedKeyManagement,
requestorUid);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof WifiNetworkSpecifier)) {
return false;
}
WifiNetworkSpecifier lhs = (WifiNetworkSpecifier) obj;
return Objects.equals(this.ssidPatternMatcher.getPath(),
lhs.ssidPatternMatcher.getPath())
&& Objects.equals(this.ssidPatternMatcher.getType(),
lhs.ssidPatternMatcher.getType())
&& Objects.equals(this.bssidPatternMatcher,
lhs.bssidPatternMatcher)
&& Objects.equals(this.wifiConfiguration.allowedKeyManagement,
lhs.wifiConfiguration.allowedKeyManagement)
&& requestorUid == lhs.requestorUid;
}
@Override
public String toString() {
return new StringBuilder()
.append("WifiNetworkSpecifierWifiNetworkSpecifier [")
.append(", SSID Match pattern=").append(ssidPatternMatcher)
.append(", BSSID Match pattern=").append(bssidPatternMatcher)
.append(", WifiConfiguration=").append(
wifiConfiguration == null ? null : wifiConfiguration.configKey())
.append(", requestorUid=").append(requestorUid)
.append("]")
.toString();
}
@Override
public void assertValidFromUid(int requestorUid) {
if (this.requestorUid != requestorUid) {
throw new SecurityException("mismatched UIDs");
}
}
}

View File

@@ -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();
}
}

View File

@@ -43,6 +43,8 @@ import android.net.wifi.WifiManager.LocalOnlyHotspotCallback;
import android.net.wifi.WifiManager.LocalOnlyHotspotObserver;
import android.net.wifi.WifiManager.LocalOnlyHotspotReservation;
import android.net.wifi.WifiManager.LocalOnlyHotspotSubscription;
import android.net.wifi.WifiManager.NetworkRequestMatchCallback;
import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback;
import android.net.wifi.WifiManager.SoftApCallback;
import android.net.wifi.WifiManager.TrafficStateCallback;
import android.os.Handler;
@@ -59,6 +61,8 @@ import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
/**
* Unit tests for {@link android.net.wifi.WifiManager}.
*/
@@ -67,16 +71,19 @@ public class WifiManagerTest {
private static final int ERROR_NOT_SET = -1;
private static final int ERROR_TEST_REASON = 5;
private static final int TEST_UID = 14553;
private static final String TEST_PACKAGE_NAME = "TestPackage";
private static final String TEST_COUNTRY_CODE = "US";
@Mock Context mContext;
@Mock IWifiManager mWifiService;
@Mock
android.net.wifi.IWifiManager mWifiService;
@Mock ApplicationInfo mApplicationInfo;
@Mock WifiConfiguration mApConfig;
@Mock IBinder mAppBinder;
@Mock SoftApCallback mSoftApCallback;
@Mock TrafficStateCallback mTrafficStateCallback;
@Mock NetworkRequestMatchCallback mNetworkRequestMatchCallback;
private Handler mHandler;
private TestLooper mLooper;
@@ -1163,4 +1170,84 @@ i * Verify that a call to cancel WPS immediately returns a failure.
assertEquals(1, altLooper.dispatchAll());
verify(mTrafficStateCallback).onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT);
}
/**
* Verify the call to registerNetworkRequestMatchCallback goes to WifiServiceImpl.
*/
@Test
public void registerNetworkRequestMatchCallbackCallGoesToWifiServiceImpl()
throws Exception {
when(mContext.getMainLooper()).thenReturn(mLooper.getLooper());
ArgumentCaptor<INetworkRequestMatchCallback.Stub> callbackCaptor =
ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class);
mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback, null);
verify(mWifiService).registerNetworkRequestMatchCallback(
any(IBinder.class), callbackCaptor.capture(), anyInt());
INetworkRequestUserSelectionCallback iUserSelectionCallback =
mock(INetworkRequestUserSelectionCallback.class);
assertEquals(0, mLooper.dispatchAll());
callbackCaptor.getValue().onMatch(new ArrayList<WifiConfiguration>());
assertEquals(1, mLooper.dispatchAll());
verify(mNetworkRequestMatchCallback).onMatch(anyList());
callbackCaptor.getValue().onUserSelectionConnectSuccess(new WifiConfiguration());
assertEquals(1, mLooper.dispatchAll());
verify(mNetworkRequestMatchCallback).onUserSelectionConnectSuccess(
any(WifiConfiguration.class));
callbackCaptor.getValue().onUserSelectionConnectFailure(new WifiConfiguration());
assertEquals(1, mLooper.dispatchAll());
verify(mNetworkRequestMatchCallback).onUserSelectionConnectFailure(
any(WifiConfiguration.class));
}
/**
* Verify the call to unregisterNetworkRequestMatchCallback goes to WifiServiceImpl.
*/
@Test
public void unregisterNetworkRequestMatchCallbackCallGoesToWifiServiceImpl() throws Exception {
ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class);
mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback, mHandler);
verify(mWifiService).registerNetworkRequestMatchCallback(
any(IBinder.class), any(INetworkRequestMatchCallback.class),
callbackIdentifier.capture());
mWifiManager.unregisterNetworkRequestMatchCallback(mNetworkRequestMatchCallback);
verify(mWifiService).unregisterNetworkRequestMatchCallback(
eq((int) callbackIdentifier.getValue()));
}
/**
* Verify the call to NetworkRequestUserSelectionCallback goes to
* WifiServiceImpl.
*/
@Test
public void networkRequestUserSelectionCallbackCallGoesToWifiServiceImpl()
throws Exception {
when(mContext.getMainLooper()).thenReturn(mLooper.getLooper());
ArgumentCaptor<INetworkRequestMatchCallback.Stub> callbackCaptor =
ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class);
mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback, null);
verify(mWifiService).registerNetworkRequestMatchCallback(
any(IBinder.class), callbackCaptor.capture(), anyInt());
INetworkRequestUserSelectionCallback iUserSelectionCallback =
mock(INetworkRequestUserSelectionCallback.class);
ArgumentCaptor<NetworkRequestUserSelectionCallback> userSelectionCallbackCaptor =
ArgumentCaptor.forClass(NetworkRequestUserSelectionCallback.class);
callbackCaptor.getValue().onUserSelectionCallbackRegistration(
iUserSelectionCallback);
assertEquals(1, mLooper.dispatchAll());
verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
userSelectionCallbackCaptor.capture());
WifiConfiguration selected = new WifiConfiguration();
userSelectionCallbackCaptor.getValue().select(selected);
verify(iUserSelectionCallback).select(selected);
userSelectionCallbackCaptor.getValue().reject();
verify(iUserSelectionCallback).reject();
}
}

View File

@@ -0,0 +1,453 @@
/*
* 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.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import android.net.MacAddress;
import android.net.MatchAllNetworkSpecifier;
import android.net.NetworkRequest;
import android.net.NetworkSpecifier;
import android.os.Parcel;
import android.os.PatternMatcher;
import android.support.test.filters.SmallTest;
import android.util.Pair;
import org.junit.Test;
/**
* Unit tests for {@link android.net.wifi.WifiNetworkAgentSpecifier}.
*/
@SmallTest
public class WifiNetworkAgentSpecifierTest {
private static final int TEST_UID = 5;
private static final int TEST_UID_1 = 8;
private static final String TEST_SSID = "Test123";
private static final String TEST_SSID_PATTERN = "Test";
private static final String TEST_SSID_1 = "456test";
private static final String TEST_BSSID = "12:12:12:aa:0b:c0";
private static final String TEST_BSSID_OUI_BASE_ADDRESS = "12:12:12:00:00:00";
private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00";
private static final String TEST_BSSID_1 = "aa:cc:12:aa:0b:c0";
private static final String TEST_PRESHARED_KEY = "\"Test123\"";
/**
* Validate that parcel marshalling/unmarshalling works
*/
@Test
public void testWifiNetworkAgentSpecifierParcel() {
WifiNetworkAgentSpecifier specifier = createDefaultNetworkAgentSpecifier();
Parcel parcelW = Parcel.obtain();
specifier.writeToParcel(parcelW, 0);
byte[] bytes = parcelW.marshall();
parcelW.recycle();
Parcel parcelR = Parcel.obtain();
parcelR.unmarshall(bytes, 0, bytes.length);
parcelR.setDataPosition(0);
WifiNetworkAgentSpecifier parcelSpecifier =
WifiNetworkAgentSpecifier.CREATOR.createFromParcel(parcelR);
assertEquals(specifier, parcelSpecifier);
}
/**
* Validate that the NetworkAgentSpecifier cannot be used in a {@link NetworkRequest} by apps.
*/
@Test(expected = IllegalStateException.class)
public void testWifiNetworkAgentSpecifierNotUsedInNetworkRequest() {
WifiNetworkAgentSpecifier specifier = createDefaultNetworkAgentSpecifier();
specifier.assertValidFromUid(TEST_UID);
}
/**
* Validate NetworkAgentSpecifier equals with itself.
* a) Create network agent specifier 1 for WPA_PSK network
* b) Create network agent specifier 2 with the same params as specifier 1.
* c) Ensure that the specifier 2 equals specifier 1.
*/
@Test
public void testWifiNetworkAgentSpecifierEqualsSame() {
WifiNetworkAgentSpecifier specifier1 = createDefaultNetworkAgentSpecifier();
WifiNetworkAgentSpecifier specifier2 = createDefaultNetworkAgentSpecifier();
assertTrue(specifier2.equals(specifier1));
}
/**
* Validate NetworkAgentSpecifier equals between instances of {@link WifiNetworkAgentSpecifier}.
* a) Create network agent specifier 1 for WPA_PSK network
* b) Create network agent specifier 2 with different key mgmt params.
* c) Ensure that the specifier 2 does not equal specifier 1.
*/
@Test
public void testWifiNetworkAgentSpecifierDoesNotEqualsWhenKeyMgmtDifferent() {
WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration();
WifiNetworkAgentSpecifier specifier1 =
new WifiNetworkAgentSpecifier(
wifiConfiguration1,
TEST_UID);
WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1);
wifiConfiguration2.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
WifiNetworkAgentSpecifier specifier2 =
new WifiNetworkAgentSpecifier(
wifiConfiguration2,
TEST_UID);
assertFalse(specifier2.equals(specifier1));
}
/**
* Validate NetworkAgentSpecifier equals between instances of {@link WifiNetworkAgentSpecifier}.
* a) Create network agent specifier 1 for WPA_PSK network
* b) Create network agent specifier 2 with different SSID.
* c) Ensure that the specifier 2 does not equal specifier 1.
*/
@Test
public void testWifiNetworkAgentSpecifierDoesNotSatisifyWhenSsidDifferent() {
WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration();
WifiNetworkAgentSpecifier specifier1 =
new WifiNetworkAgentSpecifier(
wifiConfiguration1,
TEST_UID);
WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1);
wifiConfiguration2.SSID = TEST_SSID_1;
WifiNetworkAgentSpecifier specifier2 =
new WifiNetworkAgentSpecifier(
wifiConfiguration2,
TEST_UID);
assertFalse(specifier2.equals(specifier1));
}
/**
* Validate NetworkAgentSpecifier equals between instances of {@link WifiNetworkAgentSpecifier}.
* a) Create network agent specifier 1 for WPA_PSK network
* b) Create network agent specifier 2 with different BSSID.
* c) Ensure that the specifier 2 does not equal specifier 1.
*/
@Test
public void testWifiNetworkAgentSpecifierDoesNotSatisifyWhenBssidDifferent() {
WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration();
WifiNetworkAgentSpecifier specifier1 =
new WifiNetworkAgentSpecifier(
wifiConfiguration1,
TEST_UID);
WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1);
wifiConfiguration2.BSSID = TEST_BSSID_1;
WifiNetworkAgentSpecifier specifier2 =
new WifiNetworkAgentSpecifier(
wifiConfiguration2,
TEST_UID);
assertFalse(specifier2.equals(specifier1));
}
/**
* Validate NetworkAgentSpecifier matching.
* a) Create a network agent specifier for WPA_PSK network
* b) Ensure that the specifier matches {@code null} and {@link MatchAllNetworkSpecifier}
* specifiers.
*/
@Test
public void testWifiNetworkAgentSpecifierSatisifiesNullAndAllMatch() {
WifiNetworkAgentSpecifier specifier = createDefaultNetworkAgentSpecifier();
assertTrue(specifier.satisfiedBy(null));
assertTrue(specifier.satisfiedBy(new MatchAllNetworkSpecifier()));
}
/**
* Validate NetworkAgentSpecifier matching with itself.
* a) Create network agent specifier 1 for WPA_PSK network
* b) Create network agent specifier 2 with the same params as specifier 1.
* c) Ensure that invoking {@link NetworkSpecifier#satisfiedBy(NetworkSpecifier)} on 2
* {@link WifiNetworkAgentSpecifier} throws an exception.
*/
@Test(expected = IllegalStateException.class)
public void testWifiNetworkAgentSpecifierDoesNotSatisifySame() {
WifiNetworkAgentSpecifier specifier1 = createDefaultNetworkAgentSpecifier();
WifiNetworkAgentSpecifier specifier2 = createDefaultNetworkAgentSpecifier();
assertTrue(specifier2.satisfiedBy(specifier1));
}
/**
* Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
* a) Create network agent specifier for WPA_PSK network
* b) Create network specifier with matching SSID pattern.
* c) Ensure that the agent specifier is satisfied by specifier.
*/
@Test
public void
testWifiNetworkAgentSpecifierSatisfiesNetworkSpecifierWithSsidPattern() {
WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
PatternMatcher ssidPattern =
new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
Pair<MacAddress, MacAddress> bssidPattern =
Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
wificonfigurationNetworkSpecifier.allowedKeyManagement
.set(WifiConfiguration.KeyMgmt.WPA_PSK);
WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
ssidPattern,
bssidPattern,
wificonfigurationNetworkSpecifier,
TEST_UID);
assertTrue(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
assertTrue(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
}
/**
* Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
* a) Create network agent specifier for WPA_PSK network
* b) Create network specifier with matching BSSID pattern.
* c) Ensure that the agent specifier is satisfied by specifier.
*/
@Test
public void
testWifiNetworkAgentSpecifierSatisfiesNetworkSpecifierWithBssidPattern() {
WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
PatternMatcher ssidPattern =
new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB);
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);
WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
ssidPattern,
bssidPattern,
wificonfigurationNetworkSpecifier,
TEST_UID);
assertTrue(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
assertTrue(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
}
/**
* Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
* a) Create network agent specifier for WPA_PSK network
* b) Create network specifier with matching SSID & BSSID pattern.
* c) Ensure that the agent specifier is satisfied by specifier.
*/
@Test
public void
testWifiNetworkAgentSpecifierSatisfiesNetworkSpecifierWithSsidAndBssidPattern() {
WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
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);
WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
ssidPattern,
bssidPattern,
wificonfigurationNetworkSpecifier,
TEST_UID);
assertTrue(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
assertTrue(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
}
/**
* Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
* a) Create network agent specifier for WPA_PSK network
* b) Create network specifier with non-matching SSID pattern.
* c) Ensure that the agent specifier is not satisfied by specifier.
*/
@Test
public void
testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithSsidPattern() {
WifiConfiguration wifiConfigurationNetworkAgent = createDefaultWifiConfiguration();
wifiConfigurationNetworkAgent.SSID = "\"" + TEST_SSID_1 + "\"";
WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
new WifiNetworkAgentSpecifier(
wifiConfigurationNetworkAgent,
TEST_UID);
PatternMatcher ssidPattern =
new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
Pair<MacAddress, MacAddress> bssidPattern =
Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
wificonfigurationNetworkSpecifier.allowedKeyManagement
.set(WifiConfiguration.KeyMgmt.WPA_PSK);
WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
ssidPattern,
bssidPattern,
wificonfigurationNetworkSpecifier,
TEST_UID);
assertFalse(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
assertFalse(wifiNetworkAgentSpecifier.satisfiedBy(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.
* c) Ensure that the agent specifier is not satisfied by specifier.
*/
@Test
public void
testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithBssidPattern() {
WifiConfiguration wifiConfigurationNetworkAgent = createDefaultWifiConfiguration();
wifiConfigurationNetworkAgent.BSSID = TEST_BSSID_1;
WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
new WifiNetworkAgentSpecifier(
wifiConfigurationNetworkAgent,
TEST_UID);
PatternMatcher ssidPattern =
new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB);
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);
WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
ssidPattern,
bssidPattern,
wificonfigurationNetworkSpecifier,
TEST_UID);
assertFalse(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
assertFalse(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
}
/**
* Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
* a) Create network agent specifier for WPA_PSK network
* b) Create network specifier with non-matching SSID and BSSID pattern.
* c) Ensure that the agent specifier is not satisfied by specifier.
*/
@Test
public void
testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithSsidAndBssidPattern() {
WifiConfiguration wifiConfigurationNetworkAgent = createDefaultWifiConfiguration();
wifiConfigurationNetworkAgent.BSSID = TEST_BSSID_1;
WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
new WifiNetworkAgentSpecifier(
wifiConfigurationNetworkAgent,
TEST_UID);
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);
WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
ssidPattern,
bssidPattern,
wificonfigurationNetworkSpecifier,
TEST_UID);
assertFalse(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
assertFalse(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
}
/**
* Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
* a) Create network agent specifier for WPA_PSK network
* b) Create network specifier with matching SSID and BSSID pattern, but different key mgmt.
* c) Ensure that the agent specifier is not satisfied by specifier.
*/
@Test
public void
testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithDifferentKeyMgmt() {
WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
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.NONE);
WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
ssidPattern,
bssidPattern,
wificonfigurationNetworkSpecifier,
TEST_UID);
assertFalse(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
assertFalse(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
}
/**
* Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
* a) Create network agent specifier for WPA_PSK network
* b) Create network specifier with matching SSID and BSSID pattern, but different UID.
* c) Ensure that the agent specifier is not satisfied by specifier.
*/
@Test
public void
testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithDifferentUid() {
WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
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);
WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
ssidPattern,
bssidPattern,
wificonfigurationNetworkSpecifier,
TEST_UID_1);
assertFalse(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
assertFalse(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
}
private WifiConfiguration createDefaultWifiConfiguration() {
WifiConfiguration wifiConfiguration = new WifiConfiguration();
wifiConfiguration.SSID = "\"" + TEST_SSID + "\"";
wifiConfiguration.BSSID = TEST_BSSID;
wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
return wifiConfiguration;
}
private WifiNetworkAgentSpecifier createDefaultNetworkAgentSpecifier() {
return new WifiNetworkAgentSpecifier(createDefaultWifiConfiguration(), TEST_UID);
}
}

View File

@@ -0,0 +1,481 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net.wifi;
import static android.os.PatternMatcher.PATTERN_LITERAL;
import static android.os.PatternMatcher.PATTERN_PREFIX;
import static android.os.PatternMatcher.PATTERN_SIMPLE_GLOB;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import android.net.MacAddress;
import android.net.NetworkSpecifier;
import android.os.PatternMatcher;
import android.os.Process;
import android.support.test.filters.SmallTest;
import org.junit.Test;
/**
* Unit tests for {@link android.net.wifi.WifiNetworkConfigBuilder}.
*/
@SmallTest
public class WifiNetworkConfigBuilderTest {
private static final String TEST_SSID = "Test123";
private static final String TEST_BSSID_OUI_BASE_ADDRESS = "12:12:12:00:00:00";
private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00";
private static final String TEST_BSSID = "12:12:12:12:12:12";
private static final String TEST_PRESHARED_KEY = "Test123";
/**
* Validate correctness of WifiNetworkSpecifier object created by
* {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for open network with SSID pattern.
*/
@Test
public void testWifiNetworkSpecifierBuilderForOpenNetworkWithSsidPattern() {
NetworkSpecifier specifier = new WifiNetworkConfigBuilder()
.setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_PREFIX))
.buildNetworkSpecifier();
assertTrue(specifier instanceof WifiNetworkSpecifier);
WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
assertEquals(Process.myUid(), wifiNetworkSpecifier.requestorUid);
assertEquals(TEST_SSID, wifiNetworkSpecifier.ssidPatternMatcher.getPath());
assertEquals(PATTERN_PREFIX, wifiNetworkSpecifier.ssidPatternMatcher.getType());
assertEquals(MacAddress.ALL_ZEROS_ADDRESS, wifiNetworkSpecifier.bssidPatternMatcher.first);
assertEquals(MacAddress.ALL_ZEROS_ADDRESS, wifiNetworkSpecifier.bssidPatternMatcher.second);
assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
.get(WifiConfiguration.KeyMgmt.NONE));
assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedProtocols
.get(WifiConfiguration.Protocol.RSN));
assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedAuthAlgorithms
.get(WifiConfiguration.AuthAlgorithm.OPEN));
assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedPairwiseCiphers
.get(WifiConfiguration.PairwiseCipher.CCMP));
assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
.get(WifiConfiguration.GroupCipher.CCMP));
assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
.get(WifiConfiguration.GroupCipher.TKIP));
}
/**
* Validate correctness of WifiNetworkSpecifier object created by
* {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for WPA_PSK network with BSSID
* pattern.
*/
@Test
public void testWifiNetworkSpecifierBuilderForWpaPskNetworkWithBssidPattern() {
NetworkSpecifier specifier = new WifiNetworkConfigBuilder()
.setBssidPattern(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK))
.setPskPassphrase(TEST_PRESHARED_KEY)
.buildNetworkSpecifier();
assertTrue(specifier instanceof WifiNetworkSpecifier);
WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
assertEquals(".*", wifiNetworkSpecifier.ssidPatternMatcher.getPath());
assertEquals(PATTERN_SIMPLE_GLOB, wifiNetworkSpecifier.ssidPatternMatcher.getType());
assertEquals(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
wifiNetworkSpecifier.bssidPatternMatcher.first);
assertEquals(MacAddress.fromString(TEST_BSSID_OUI_MASK),
wifiNetworkSpecifier.bssidPatternMatcher.second);
assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
.get(WifiConfiguration.KeyMgmt.WPA_PSK));
assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedProtocols
.get(WifiConfiguration.Protocol.RSN));
assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedAuthAlgorithms
.get(WifiConfiguration.AuthAlgorithm.OPEN));
assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedPairwiseCiphers
.get(WifiConfiguration.PairwiseCipher.CCMP));
assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
.get(WifiConfiguration.GroupCipher.CCMP));
assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
.get(WifiConfiguration.GroupCipher.TKIP));
assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
wifiNetworkSpecifier.wifiConfiguration.preSharedKey);
}
/**
* Validate correctness of WifiNetworkSpecifier object created by
* {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for WPA_EAP network with
* SSID and BSSID pattern.
*/
@Test
public void testWifiNetworkSpecifierBuilderForEnterpriseHiddenNetworkWithSsidAndBssid() {
WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
NetworkSpecifier specifier = new WifiNetworkConfigBuilder()
.setSsid(TEST_SSID)
.setBssid(MacAddress.fromString(TEST_BSSID))
.setEnterpriseConfig(enterpriseConfig)
.setIsHiddenSsid()
.buildNetworkSpecifier();
assertTrue(specifier instanceof WifiNetworkSpecifier);
WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
assertEquals(TEST_SSID, wifiNetworkSpecifier.ssidPatternMatcher.getPath());
assertEquals(PATTERN_LITERAL, wifiNetworkSpecifier.ssidPatternMatcher.getType());
assertEquals(MacAddress.fromString(TEST_BSSID),
wifiNetworkSpecifier.bssidPatternMatcher.first);
assertEquals(MacAddress.BROADCAST_ADDRESS,
wifiNetworkSpecifier.bssidPatternMatcher.second);
assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
.get(WifiConfiguration.KeyMgmt.WPA_EAP));
assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
.get(WifiConfiguration.KeyMgmt.IEEE8021X));
assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedProtocols
.get(WifiConfiguration.Protocol.RSN));
assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedAuthAlgorithms
.get(WifiConfiguration.AuthAlgorithm.OPEN));
assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedPairwiseCiphers
.get(WifiConfiguration.PairwiseCipher.CCMP));
assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
.get(WifiConfiguration.GroupCipher.CCMP));
assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
.get(WifiConfiguration.GroupCipher.TKIP));
assertTrue(wifiNetworkSpecifier.wifiConfiguration.hiddenSSID);
assertEquals(enterpriseConfig.getEapMethod(),
wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig.getEapMethod());
assertEquals(enterpriseConfig.getPhase2Method(),
wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig.getPhase2Method());
}
/**
* Ensure {@link WifiNetworkConfigBuilder#setSsid(String)} throws an exception
* when the string is not Unicode.
*/
@Test(expected = IllegalArgumentException.class)
public void testSetSsidWithNonUnicodeString() {
new WifiNetworkConfigBuilder()
.setSsid("\ud800")
.buildNetworkSpecifier();
}
/**
* Ensure {@link WifiNetworkConfigBuilder#setPskPassphrase(String)} throws an exception
* when the string is not ASCII encodable.
*/
@Test(expected = IllegalArgumentException.class)
public void testSetPskPassphraseWithNonAsciiString() {
new WifiNetworkConfigBuilder()
.setSsid(TEST_SSID)
.setPskPassphrase("salvē")
.buildNetworkSpecifier();
}
/**
* Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
* when neither SSID nor BSSID patterns were set.
*/
@Test(expected = IllegalStateException.class)
public void testWifiNetworkSpecifierBuilderWithNoSsidAndBssidPattern() {
new WifiNetworkConfigBuilder().buildNetworkSpecifier();
}
/**
* Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
* when match-all SSID pattern is set.
*/
@Test(expected = IllegalStateException.class)
public void testWifiNetworkSpecifierBuilderWithMatchAllSsidPattern1() {
new WifiNetworkConfigBuilder()
.setSsidPattern(new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB))
.buildNetworkSpecifier();
}
/**
* Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
* when match-all SSID pattern is set.
*/
@Test(expected = IllegalStateException.class)
public void testWifiNetworkSpecifierBuilderWithMatchAllSsidPattern2() {
new WifiNetworkConfigBuilder()
.setSsidPattern(new PatternMatcher(".*", PatternMatcher.PATTERN_ADVANCED_GLOB))
.buildNetworkSpecifier();
}
/**
* Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
* when match-all SSID pattern is set.
*/
@Test(expected = IllegalStateException.class)
public void testWifiNetworkSpecifierBuilderWithMatchAllSsidPattern3() {
new WifiNetworkConfigBuilder()
.setSsidPattern(new PatternMatcher("", PatternMatcher.PATTERN_PREFIX))
.buildNetworkSpecifier();
}
/**
* Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
* when match-all BSSID pattern is set.
*/
@Test(expected = IllegalStateException.class)
public void testWifiNetworkSpecifierBuilderWithMatchAllBssidPattern() {
new WifiNetworkConfigBuilder()
.setBssidPattern(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS)
.buildNetworkSpecifier();
}
/**
* Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
* when match-none SSID pattern is set.
*/
@Test(expected = IllegalStateException.class)
public void testWifiNetworkSpecifierBuilderWithMatchNoneSsidPattern() {
new WifiNetworkConfigBuilder()
.setSsidPattern(new PatternMatcher("", PatternMatcher.PATTERN_LITERAL))
.buildNetworkSpecifier();
}
/**
* Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
* when match-none BSSID pattern is set.
*/
@Test(expected = IllegalStateException.class)
public void testWifiNetworkSpecifierBuilderWithMatchNoneBssidPattern() {
new WifiNetworkConfigBuilder()
.setBssidPattern(MacAddress.BROADCAST_ADDRESS, MacAddress.BROADCAST_ADDRESS)
.buildNetworkSpecifier();
}
/**
* Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
* when SSID pattern is set for hidden network.
*/
@Test(expected = IllegalStateException.class)
public void testWifiNetworkSpecifierBuilderWithBssidMatchPatternForHiddenNetwork() {
new WifiNetworkConfigBuilder()
.setBssidPattern(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK))
.setIsHiddenSsid()
.buildNetworkSpecifier();
}
/**
* Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
* when both {@link WifiNetworkConfigBuilder#setPskPassphrase(String)} and
* {@link WifiNetworkConfigBuilder#setEnterpriseConfig(WifiEnterpriseConfig)} are invoked.
*/
@Test(expected = IllegalStateException.class)
public void testWifiNetworkSpecifierBuilderWithBothPskPassphraseAndEnterpriseConfig() {
new WifiNetworkConfigBuilder()
.setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
.setPskPassphrase(TEST_PRESHARED_KEY)
.setEnterpriseConfig(new WifiEnterpriseConfig())
.buildNetworkSpecifier();
}
/**
* Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
* when SSID pattern is set for hidden network.
*/
@Test(expected = IllegalStateException.class)
public void testWifiNetworkSpecifierBuilderWithSsidMatchPatternForHiddenNetwork() {
new WifiNetworkConfigBuilder()
.setSsidPattern(new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_PREFIX))
.setIsHiddenSsid()
.buildNetworkSpecifier();
}
/**
* Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
* when {@link WifiNetworkConfigBuilder#setIsAppInteractionRequired()} is set.
*/
@Test(expected = IllegalStateException.class)
public void testWifiNetworkSpecifierBuilderWithRequiredAppInteraction() {
new WifiNetworkConfigBuilder()
.setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
.setIsAppInteractionRequired()
.buildNetworkSpecifier();
}
/**
* Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
* when {@link WifiNetworkConfigBuilder#setIsUserInteractionRequired()} is set.
*/
@Test(expected = IllegalStateException.class)
public void testWifiNetworkSpecifierBuilderWithRequiredUserInteraction() {
new WifiNetworkConfigBuilder()
.setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
.setIsUserInteractionRequired()
.buildNetworkSpecifier();
}
/**
* Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
* when {@link WifiNetworkConfigBuilder#setPriority(int)} is set.
*/
@Test(expected = IllegalStateException.class)
public void testWifiNetworkSpecifierBuilderWithSetPriority() {
new WifiNetworkConfigBuilder()
.setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
.setPriority(4)
.buildNetworkSpecifier();
}
/**
* Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
* when {@link WifiNetworkConfigBuilder#setIsMetered()} is set.
*/
@Test(expected = IllegalStateException.class)
public void testWifiNetworkSpecifierBuilderWithMetered() {
new WifiNetworkConfigBuilder()
.setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
.setIsMetered()
.buildNetworkSpecifier();
}
/**
* Validate correctness of WifiNetworkSuggestion object created by
* {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} for Open network which requires
* app interaction.
*/
@Test
public void testWifiNetworkSuggestionBuilderForOpenNetworkWithReqAppInteraction() {
WifiNetworkSuggestion suggestion = new WifiNetworkConfigBuilder()
.setSsid(TEST_SSID)
.setIsAppInteractionRequired()
.buildNetworkSuggestion();
assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
.get(WifiConfiguration.KeyMgmt.NONE));
assertTrue(suggestion.isAppInteractionRequired);
assertFalse(suggestion.isUserInteractionRequired);
assertEquals(WifiConfiguration.METERED_OVERRIDE_NONE,
suggestion.wifiConfiguration.meteredOverride);
assertEquals(-1, suggestion.wifiConfiguration.priority);
}
/**
* Validate correctness of WifiNetworkSuggestion object created by
* {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} for WPA_EAP network which requires
* app interaction and has a priority of zero set.
*/
@Test
public void 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();
}
}

View File

@@ -0,0 +1,212 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net.wifi;
import static android.os.PatternMatcher.PATTERN_LITERAL;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import android.net.MacAddress;
import android.net.MatchAllNetworkSpecifier;
import android.os.Parcel;
import android.os.PatternMatcher;
import android.support.test.filters.SmallTest;
import android.util.Pair;
import org.junit.Test;
/**
* Unit tests for {@link android.net.wifi.WifiNetworkSpecifier}.
*/
@SmallTest
public class WifiNetworkSpecifierTest {
private static final int TEST_UID = 5;
private static final String TEST_SSID = "Test123";
private static final String TEST_BSSID_OUI_BASE_ADDRESS = "12:12:12:00:00:00";
private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00";
private static final String TEST_PRESHARED_KEY = "\"Test123\"";
/**
* Validate that parcel marshalling/unmarshalling works
*/
@Test
public void testWifiNetworkSpecifierParcel() {
WifiConfiguration wifiConfiguration = new WifiConfiguration();
wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
WifiNetworkSpecifier specifier =
new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
wifiConfiguration,
TEST_UID);
Parcel parcelW = Parcel.obtain();
specifier.writeToParcel(parcelW, 0);
byte[] bytes = parcelW.marshall();
parcelW.recycle();
Parcel parcelR = Parcel.obtain();
parcelR.unmarshall(bytes, 0, bytes.length);
parcelR.setDataPosition(0);
WifiNetworkSpecifier parcelSpecifier =
WifiNetworkSpecifier.CREATOR.createFromParcel(parcelR);
assertEquals(specifier, parcelSpecifier);
}
/**
* Validate NetworkSpecifier matching.
* a) Create a network specifier for WPA_PSK network
* b) Ensure that the specifier matches {@code null} and {@link MatchAllNetworkSpecifier}
* specifiers.
*/
@Test
public void testWifiNetworkSpecifierSatisfiesNullAndAllMatch() {
WifiConfiguration wifiConfiguration = new WifiConfiguration();
wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
WifiNetworkSpecifier specifier =
new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
wifiConfiguration,
TEST_UID);
assertTrue(specifier.satisfiedBy(null));
assertTrue(specifier.satisfiedBy(new MatchAllNetworkSpecifier()));
}
/**
* Validate NetworkSpecifier matching.
* a) Create network specifier 1 for WPA_PSK network
* b) Create network specifier 2 with the same params as specifier 1.
* c) Ensure that the specifier 2 is satisfied by specifier 1.
*/
@Test
public void testWifiNetworkSpecifierSatisfiesSame() {
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)),
wifiConfiguration,
TEST_UID);
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)),
wifiConfiguration,
TEST_UID);
assertTrue(specifier2.satisfiedBy(specifier1));
}
/**
* Validate NetworkSpecifier matching.
* a) Create network specifier 1 for WPA_PSK network
* b) Create network specifier 2 with different key mgmt params.
* c) Ensure that the specifier 2 is not satisfied by specifier 1.
*/
@Test
public void testWifiNetworkSpecifierDoesNotSatisfyWhenKeyMgmtDifferent() {
WifiConfiguration wifiConfiguration1 = new WifiConfiguration();
wifiConfiguration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wifiConfiguration1.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)),
wifiConfiguration1,
TEST_UID);
WifiConfiguration wifiConfiguration2 = new WifiConfiguration();
wifiConfiguration2.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
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)),
wifiConfiguration2,
TEST_UID);
assertFalse(specifier2.satisfiedBy(specifier1));
}
/**
* Validate NetworkSpecifier matching.
* a) Create network specifier 1 for WPA_PSK network
* b) Create network specifier 2 with different SSID pattern.
* c) Ensure that the specifier 2 is not satisfied by specifier 1.
*/
@Test
public void testWifiNetworkSpecifierDoesNotSatisfyWhenSsidDifferent() {
WifiConfiguration wifiConfiguration = new WifiConfiguration();
wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
WifiNetworkSpecifier specifier1 =
new WifiNetworkSpecifier(new PatternMatcher("", PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
wifiConfiguration,
TEST_UID);
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)),
wifiConfiguration,
TEST_UID);
assertFalse(specifier2.satisfiedBy(specifier1));
}
/**
* Validate NetworkSpecifier matching.
* a) Create network specifier 1 for WPA_PSK network
* b) Create network specifier 2 with different BSSID pattern.
* c) Ensure that the specifier 2 is not satisfied by specifier 1.
*/
@Test
public void testWifiNetworkSpecifierDoesNotSatisfyWhenBssidDifferent() {
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)),
wifiConfiguration,
TEST_UID);
WifiNetworkSpecifier specifier2 =
new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS),
wifiConfiguration,
TEST_UID);
assertFalse(specifier2.satisfiedBy(specifier1));
}
}

View File

@@ -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);
}
}