summaryrefslogtreecommitdiff
path: root/wifi/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'wifi/java/android')
-rw-r--r--wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl36
-rw-r--r--wifi/java/android/net/wifi/INetworkRequestUserSelectionCallback.aidl31
-rw-r--r--wifi/java/android/net/wifi/ITrafficStateCallback.aidl34
-rw-r--r--wifi/java/android/net/wifi/IWifiManager.aidl12
-rw-r--r--wifi/java/android/net/wifi/ScanResult.java25
-rw-r--r--wifi/java/android/net/wifi/WifiConfiguration.java173
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java654
-rw-r--r--wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java187
-rw-r--r--wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java511
-rw-r--r--wifi/java/android/net/wifi/WifiNetworkSpecifier.java181
-rw-r--r--wifi/java/android/net/wifi/WifiNetworkSuggestion.java143
-rw-r--r--wifi/java/android/net/wifi/WifiScanner.java29
-rw-r--r--wifi/java/android/net/wifi/WifiWakeReasonAndCounts.java163
-rw-r--r--wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java2
-rw-r--r--wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.aidl5
-rw-r--r--wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java180
-rw-r--r--wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java2
-rw-r--r--wifi/java/android/net/wifi/p2p/WifiP2pDevice.java7
-rw-r--r--wifi/java/android/net/wifi/p2p/WifiP2pManager.java31
19 files changed, 2133 insertions, 273 deletions
diff --git a/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl b/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl
new file mode 100644
index 000000000000..f472a021b031
--- /dev/null
+++ b/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl
@@ -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);
+}
diff --git a/wifi/java/android/net/wifi/INetworkRequestUserSelectionCallback.aidl b/wifi/java/android/net/wifi/INetworkRequestUserSelectionCallback.aidl
new file mode 100644
index 000000000000..524cefbb295f
--- /dev/null
+++ b/wifi/java/android/net/wifi/INetworkRequestUserSelectionCallback.aidl
@@ -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();
+}
diff --git a/wifi/java/android/net/wifi/ITrafficStateCallback.aidl b/wifi/java/android/net/wifi/ITrafficStateCallback.aidl
new file mode 100644
index 000000000000..0c8e777f67ba
--- /dev/null
+++ b/wifi/java/android/net/wifi/ITrafficStateCallback.aidl
@@ -0,0 +1,34 @@
+/*
+ * 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;
+
+/**
+ * Interface for Traffic state callback.
+ *
+ * @hide
+ */
+oneway interface ITrafficStateCallback
+{
+ /**
+ * Callback invoked to inform clients about the current traffic state.
+ *
+ * @param state One of the values: {@link #DATA_ACTIVITY_NONE}, {@link #DATA_ACTIVITY_IN},
+ * {@link #DATA_ACTIVITY_OUT} & {@link #DATA_ACTIVITY_INOUT}.
+ * @hide
+ */
+ void onStateChanged(int state);
+}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index af44b7e6cd16..1fd68ec1df70 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -25,7 +25,9 @@ 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;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiActivityEnergyInfo;
@@ -125,7 +127,7 @@ interface IWifiManager
void acquireMulticastLock(IBinder binder, String tag);
- void releaseMulticastLock();
+ void releaseMulticastLock(String tag);
void updateInterfaceIpState(String ifaceName, int mode);
@@ -180,5 +182,13 @@ interface IWifiManager
void registerSoftApCallback(in IBinder binder, in ISoftApCallback callback, int callbackIdentifier);
void unregisterSoftApCallback(int callbackIdentifier);
+
+ 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);
}
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index 3a4e88b49daf..9b9247dba17c 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -86,9 +86,9 @@ public class ScanResult implements Parcelable {
public static final int PROTOCOL_WPA = 1;
/**
* @hide
- * Security protocol type: WPA version 2, also called RSN.
+ * Security protocol type: RSN, for WPA version 2, and version 3.
*/
- public static final int PROTOCOL_WPA2 = 2;
+ public static final int PROTOCOL_RSN = 2;
/**
* @hide
* Security protocol type:
@@ -138,7 +138,21 @@ public class ScanResult implements Parcelable {
* Used for Hotspot 2.0.
*/
public static final int KEY_MGMT_OSEN = 7;
-
+ /**
+ * @hide
+ * Security key management scheme: SAE.
+ */
+ public static final int KEY_MGMT_SAE = 8;
+ /**
+ * @hide
+ * Security key management scheme: OWE.
+ */
+ public static final int KEY_MGMT_OWE = 9;
+ /**
+ * @hide
+ * Security key management scheme: SUITE_B_192.
+ */
+ public static final int KEY_MGMT_EAP_SUITE_B_192 = 10;
/**
* @hide
* No cipher suite.
@@ -159,6 +173,11 @@ public class ScanResult implements Parcelable {
* Cipher suite: CCMP
*/
public static final int CIPHER_CCMP = 3;
+ /**
+ * @hide
+ * Cipher suite: GCMP
+ */
+ public static final int CIPHER_GCMP_256 = 4;
/**
* The detected signal level in dBm, also known as the RSSI.
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 74722787f441..8fc9b9759469 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -23,6 +23,7 @@ import android.content.pm.PackageManager;
import android.net.IpConfiguration;
import android.net.IpConfiguration.ProxySettings;
import android.net.MacAddress;
+import android.net.NetworkSpecifier;
import android.net.ProxyInfo;
import android.net.StaticIpConfiguration;
import android.net.Uri;
@@ -47,7 +48,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";
/**
@@ -125,10 +130,26 @@ public class WifiConfiguration implements Parcelable {
*/
public static final int FT_EAP = 7;
+ /**
+ * Simultaneous Authentication of Equals
+ */
+ public static final int SAE = 8;
+
+ /**
+ * Opportunististic Wireless Encryption
+ */
+ public static final int OWE = 9;
+
+ /**
+ * SUITE_B_192 192 bit level
+ */
+ public static final int SUITE_B_192 = 10;
+
public static final String varName = "key_mgmt";
public static final String[] strings = { "NONE", "WPA_PSK", "WPA_EAP",
- "IEEE8021X", "WPA2_PSK", "OSEN", "FT_PSK", "FT_EAP" };
+ "IEEE8021X", "WPA2_PSK", "OSEN", "FT_PSK", "FT_EAP",
+ "SAE", "OWE", "SUITE_B_192"};
}
/**
@@ -142,7 +163,7 @@ public class WifiConfiguration implements Parcelable {
* is discouraged. WPA-2 (RSN) should be used instead. */
@Deprecated
public static final int WPA = 0;
- /** WPA2/IEEE 802.11i */
+ /** RSN WPA2/WPA3/IEEE 802.11i */
public static final int RSN = 1;
/** HS2.0 r2 OSEN
* @hide
@@ -190,10 +211,14 @@ public class WifiConfiguration implements Parcelable {
public static final int TKIP = 1;
/** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */
public static final int CCMP = 2;
+ /**
+ * AES in Galois/Counter Mode
+ */
+ public static final int GCMP_256 = 3;
public static final String varName = "pairwise";
- public static final String[] strings = { "NONE", "TKIP", "CCMP" };
+ public static final String[] strings = { "NONE", "TKIP", "CCMP", "GCMP_256" };
}
/**
@@ -203,6 +228,7 @@ public class WifiConfiguration implements Parcelable {
* TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0]
* WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key
* WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11)
+ * GCMP_256 = AES in Galois/Counter Mode
* </pre>
*/
public static class GroupCipher {
@@ -226,12 +252,64 @@ public class WifiConfiguration implements Parcelable {
* @hide
*/
public static final int GTK_NOT_USED = 4;
+ /**
+ * AES in Galois/Counter Mode
+ */
+ public static final int GCMP_256 = 5;
public static final String varName = "group";
public static final String[] strings =
{ /* deprecated */ "WEP40", /* deprecated */ "WEP104",
- "TKIP", "CCMP", "GTK_NOT_USED" };
+ "TKIP", "CCMP", "GTK_NOT_USED", "GCMP_256" };
+ }
+
+ /**
+ * Recognized group management ciphers.
+ * <pre>
+ * BIP_CMAC_256 = Cipher-based Message Authentication Code 256 bits
+ * BIP_GMAC_128 = Galois Message Authentication Code 128 bits
+ * BIP_GMAC_256 = Galois Message Authentication Code 256 bits
+ * </pre>
+ */
+ public static class GroupMgmtCipher {
+ private GroupMgmtCipher() { }
+
+ /** CMAC-256 = Cipher-based Message Authentication Code */
+ public static final int BIP_CMAC_256 = 0;
+
+ /** GMAC-128 = Galois Message Authentication Code */
+ public static final int BIP_GMAC_128 = 1;
+
+ /** GMAC-256 = Galois Message Authentication Code */
+ public static final int BIP_GMAC_256 = 2;
+
+ private static final String varName = "groupMgmt";
+
+ private static final String[] strings = { "BIP_CMAC_256",
+ "BIP_GMAC_128", "BIP_GMAC_256"};
+ }
+
+ /**
+ * Recognized suiteB ciphers.
+ * <pre>
+ * ECDHE_ECDSA
+ * ECDHE_RSA
+ * </pre>
+ * @hide
+ */
+ public static class SuiteBCipher {
+ private SuiteBCipher() { }
+
+ /** Diffie-Hellman with Elliptic Curve_ECDSA signature */
+ public static final int ECDHE_ECDSA = 0;
+
+ /** Diffie-Hellman with_RSA signature */
+ public static final int ECDHE_RSA = 1;
+
+ private static final String varName = "SuiteB";
+
+ private static final String[] strings = { "ECDHE_ECDSA", "ECDHE_RSA" };
}
/** Possible status of a network configuration. */
@@ -409,6 +487,17 @@ public class WifiConfiguration implements Parcelable {
*/
public BitSet allowedGroupCiphers;
/**
+ * The set of group management ciphers supported by this configuration.
+ * See {@link GroupMgmtCipher} for descriptions of the values.
+ */
+ public BitSet allowedGroupMgmtCiphers;
+ /**
+ * The set of SuiteB ciphers supported by this configuration.
+ * To be used for WPA3-Enterprise mode.
+ * See {@link SuiteBCipher} for descriptions of the values.
+ */
+ public BitSet allowedSuiteBCiphers;
+ /**
* The enterprise configuration details specifying the EAP method,
* certificates and other settings associated with the EAP.
*/
@@ -733,7 +822,8 @@ public class WifiConfiguration implements Parcelable {
public boolean isOpenNetwork() {
final int cardinality = allowedKeyManagement.cardinality();
final boolean hasNoKeyMgmt = cardinality == 0
- || (cardinality == 1 && allowedKeyManagement.get(KeyMgmt.NONE));
+ || (cardinality == 1 && (allowedKeyManagement.get(KeyMgmt.NONE)
+ || allowedKeyManagement.get(KeyMgmt.OWE)));
boolean hasNoWepKeys = true;
if (wepKeys != null) {
@@ -785,6 +875,23 @@ public class WifiConfiguration implements Parcelable {
/**
* @hide
+ * Use factory MAC when connecting to this network
+ */
+ public static final int RANDOMIZATION_NONE = 0;
+ /**
+ * @hide
+ * Generate a randomized MAC once and reuse it for all connections to this network
+ */
+ public static final int RANDOMIZATION_PERSISTENT = 1;
+
+ /**
+ * @hide
+ * Level of MAC randomization for this network
+ */
+ public int macRandomizationSetting = RANDOMIZATION_PERSISTENT;
+
+ /**
+ * @hide
* Randomized MAC address to use with this particular network
*/
@NonNull
@@ -1521,6 +1628,8 @@ public class WifiConfiguration implements Parcelable {
allowedAuthAlgorithms = new BitSet();
allowedPairwiseCiphers = new BitSet();
allowedGroupCiphers = new BitSet();
+ allowedGroupMgmtCiphers = new BitSet();
+ allowedSuiteBCiphers = new BitSet();
wepKeys = new String[4];
for (int i = 0; i < wepKeys.length; i++) {
wepKeys[i] = null;
@@ -1574,7 +1683,8 @@ public class WifiConfiguration implements Parcelable {
@UnsupportedAppUsage
public boolean isEnterprise() {
return (allowedKeyManagement.get(KeyMgmt.WPA_EAP)
- || allowedKeyManagement.get(KeyMgmt.IEEE8021X))
+ || allowedKeyManagement.get(KeyMgmt.IEEE8021X)
+ || allowedKeyManagement.get(KeyMgmt.SUITE_B_192))
&& enterpriseConfig != null
&& enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE;
}
@@ -1592,6 +1702,7 @@ public class WifiConfiguration implements Parcelable {
append(" BSSID: ").append(this.BSSID).append(" FQDN: ").append(this.FQDN)
.append(" PRIO: ").append(this.priority)
.append(" HIDDEN: ").append(this.hiddenSSID)
+ .append(" PMF: ").append(this.requirePMF)
.append('\n');
@@ -1645,6 +1756,7 @@ public class WifiConfiguration implements Parcelable {
if (this.meteredOverride != METERED_OVERRIDE_NONE) {
sbuf.append(" meteredOverride ").append(meteredOverride).append("\n");
}
+ sbuf.append(" macRandomizationSetting ").append(macRandomizationSetting).append("\n");
sbuf.append(" KeyMgmt:");
for (int k = 0; k < this.allowedKeyManagement.size(); k++) {
if (this.allowedKeyManagement.get(k)) {
@@ -1703,10 +1815,35 @@ public class WifiConfiguration implements Parcelable {
}
}
}
- sbuf.append('\n').append(" PSK: ");
+ sbuf.append('\n');
+ sbuf.append(" GroupMgmtCiphers:");
+ for (int gmc = 0; gmc < this.allowedGroupMgmtCiphers.size(); gmc++) {
+ if (this.allowedGroupMgmtCiphers.get(gmc)) {
+ sbuf.append(" ");
+ if (gmc < GroupMgmtCipher.strings.length) {
+ sbuf.append(GroupMgmtCipher.strings[gmc]);
+ } else {
+ sbuf.append("??");
+ }
+ }
+ }
+ sbuf.append('\n');
+ sbuf.append(" SuiteBCiphers:");
+ for (int sbc = 0; sbc < this.allowedSuiteBCiphers.size(); sbc++) {
+ if (this.allowedSuiteBCiphers.get(sbc)) {
+ sbuf.append(" ");
+ if (sbc < SuiteBCipher.strings.length) {
+ sbuf.append(SuiteBCipher.strings[sbc]);
+ } else {
+ sbuf.append("??");
+ }
+ }
+ }
+ sbuf.append('\n').append(" PSK/SAE: ");
if (this.preSharedKey != null) {
sbuf.append('*');
}
+
sbuf.append("\nEnterprise config:\n");
sbuf.append(enterpriseConfig);
@@ -1869,6 +2006,12 @@ public class WifiConfiguration implements Parcelable {
return KeyMgmt.WPA_EAP;
} else if (allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
return KeyMgmt.IEEE8021X;
+ } else if (allowedKeyManagement.get(KeyMgmt.SAE)) {
+ return KeyMgmt.SAE;
+ } else if (allowedKeyManagement.get(KeyMgmt.OWE)) {
+ return KeyMgmt.OWE;
+ } else if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) {
+ return KeyMgmt.SUITE_B_192;
}
return KeyMgmt.NONE;
}
@@ -1900,6 +2043,12 @@ public class WifiConfiguration implements Parcelable {
key = SSID + KeyMgmt.strings[KeyMgmt.WPA_EAP];
} else if (wepKeys[0] != null) {
key = SSID + "WEP";
+ } else if (allowedKeyManagement.get(KeyMgmt.OWE)) {
+ key = SSID + KeyMgmt.strings[KeyMgmt.OWE];
+ } else if (allowedKeyManagement.get(KeyMgmt.SAE)) {
+ key = SSID + KeyMgmt.strings[KeyMgmt.SAE];
+ } else if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) {
+ key = SSID + KeyMgmt.strings[KeyMgmt.SUITE_B_192];
} else {
key = SSID + KeyMgmt.strings[KeyMgmt.NONE];
}
@@ -2068,6 +2217,8 @@ public class WifiConfiguration implements Parcelable {
allowedAuthAlgorithms = (BitSet) source.allowedAuthAlgorithms.clone();
allowedPairwiseCiphers = (BitSet) source.allowedPairwiseCiphers.clone();
allowedGroupCiphers = (BitSet) source.allowedGroupCiphers.clone();
+ allowedGroupMgmtCiphers = (BitSet) source.allowedGroupMgmtCiphers.clone();
+ allowedSuiteBCiphers = (BitSet) source.allowedSuiteBCiphers.clone();
enterpriseConfig = new WifiEnterpriseConfig(source.enterpriseConfig);
defaultGwMacAddress = source.defaultGwMacAddress;
@@ -2109,6 +2260,8 @@ public class WifiConfiguration implements Parcelable {
shared = source.shared;
recentFailure.setAssociationStatus(source.recentFailure.getAssociationStatus());
mRandomizedMacAddress = source.mRandomizedMacAddress;
+ macRandomizationSetting = source.macRandomizationSetting;
+ requirePMF = source.requirePMF;
}
}
@@ -2144,6 +2297,8 @@ public class WifiConfiguration implements Parcelable {
writeBitSet(dest, allowedAuthAlgorithms);
writeBitSet(dest, allowedPairwiseCiphers);
writeBitSet(dest, allowedGroupCiphers);
+ writeBitSet(dest, allowedGroupMgmtCiphers);
+ writeBitSet(dest, allowedSuiteBCiphers);
dest.writeParcelable(enterpriseConfig, flags);
@@ -2173,6 +2328,7 @@ public class WifiConfiguration implements Parcelable {
dest.writeString(mPasspointManagementObjectTree);
dest.writeInt(recentFailure.getAssociationStatus());
dest.writeParcelable(mRandomizedMacAddress, flags);
+ dest.writeInt(macRandomizationSetting);
}
/** Implement the Parcelable interface {@hide} */
@@ -2211,6 +2367,8 @@ public class WifiConfiguration implements Parcelable {
config.allowedAuthAlgorithms = readBitSet(in);
config.allowedPairwiseCiphers = readBitSet(in);
config.allowedGroupCiphers = readBitSet(in);
+ config.allowedGroupMgmtCiphers = readBitSet(in);
+ config.allowedSuiteBCiphers = readBitSet(in);
config.enterpriseConfig = in.readParcelable(null);
config.setIpConfiguration(in.readParcelable(null));
@@ -2239,6 +2397,7 @@ public class WifiConfiguration implements Parcelable {
config.mPasspointManagementObjectTree = in.readString();
config.recentFailure.setAssociationStatus(in.readInt());
config.mRandomizedMacAddress = in.readParcelable(null);
+ config.macRandomizationSetting = in.readInt();
return config;
}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 15e092bc8623..954b51f02820 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -21,24 +21,21 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
-import android.annotation.SuppressLint;
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.IProvisioningCallback;
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;
@@ -53,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;
@@ -319,6 +315,31 @@ public class WifiManager {
"android.net.wifi.extra.SUBSCRIPTION_REMEDIATION_METHOD";
/**
+ * Activity Action: lunch OSU (Online Sign Up) view.
+ * Included extras:
+ *
+ * {@link #EXTRA_OSU_NETWORK}: {@link Network} instance associated with OSU AP.
+ * {@link #EXTRA_URL}: String representation of a server URL used for OSU process.
+ *
+ * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
+ * components will be launched.
+ *
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_PASSPOINT_LAUNCH_OSU_VIEW =
+ "android.net.wifi.action.PASSPOINT_LAUNCH_OSU_VIEW";
+
+ /**
+ * The lookup key for a {@link android.net.Network} associated with OSU server.
+ *
+ * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}.
+ *
+ * @hide
+ */
+ public static final String EXTRA_OSU_NETWORK = "android.net.wifi.extra.OSU_NETWORK";
+
+ /**
* Broadcast intent action indicating that Wi-Fi has been enabled, disabled,
* enabling, disabling, or unknown. One extra provides this state as an int.
* Another extra provides the previous state, if available.
@@ -759,9 +780,12 @@ public class WifiManager {
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String BATCHED_SCAN_RESULTS_AVAILABLE_ACTION =
"android.net.wifi.BATCHED_RESULTS";
+
/**
* The RSSI (signal strength) has changed.
- * @see #EXTRA_NEW_RSSI
+ *
+ * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
+ * @see {@link #EXTRA_NEW_RSSI}
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED";
@@ -928,22 +952,6 @@ public class WifiManager {
@UnsupportedAppUsage
public static final int WIFI_FREQUENCY_BAND_2GHZ = 2;
- /** List of asyncronous notifications
- * @hide
- */
- public static final int DATA_ACTIVITY_NOTIFICATION = 1;
-
- //Lowest bit indicates data reception and the second lowest
- //bit indicates data transmitted
- /** @hide */
- public static final int DATA_ACTIVITY_NONE = 0x00;
- /** @hide */
- public static final int DATA_ACTIVITY_IN = 0x01;
- /** @hide */
- public static final int DATA_ACTIVITY_OUT = 0x02;
- /** @hide */
- public static final int DATA_ACTIVITY_INOUT = 0x03;
-
/** @hide */
public static final boolean DEFAULT_POOR_NETWORK_AVOIDANCE_ENABLED = false;
@@ -970,6 +978,7 @@ public class WifiManager {
private AsyncChannel mAsyncChannel;
private CountDownLatch mConnected;
private Looper mLooper;
+ private boolean mVerboseLoggingEnabled = false;
/* LocalOnlyHotspot callback message types */
/** @hide */
@@ -1002,6 +1011,7 @@ public class WifiManager {
mService = service;
mLooper = looper;
mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion;
+ updateVerboseLoggingEnabledFromService();
}
/**
@@ -1022,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 =
@@ -1122,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;
@@ -1147,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;
@@ -1172,6 +1212,301 @@ 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
+ * the network was created with {@link WifiNetworkConfigBuilder#setIsAppInteractionRequired()}
+ * flag set 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 that was created with
+ * {@link WifiNetworkConfigBuilder#setIsAppInteractionRequired()} flag set.
+ * Pending intent must hold a foreground service, else will be rejected.
+ * @return true on success, false if any of the suggestions match (See
+ * {@link WifiNetworkSuggestion#equals(Object)} any previously provided suggestions by the app.
+ * @throws {@link SecurityException} if the caller is missing required permissions.
+ */
+ public boolean addNetworkSuggestions(
+ @NonNull List<WifiNetworkSuggestion> networkSuggestions,
+ @Nullable PendingIntent pendingIntent) {
+ // TODO(b/115504887): Implementation
+ return false;
+ }
+
+
+ /**
+ * Remove a subset of or all of networks from previously provided suggestions by the app to the
+ * device.
+ * See {@link WifiNetworkSuggestion} for a detailed explanation of the parameters.
+ * See {@link WifiNetworkSuggestion#equals(Object)} for the equivalence evaluation used.
+ *
+ * @param networkSuggestions List of network suggestions to be removed. Pass an empty list
+ * to remove all the previous suggestions provided by the app.
+ * @return true on success, false if any of the suggestions do not match any suggestions
+ * previously provided by the app. Any matching suggestions are removed from the device and
+ * will not be considered for any further connection attempts.
+ */
+ public boolean removeNetworkSuggestions(
+ @NonNull List<WifiNetworkSuggestion> networkSuggestions) {
+ // TODO(b/115504887): Implementation
+ return false;
+ }
+
+ /**
* Add or update a Passpoint configuration. The configuration provides a credential
* for connecting to Passpoint networks that are operated by the Passpoint
* service provider specified in the configuration.
@@ -1286,7 +1621,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());
@@ -1301,10 +1646,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.
@@ -1322,29 +1665,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;
}
@@ -1359,7 +1697,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());
@@ -1372,7 +1720,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());
@@ -1387,7 +1745,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());
@@ -1402,7 +1770,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());
@@ -1477,7 +1855,12 @@ public class WifiManager {
public static final int WIFI_FEATURE_SCAN_RAND = 0x2000000; // Random MAC & Probe seq
/** @hide */
public static final int WIFI_FEATURE_TX_POWER_LIMIT = 0x4000000; // Set Tx power limit
-
+ /** @hide */
+ public static final int WIFI_FEATURE_WPA3_SAE = 0x8000000; // WPA3-Personal SAE
+ /** @hide */
+ public static final int WIFI_FEATURE_WPA3_SUITE_B = 0x10000000; // WPA3-Enterprise Suite-B
+ /** @hide */
+ public static final int WIFI_FEATURE_OWE = 0x20000000; // Enhanced Open
private int getSupportedFeatures() {
try {
@@ -1596,13 +1979,12 @@ public class WifiManager {
* Return the record of {@link WifiActivityEnergyInfo} object that
* has the activity and energy info. This can be used to ascertain what
* the controller has been up to, since the last sample.
- * @param updateType Type of info, cached vs refreshed.
*
* @return a record with {@link WifiActivityEnergyInfo} or null if
* report is unavailable or unsupported
* @hide
*/
- public WifiActivityEnergyInfo getControllerActivityEnergyInfo(int updateType) {
+ public WifiActivityEnergyInfo getControllerActivityEnergyInfo() {
if (mService == null) return null;
try {
synchronized(this) {
@@ -1686,9 +2068,7 @@ public class WifiManager {
* @return the list of access points found in the most recent scan. An app must hold
* {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
* {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
- * in order to get valid results. If there is a remote exception (e.g., either a communication
- * problem with the system service or an exception within the framework) an empty list will be
- * returned.
+ * in order to get valid results.
*/
public List<ScanResult> getScanResults() {
try {
@@ -1705,7 +2085,10 @@ public class WifiManager {
* even when Wi-Fi is turned off.
*
* To change this setting, see {@link #ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE}.
+ * @deprecated The ability for apps to trigger scan requests will be removed in a future
+ * release.
*/
+ @Deprecated
public boolean isScanAlwaysAvailable() {
try {
return mService.isScanAlwaysAvailable();
@@ -1811,7 +2194,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);
@@ -2465,7 +2853,7 @@ public class WifiManager {
*
* @hide
*/
- private static class SoftApCallbackProxy extends ISoftApCallback.Stub {
+ private class SoftApCallbackProxy extends ISoftApCallback.Stub {
private final Handler mHandler;
private final SoftApCallback mCallback;
@@ -2475,17 +2863,21 @@ public class WifiManager {
}
@Override
- public void onStateChanged(int state, int failureReason) throws RemoteException {
- Log.v(TAG, "SoftApCallbackProxy: onStateChanged: state=" + state + ", failureReason=" +
- failureReason);
+ public void onStateChanged(int state, int failureReason) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "SoftApCallbackProxy: onStateChanged: state=" + state
+ + ", failureReason=" + failureReason);
+ }
mHandler.post(() -> {
mCallback.onStateChanged(state, failureReason);
});
}
@Override
- public void onNumClientsChanged(int numClients) throws RemoteException {
- Log.v(TAG, "SoftApCallbackProxy: onNumClientsChanged: numClients=" + numClients);
+ public void onNumClientsChanged(int numClients) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "SoftApCallbackProxy: onNumClientsChanged: numClients=" + numClients);
+ }
mHandler.post(() -> {
mCallback.onNumClientsChanged(numClients);
});
@@ -3121,10 +3513,9 @@ public class WifiManager {
* an AsyncChannel communication with WifiService
*
* @return Messenger pointing to the WifiService handler
- * @hide
*/
@UnsupportedAppUsage
- public Messenger getWifiServiceMessenger() {
+ private Messenger getWifiServiceMessenger() {
try {
return mService.getWifiServiceMessenger(mContext.getOpPackageName());
} catch (RemoteException e) {
@@ -3425,7 +3816,7 @@ public class WifiManager {
mService.acquireMulticastLock(mBinder, mTag);
synchronized (WifiManager.this) {
if (mActiveLockCount >= MAX_ACTIVE_LOCKS) {
- mService.releaseMulticastLock();
+ mService.releaseMulticastLock(mTag);
throw new UnsupportedOperationException(
"Exceeded maximum number of wifi locks");
}
@@ -3467,7 +3858,7 @@ public class WifiManager {
synchronized (mBinder) {
if (mRefCounted ? (--mRefCount == 0) : (mHeld)) {
try {
- mService.releaseMulticastLock();
+ mService.releaseMulticastLock(mTag);
synchronized (WifiManager.this) {
mActiveLockCount--;
}
@@ -3741,5 +4132,152 @@ public class WifiManager {
mCallback.onProvisioningFailure(status);
});
}
+
+ @Override
+ public void onProvisioningComplete() {
+ mHandler.post(() -> {
+ mCallback.onProvisioningComplete();
+ });
+ }
+ }
+
+ /**
+ * Base class for Traffic state callback. Should be extended by applications and set when
+ * calling {@link WifiManager#registerTrafficStateCallback(TrafficStateCallback, Handler)}.
+ * @hide
+ */
+ public interface TrafficStateCallback {
+ /**
+ * Lowest bit indicates data reception and the second lowest
+ * bit indicates data transmitted
+ */
+ /** @hide */
+ int DATA_ACTIVITY_NONE = 0x00;
+ /** @hide */
+ int DATA_ACTIVITY_IN = 0x01;
+ /** @hide */
+ int DATA_ACTIVITY_OUT = 0x02;
+ /** @hide */
+ int DATA_ACTIVITY_INOUT = 0x03;
+
+ /**
+ * Callback invoked to inform clients about the current traffic state.
+ *
+ * @param state One of the values: {@link #DATA_ACTIVITY_NONE}, {@link #DATA_ACTIVITY_IN},
+ * {@link #DATA_ACTIVITY_OUT} & {@link #DATA_ACTIVITY_INOUT}.
+ * @hide
+ */
+ void onStateChanged(int state);
+ }
+
+ /**
+ * Callback proxy for TrafficStateCallback objects.
+ *
+ * @hide
+ */
+ private class TrafficStateCallbackProxy extends ITrafficStateCallback.Stub {
+ private final Handler mHandler;
+ private final TrafficStateCallback mCallback;
+
+ TrafficStateCallbackProxy(Looper looper, TrafficStateCallback callback) {
+ mHandler = new Handler(looper);
+ mCallback = callback;
+ }
+
+ @Override
+ public void onStateChanged(int state) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "TrafficStateCallbackProxy: onStateChanged state=" + state);
+ }
+ mHandler.post(() -> {
+ mCallback.onStateChanged(state);
+ });
+ }
+ }
+
+ /**
+ * Registers a callback for monitoring traffic state. See {@link TrafficStateCallback}. These
+ * callbacks will be invoked periodically by platform to inform clients about the current
+ * traffic state. Caller can unregister a previously registered callback using
+ * {@link #unregisterTrafficStateCallback(TrafficStateCallback)}
+ * <p>
+ * Applications should have the
+ * {@link android.Manifest.permission#NETWORK_SETTINGS NETWORK_SETTINGS} permission. Callers
+ * without the permission will trigger a {@link java.lang.SecurityException}.
+ * <p>
+ *
+ * @param callback Callback for traffic state 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
+ */
+ @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
+ public void registerTrafficStateCallback(@NonNull TrafficStateCallback callback,
+ @Nullable Handler handler) {
+ if (callback == null) throw new IllegalArgumentException("callback cannot be null");
+ Log.v(TAG, "registerTrafficStateCallback: callback=" + callback + ", handler=" + handler);
+
+ Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper();
+ Binder binder = new Binder();
+ try {
+ mService.registerTrafficStateCallback(
+ binder, new TrafficStateCallbackProxy(looper, callback), callback.hashCode());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Allow callers to unregister a previously registered callback. After calling this method,
+ * applications will no longer receive traffic state notifications.
+ *
+ * @param callback Callback to unregister for traffic state events
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
+ public void unregisterTrafficStateCallback(@NonNull TrafficStateCallback callback) {
+ if (callback == null) throw new IllegalArgumentException("callback cannot be null");
+ Log.v(TAG, "unregisterTrafficStateCallback: callback=" + callback);
+
+ try {
+ mService.unregisterTrafficStateCallback(callback.hashCode());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Helper method to update the local verbose logging flag based on the verbose logging
+ * level from wifi service.
+ */
+ private void updateVerboseLoggingEnabledFromService() {
+ mVerboseLoggingEnabled = getVerboseLoggingLevel() > 0;
+ }
+
+ /**
+ * @return true if this device supports WPA3-Personal SAE
+ * @hide
+ */
+ @SystemApi
+ public boolean isWpa3SaeSupported() {
+ return isFeatureSupported(WIFI_FEATURE_WPA3_SAE);
+ }
+
+ /**
+ * @return true if this device supports WPA3-Enterprise Suite-B-192
+ * @hide
+ */
+ @SystemApi
+ public boolean isWpa3SuiteBSupported() {
+ return isFeatureSupported(WIFI_FEATURE_WPA3_SUITE_B);
+ }
+
+ /**
+ * @return true if this device supports Wi-Fi Enhanced Open (OWE)
+ * @hide
+ */
+ @SystemApi
+ public boolean isOweSupported() {
+ return isFeatureSupported(WIFI_FEATURE_OWE);
}
}
diff --git a/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java
new file mode 100644
index 000000000000..55fde4ca335e
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java
@@ -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.");
+ }
+}
diff --git a/wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java b/wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java
new file mode 100644
index 000000000000..67e218972994
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java
@@ -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() {
+ * ...
+ * {@literal @}Override
+ * void onAvailable(...) {}
+ * // etc.
+ * };
+ * connectivityManager.requestNetwork(request, networkCallback);
+ * }
+ *
+ * @return Instance of {@link NetworkSpecifier}.
+ * @throws IllegalStateException on invalid params set.
+ */
+ public NetworkSpecifier buildNetworkSpecifier() {
+ if (!hasSetAnyPattern()) {
+ throw new IllegalStateException("one of setSsidPattern/setSsid/setBssidPattern/setBssid"
+ + " should be invoked for specifier");
+ }
+ setMatchAnyPatternIfUnset();
+ if (hasSetMatchNonePattern()) {
+ throw new IllegalStateException("cannot set match-none pattern for specifier");
+ }
+ if (hasSetMatchAllPattern()) {
+ throw new IllegalStateException("cannot set match-all pattern for specifier");
+ }
+ if (mIsHiddenSSID && mSsidPatternMatcher.getType() != PatternMatcher.PATTERN_LITERAL) {
+ throw new IllegalStateException("setSsid should also be invoked when "
+ + "setIsHiddenSsid is invoked for network specifier");
+ }
+ if (mIsAppInteractionRequired || mIsUserInteractionRequired
+ || mPriority != -1 || mIsMetered) {
+ throw new IllegalStateException("none of setIsAppInteractionRequired/"
+ + "setIsUserInteractionRequired/setPriority/setIsMetered are allowed for "
+ + "specifier");
+ }
+ 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());
+
+ }
+}
diff --git a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
new file mode 100644
index 000000000000..4348399b404b
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
@@ -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");
+ }
+ }
+}
diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
new file mode 100644
index 000000000000..04b9cb5dfb8d
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.app.PendingIntent;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * The Network Suggestion object is used to provide a Wi-Fi network for consideration when
+ * auto-connecting to networks. Apps cannot directly create this object, they must use
+ * {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} to obtain an instance
+ * of this object.
+ *<p>
+ * Apps can provide a list of such networks to the platform using
+ * {@link WifiManager#addNetworkSuggestions(List, PendingIntent)}.
+ */
+public final class WifiNetworkSuggestion implements Parcelable {
+ /**
+ * Network configuration for the provided network.
+ * @hide
+ */
+ public final WifiConfiguration wifiConfiguration;
+
+ /**
+ * Whether app needs to log in to captive portal to obtain Internet access.
+ * This will dictate if the associated pending intent in
+ * {@link WifiManager#addNetworkSuggestions(List, PendingIntent)} needs to be sent after
+ * successfully connecting to the network.
+ * @hide
+ */
+ public final boolean isAppInteractionRequired;
+
+ /**
+ * Whether user needs to log in to captive portal to obtain Internet access.
+ * @hide
+ */
+ public final boolean isUserInteractionRequired;
+
+ /**
+ * The UID of the process initializing this network suggestion.
+ * @hide
+ */
+ public final int suggestorUid;
+
+ /** @hide */
+ public WifiNetworkSuggestion(WifiConfiguration wifiConfiguration,
+ boolean isAppInteractionRequired,
+ boolean isUserInteractionRequired,
+ int suggestorUid) {
+ checkNotNull(wifiConfiguration);
+
+ this.wifiConfiguration = wifiConfiguration;
+ this.isAppInteractionRequired = isAppInteractionRequired;
+ this.isUserInteractionRequired = isUserInteractionRequired;
+ this.suggestorUid = suggestorUid;
+ }
+
+ public static final Creator<WifiNetworkSuggestion> CREATOR =
+ new Creator<WifiNetworkSuggestion>() {
+ @Override
+ public WifiNetworkSuggestion createFromParcel(Parcel in) {
+ return new WifiNetworkSuggestion(
+ in.readParcelable(null), // wifiConfiguration
+ in.readBoolean(), // isAppInteractionRequired
+ in.readBoolean(), // isUserInteractionRequired
+ in.readInt() // suggestorUid
+ );
+ }
+
+ @Override
+ public WifiNetworkSuggestion[] newArray(int size) {
+ return new WifiNetworkSuggestion[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeParcelable(wifiConfiguration, flags);
+ dest.writeBoolean(isAppInteractionRequired);
+ dest.writeBoolean(isUserInteractionRequired);
+ dest.writeInt(suggestorUid);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(wifiConfiguration.SSID, wifiConfiguration.allowedKeyManagement,
+ suggestorUid);
+ }
+
+ /**
+ * Equals for network suggestions.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof WifiNetworkSuggestion)) {
+ return false;
+ }
+ WifiNetworkSuggestion lhs = (WifiNetworkSuggestion) obj;
+ return Objects.equals(this.wifiConfiguration.SSID, lhs.wifiConfiguration.SSID)
+ && Objects.equals(this.wifiConfiguration.allowedKeyManagement,
+ lhs.wifiConfiguration.allowedKeyManagement)
+ && suggestorUid == lhs.suggestorUid;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("WifiNetworkSuggestion [")
+ .append(", WifiConfiguration=").append(wifiConfiguration)
+ .append(", isAppInteractionRequired=").append(isAppInteractionRequired)
+ .append(", isUserInteractionRequired=").append(isUserInteractionRequired)
+ .append(", suggestorUid=").append(suggestorUid)
+ .append("]");
+ return sb.toString();
+ }
+}
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index 928a1da8b51c..529548f1d2b8 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -16,6 +16,7 @@
package android.net.wifi;
+import android.Manifest;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
@@ -593,17 +594,17 @@ public class WifiScanner {
/** SSID of the network */
public String ssid;
/** Bitmask of the FLAG_XXX */
- public byte flags;
+ public byte flags = 0;
/** Bitmask of the ATUH_XXX */
- public byte authBitField;
+ public byte authBitField = 0;
+ /** frequencies on which the particular network needs to be scanned for */
+ public int[] frequencies = {};
/**
* default constructor for PnoNetwork
*/
public PnoNetwork(String ssid) {
this.ssid = ssid;
- flags = 0;
- authBitField = 0;
}
}
@@ -650,6 +651,7 @@ public class WifiScanner {
dest.writeString(networkList[i].ssid);
dest.writeByte(networkList[i].flags);
dest.writeByte(networkList[i].authBitField);
+ dest.writeIntArray(networkList[i].frequencies);
}
} else {
dest.writeInt(0);
@@ -676,6 +678,7 @@ public class WifiScanner {
PnoNetwork network = new PnoNetwork(ssid);
network.flags = in.readByte();
network.authBitField = in.readByte();
+ network.frequencies = in.createIntArray();
settings.networkList[i] = network;
}
return settings;
@@ -721,6 +724,17 @@ public class WifiScanner {
}
/**
+ * Enable/Disable wifi scanning.
+ *
+ * {@hide}
+ */
+ @RequiresPermission(Manifest.permission.NETWORK_STACK)
+ public void setScanningEnabled(boolean enable) {
+ validateChannel();
+ mAsyncChannel.sendMessage(enable ? CMD_ENABLE : CMD_DISABLE);
+ }
+
+ /**
* Register a listener that will receive results from all single scans
* Either the onSuccess/onFailure will be called once when the listener is registered. After
* (assuming onSuccess was called) all subsequent single scan results will be delivered to the
@@ -916,6 +930,7 @@ public class WifiScanner {
* scans should also not share this object.
* {@hide}
*/
+ @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
public void startDisconnectedPnoScan(ScanSettings scanSettings, PnoSettings pnoSettings,
PnoScanListener listener) {
Preconditions.checkNotNull(listener, "listener cannot be null");
@@ -930,9 +945,9 @@ public class WifiScanner {
* Stop an ongoing wifi PNO scan
* @param listener specifies which scan to cancel; must be same object as passed in {@link
* #startPnoScan}
- * TODO(rpius): Check if we can remove pnoSettings param in stop.
* {@hide}
*/
+ @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
public void stopPnoScan(ScanListener listener) {
Preconditions.checkNotNull(listener, "listener cannot be null");
int key = removeListener(listener);
@@ -1164,6 +1179,10 @@ public class WifiScanner {
public static final int CMD_DEREGISTER_SCAN_LISTENER = BASE + 28;
/** @hide */
public static final int CMD_GET_SINGLE_SCAN_RESULTS = BASE + 29;
+ /** @hide */
+ public static final int CMD_ENABLE = BASE + 30;
+ /** @hide */
+ public static final int CMD_DISABLE = BASE + 31;
private Context mContext;
private IWifiScanner mService;
diff --git a/wifi/java/android/net/wifi/WifiWakeReasonAndCounts.java b/wifi/java/android/net/wifi/WifiWakeReasonAndCounts.java
deleted file mode 100644
index f5cad139bd23..000000000000
--- a/wifi/java/android/net/wifi/WifiWakeReasonAndCounts.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2015 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.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * A class representing wifi wake reason accounting.
- */
-
-/** @hide */
-public class WifiWakeReasonAndCounts implements Parcelable {
- private static final String TAG = "WifiWakeReasonAndCounts";
- /**
- * Wlan can wake host, only when it is cmd/event, local driver-fw
- * functions(non-data, non cmd/event) and rx data.The first packet
- * from wlan that woke up a sleep host is what is accounted here.
- * Total wlan wake to application processor would be:
- * [cmdEventWake + driverFwLocalWake + totalRxDataWake]
- * A further classification is provided for identifying the reasons
- * for wakeup.
- */
- public int totalCmdEventWake;
- public int totalDriverFwLocalWake;
- public int totalRxDataWake;
-
- public int rxUnicast;
- public int rxMulticast;
- public int rxBroadcast;
-
- public int icmp;
- public int icmp6;
- public int icmp6Ra;
- public int icmp6Na;
- public int icmp6Ns;
-
- public int ipv4RxMulticast;
- public int ipv6Multicast;
- public int otherRxMulticast;
- public int[] cmdEventWakeCntArray;
- public int[] driverFWLocalWakeCntArray;
-
- /* {@hide} */
- public WifiWakeReasonAndCounts () {
- }
-
- @Override
- /* {@hide} */
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append(" totalCmdEventWake ").append(totalCmdEventWake);
- sb.append(" totalDriverFwLocalWake ").append(totalDriverFwLocalWake);
- sb.append(" totalRxDataWake ").append(totalRxDataWake);
-
- sb.append(" rxUnicast ").append(rxUnicast);
- sb.append(" rxMulticast ").append(rxMulticast);
- sb.append(" rxBroadcast ").append(rxBroadcast);
-
- sb.append(" icmp ").append(icmp);
- sb.append(" icmp6 ").append(icmp6);
- sb.append(" icmp6Ra ").append(icmp6Ra);
- sb.append(" icmp6Na ").append(icmp6Na);
- sb.append(" icmp6Ns ").append(icmp6Ns);
-
- sb.append(" ipv4RxMulticast ").append(ipv4RxMulticast);
- sb.append(" ipv6Multicast ").append(ipv6Multicast);
- sb.append(" otherRxMulticast ").append(otherRxMulticast);
- for (int i = 0; i < cmdEventWakeCntArray.length; i++) {
- sb.append(" cmdEventWakeCntArray[" + i + "] " + cmdEventWakeCntArray[i]);
- }
- for (int i = 0; i < driverFWLocalWakeCntArray.length; i++) {
- sb.append(" driverFWLocalWakeCntArray[" + i + "] " + driverFWLocalWakeCntArray[i]);
- }
-
- return sb.toString();
- }
-
- /* Implement the Parcelable interface
- * {@hide}
- */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /* Implement the Parcelable interface
- * {@hide}
- */
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(totalCmdEventWake);
- dest.writeInt(totalDriverFwLocalWake);
- dest.writeInt(totalRxDataWake);
-
- dest.writeInt(rxUnicast);
- dest.writeInt(rxMulticast);
- dest.writeInt(rxBroadcast);
-
- dest.writeInt(icmp);
- dest.writeInt(icmp6);
- dest.writeInt(icmp6Ra);
- dest.writeInt(icmp6Na);
- dest.writeInt(icmp6Ns);
-
- dest.writeInt(ipv4RxMulticast);
- dest.writeInt(ipv6Multicast);
- dest.writeInt(otherRxMulticast);
- dest.writeIntArray(cmdEventWakeCntArray);
- dest.writeIntArray(driverFWLocalWakeCntArray);
- }
-
- /* Implement the Parcelable interface
- * {@hide}
- */
- public static final Creator<WifiWakeReasonAndCounts> CREATOR =
- new Creator<WifiWakeReasonAndCounts>() {
- public WifiWakeReasonAndCounts createFromParcel(Parcel in) {
- WifiWakeReasonAndCounts counts = new WifiWakeReasonAndCounts();
- counts.totalCmdEventWake = in.readInt();
- counts.totalDriverFwLocalWake = in.readInt();
- counts.totalRxDataWake = in.readInt();
-
- counts.rxUnicast = in.readInt();
- counts.rxMulticast = in.readInt();
- counts.rxBroadcast = in.readInt();
-
- counts.icmp = in.readInt();
- counts.icmp6 = in.readInt();
- counts.icmp6Ra = in.readInt();
- counts.icmp6Na = in.readInt();
- counts.icmp6Ns = in.readInt();
-
- counts.ipv4RxMulticast = in.readInt();
- counts.ipv6Multicast = in.readInt();
- counts.otherRxMulticast = in.readInt();
- in.readIntArray(counts.cmdEventWakeCntArray);
- in.readIntArray(counts.driverFWLocalWakeCntArray);
- return counts;
- }
- /* Implement the Parcelable interface
- * {@hide}
- */
- @Override
- public WifiWakeReasonAndCounts[] newArray(int size) {
- return new WifiWakeReasonAndCounts[size];
- }
- };
-}
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java
index 7c99c497c54b..14263830660f 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java
@@ -48,7 +48,7 @@ public class WifiAwareAgentNetworkSpecifier extends NetworkSpecifier implements
private MessageDigest mDigester;
public WifiAwareAgentNetworkSpecifier() {
- // do nothing, already initialized to empty
+ initialize();
}
public WifiAwareAgentNetworkSpecifier(WifiAwareNetworkSpecifier ns) {
diff --git a/wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.aidl b/wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.aidl
index c2cb16ab847c..a6bdd5b6bfff 100644
--- a/wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.aidl
+++ b/wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.aidl
@@ -32,5 +32,10 @@ oneway interface IProvisioningCallback
* Service to manager callback providing Provisioning status
*/
void onProvisioningStatus(int status);
+
+ /**
+ * Service to manager callback providing completion of Provisioning/Remediation flow
+ */
+ void onProvisioningComplete();
}
diff --git a/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java b/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java
index 2ea6e797ec93..5c9db539c8f5 100644
--- a/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java
+++ b/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java
@@ -16,11 +16,12 @@
package android.net.wifi.hotspot2;
+import android.net.wifi.WifiManager;
import android.os.Handler;
/**
* Base class for provisioning callbacks. Should be extended by applications and set when calling
- * {@link WifiManager#startSubscriptionProvisiong(OsuProvider, ProvisioningCallback, Handler)}.
+ * {@link WifiManager#startSubscriptionProvisioning(OsuProvider, ProvisioningCallback, Handler)}.
*
* @hide
*/
@@ -28,86 +29,199 @@ public abstract class ProvisioningCallback {
/**
* The reason code for Provisioning Failure due to connection failure to OSU AP.
- * @hide
*/
- public static final int OSU_FAILURE_AP_CONNECTION = 1;
+ public static final int OSU_FAILURE_AP_CONNECTION = 1;
/**
- * The reason code for Provisioning Failure due to connection failure to OSU AP.
- * @hide
+ * The reason code for invalid server URL address.
*/
public static final int OSU_FAILURE_SERVER_URL_INVALID = 2;
/**
- * The reason code for Provisioning Failure due to connection failure to OSU AP.
- * @hide
+ * The reason code for provisioning failure due to connection failure to the server.
*/
- public static final int OSU_FAILURE_SERVER_CONNECTION = 3;
+ public static final int OSU_FAILURE_SERVER_CONNECTION = 3;
/**
- * The reason code for Provisioning Failure due to connection failure to OSU AP.
- * @hide
+ * The reason code for provisioning failure due to invalid server certificate.
*/
- public static final int OSU_FAILURE_SERVER_VALIDATION = 4;
+ public static final int OSU_FAILURE_SERVER_VALIDATION = 4;
/**
- * The reason code for Provisioning Failure due to connection failure to OSU AP.
- * @hide
+ * The reason code for provisioning failure due to invalid service provider.
*/
- public static final int OSU_FAILURE_PROVIDER_VERIFICATION = 5;
+ public static final int OSU_FAILURE_SERVICE_PROVIDER_VERIFICATION = 5;
/**
- * The reason code for Provisioning Failure when a provisioning flow is aborted.
- * @hide
+ * The reason code for provisioning failure when a provisioning flow is aborted.
*/
public static final int OSU_FAILURE_PROVISIONING_ABORTED = 6;
/**
- * The reason code for Provisioning Failure when a provisioning flow is aborted.
- * @hide
+ * The reason code for provisioning failure when a provisioning flow is not possible.
*/
public static final int OSU_FAILURE_PROVISIONING_NOT_AVAILABLE = 7;
/**
- * The status code for Provisioning flow to indicate connecting to OSU AP
- * @hide
+ * The reason code for provisioning failure due to invalid server url.
+ */
+ public static final int OSU_FAILURE_INVALID_SERVER_URL = 8;
+
+ /**
+ * The reason code for provisioning failure when a command received is not the expected command
+ * type.
+ */
+ public static final int OSU_FAILURE_UNEXPECTED_COMMAND_TYPE = 9;
+
+ /**
+ * The reason code for provisioning failure when a SOAP message is not the expected message
+ * type.
+ */
+ public static final int OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_TYPE = 10;
+
+ /**
+ * The reason code for provisioning failure when a SOAP message exchange fails.
+ */
+ public static final int OSU_FAILURE_SOAP_MESSAGE_EXCHANGE = 11;
+
+ /**
+ * The reason code for provisioning failure when a redirect listener fails to start.
+ */
+ public static final int OSU_FAILURE_START_REDIRECT_LISTENER = 12;
+
+ /**
+ * The reason code for provisioning failure when a redirect listener timed out to receive a HTTP
+ * redirect response.
+ */
+ public static final int OSU_FAILURE_TIMED_OUT_REDIRECT_LISTENER = 13;
+
+ /**
+ * The reason code for provisioning failure when there is no OSU activity to listen to
+ * {@link WifiManager#ACTION_PASSPOINT_LAUNCH_OSU_VIEW} intent.
+ */
+ public static final int OSU_FAILURE_NO_OSU_ACTIVITY_FOUND = 14;
+
+ /**
+ * The reason code for provisioning failure when the status of a SOAP message is not the
+ * expected message status.
+ */
+ public static final int OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_STATUS = 15;
+
+ /**
+ * The reason code for provisioning failure when there is no PPS MO.
+ * MO.
+ */
+ public static final int OSU_FAILURE_NO_PPS_MO = 16;
+
+ /**
+ * The reason code for provisioning failure when there is no AAAServerTrustRoot node in a PPS
+ * MO.
+ */
+ public static final int OSU_FAILURE_NO_AAA_SERVER_TRUST_ROOT_NODE = 17;
+
+ /**
+ * The reason code for provisioning failure when there is no TrustRoot node for remediation
+ * server in a PPS MO.
+ */
+ public static final int OSU_FAILURE_NO_REMEDIATION_SERVER_TRUST_ROOT_NODE = 18;
+
+ /**
+ * The reason code for provisioning failure when there is no TrustRoot node for policy server in
+ * a PPS MO.
+ */
+ public static final int OSU_FAILURE_NO_POLICY_SERVER_TRUST_ROOT_NODE = 19;
+
+ /**
+ * The reason code for provisioning failure when failing to retrieve trust root certificates
+ * used for validating server certificate for AAA, Remediation and Policy server.
+ */
+ public static final int OSU_FAILURE_RETRIEVE_TRUST_ROOT_CERTIFICATES = 20;
+
+ /**
+ * The reason code for provisioning failure when there is no trust root certificate for AAA
+ * server.
+ */
+ public static final int OSU_FAILURE_NO_AAA_TRUST_ROOT_CERTIFICATE = 21;
+
+ /**
+ * The reason code for provisioning failure when a {@link PasspointConfiguration} is failed to
+ * install.
+ */
+ public static final int OSU_FAILURE_ADD_PASSPOINT_CONFIGURATION = 22;
+
+ /**
+ * The status code for provisioning flow to indicate connecting to OSU AP
*/
- public static final int OSU_STATUS_AP_CONNECTING = 1;
+ public static final int OSU_STATUS_AP_CONNECTING = 1;
/**
- * The status code for Provisioning flow to indicate connected to OSU AP
- * @hide
+ * The status code for provisioning flow to indicate the OSU AP is connected.
*/
- public static final int OSU_STATUS_AP_CONNECTED = 2;
+ public static final int OSU_STATUS_AP_CONNECTED = 2;
/**
- * The status code for Provisioning flow to indicate connecting to OSU AP
- * @hide
+ * The status code for provisioning flow to indicate connecting to the server.
*/
- public static final int OSU_STATUS_SERVER_CONNECTED = 3;
+ public static final int OSU_STATUS_SERVER_CONNECTING = 3;
/**
- * The status code for Provisioning flow to indicate connecting to OSU AP
- * @hide
+ * The status code for provisioning flow to indicate the server certificate is validated.
*/
- public static final int OSU_STATUS_SERVER_VALIDATED = 4;
+ public static final int OSU_STATUS_SERVER_VALIDATED = 4;
/**
- * The status code for Provisioning flow to indicate connecting to OSU AP
- * @hide
+ * The status code for provisioning flow to indicate the server is connected
*/
- public static final int OSU_STATUS_PROVIDER_VERIFIED = 5;
+ public static final int OSU_STATUS_SERVER_CONNECTED = 5;
+
+ /**
+ * The status code for provisioning flow to indicate starting the first SOAP exchange.
+ */
+ public static final int OSU_STATUS_INIT_SOAP_EXCHANGE = 6;
+
+ /**
+ * The status code for provisioning flow to indicate waiting for a HTTP redirect response.
+ */
+ public static final int OSU_STATUS_WAITING_FOR_REDIRECT_RESPONSE = 7;
+
+ /**
+ * The status code for provisioning flow to indicate a HTTP redirect response is received.
+ */
+ public static final int OSU_STATUS_REDIRECT_RESPONSE_RECEIVED = 8;
+
+ /**
+ * The status code for provisioning flow to indicate starting the second SOAP exchange.
+ */
+ public static final int OSU_STATUS_SECOND_SOAP_EXCHANGE = 9;
+
+ /**
+ * The status code for provisioning flow to indicate starting the third SOAP exchange.
+ */
+ public static final int OSU_STATUS_THIRD_SOAP_EXCHANGE = 10;
+
+ /**
+ * The status code for provisioning flow to indicate starting a step retrieving trust root
+ * certs.
+ */
+ public static final int OSU_STATUS_RETRIEVING_TRUST_ROOT_CERTS = 11;
/**
* Provisioning status for OSU failure
+ *
* @param status indicates error condition
*/
public abstract void onProvisioningFailure(int status);
/**
* Provisioning status when OSU is in progress
+ *
* @param status indicates status of OSU flow
*/
public abstract void onProvisioningStatus(int status);
+
+ /**
+ * Provisioning complete when provisioning/remediation flow completes
+ */
+ public abstract void onProvisioningComplete();
}
diff --git a/wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java b/wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java
index f6183fa219a1..984cf7d62aa5 100644
--- a/wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java
+++ b/wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java
@@ -136,7 +136,7 @@ public final class PpsMoParser {
private static final String NODE_UPDATE_IDENTIFIER = "UpdateIdentifier";
private static final String NODE_AAA_SERVER_TRUST_ROOT = "AAAServerTrustRoot";
private static final String NODE_SUBSCRIPTION_UPDATE = "SubscriptionUpdate";
- private static final String NODE_SUBSCRIPTION_PARAMETER = "SubscriptionParameter";
+ private static final String NODE_SUBSCRIPTION_PARAMETER = "SubscriptionParameters";
private static final String NODE_TYPE_OF_SUBSCRIPTION = "TypeOfSubscription";
private static final String NODE_USAGE_LIMITS = "UsageLimits";
private static final String NODE_DATA_LIMIT = "DataLimit";
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
index 36a50d615a04..22dc2ed32083 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
@@ -21,6 +21,8 @@ import android.os.Parcelable;
import android.os.Parcel;
import android.util.Log;
+import java.util.Objects;
+
import java.util.regex.Pattern;
import java.util.regex.Matcher;
@@ -322,6 +324,11 @@ public class WifiP2pDevice implements Parcelable {
}
@Override
+ public int hashCode() {
+ return Objects.hashCode(deviceAddress);
+ }
+
+ @Override
public String toString() {
StringBuffer sbuf = new StringBuffer();
sbuf.append("Device: ").append(deviceName);
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index 5a4c898c0bcd..e6892bea4595 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -16,9 +16,13 @@
package android.net.wifi.p2p;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
-import android.annotation.SystemService;
import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.net.wifi.WpsInfo;
@@ -480,6 +484,12 @@ public class WifiP2pManager {
/** @hide */
public static final int REPORT_NFC_HANDOVER_FAILED = BASE + 81;
+ /** @hide */
+ public static final int FACTORY_RESET = BASE + 82;
+ /** @hide */
+ public static final int FACTORY_RESET_FAILED = BASE + 83;
+ /** @hide */
+ public static final int FACTORY_RESET_SUCCEEDED = BASE + 84;
/**
* Create a new WifiP2pManager instance. Applications use
@@ -776,6 +786,7 @@ public class WifiP2pManager {
case STOP_LISTEN_FAILED:
case SET_CHANNEL_FAILED:
case REPORT_NFC_HANDOVER_FAILED:
+ case FACTORY_RESET_FAILED:
if (listener != null) {
((ActionListener) listener).onFailure(message.arg1);
}
@@ -802,6 +813,7 @@ public class WifiP2pManager {
case STOP_LISTEN_SUCCEEDED:
case SET_CHANNEL_SUCCEEDED:
case REPORT_NFC_HANDOVER_SUCCEEDED:
+ case FACTORY_RESET_SUCCEEDED:
if (listener != null) {
((ActionListener) listener).onSuccess();
}
@@ -1521,4 +1533,21 @@ public class WifiP2pManager {
c.mAsyncChannel.sendMessage(RESPONDER_REPORT_NFC_HANDOVER, 0,
c.putListener(listener), bundle);
}
+
+ /**
+ * Removes all saved p2p groups.
+ * @param c is the channel created at {@link #initialize}.
+ * @param listener for callback on success or failure. Can be null.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
+ public void factoryReset(@NonNull Channel c, @Nullable ActionListener listener) {
+ checkChannel(c);
+ Bundle callingPackage = new Bundle();
+ callingPackage.putString(CALLING_PACKAGE, c.mContext.getOpPackageName());
+ c.mAsyncChannel.sendMessage(FACTORY_RESET, 0, c.putListener(listener),
+ callingPackage);
+ }
+
}