diff options
Diffstat (limited to 'wifi/java/android/net')
20 files changed, 813 insertions, 326 deletions
diff --git a/wifi/java/android/net/wifi/DppStatusCallback.java b/wifi/java/android/net/wifi/DppStatusCallback.java deleted file mode 100644 index fa2ab30ef479..000000000000 --- a/wifi/java/android/net/wifi/DppStatusCallback.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * 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.annotation.IntDef; -import android.annotation.SystemApi; -import android.os.Handler; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * DPP Status Callback. Use this callback to get status updates (success, failure, progress) - * from the DPP operation started with {@link WifiManager#startDppAsConfiguratorInitiator(String, - * int, int, Handler, DppStatusCallback)} or {@link WifiManager#startDppAsEnrolleeInitiator(String, - * Handler, DppStatusCallback)} - * @hide - */ -@SystemApi -public abstract class DppStatusCallback { - /** - * DPP Success event: Configuration sent (Configurator mode). - */ - public static final int DPP_EVENT_SUCCESS_CONFIGURATION_SENT = 0; - - /** @hide */ - @IntDef(prefix = { "DPP_EVENT_SUCCESS_" }, value = { - DPP_EVENT_SUCCESS_CONFIGURATION_SENT, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface DppSuccessStatusCode {} - - /** - * DPP Progress event: Initial authentication with peer succeeded. - */ - public static final int DPP_EVENT_PROGRESS_AUTHENTICATION_SUCCESS = 0; - - /** - * DPP Progress event: Peer requires more time to process bootstrapping. - */ - public static final int DPP_EVENT_PROGRESS_RESPONSE_PENDING = 1; - - /** @hide */ - @IntDef(prefix = { "DPP_EVENT_PROGRESS_" }, value = { - DPP_EVENT_PROGRESS_AUTHENTICATION_SUCCESS, - DPP_EVENT_PROGRESS_RESPONSE_PENDING, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface DppProgressStatusCode {} - - /** - * DPP Failure event: Scanned QR code is either not a DPP URI, or the DPP URI has errors. - */ - public static final int DPP_EVENT_FAILURE_INVALID_URI = -1; - - /** - * DPP Failure event: Bootstrapping/Authentication initialization process failure. - */ - public static final int DPP_EVENT_FAILURE_AUTHENTICATION = -2; - - /** - * DPP Failure event: Both devices are implementing the same role and are incompatible. - */ - public static final int DPP_EVENT_FAILURE_NOT_COMPATIBLE = -3; - - /** - * DPP Failure event: Configuration process has failed due to malformed message. - */ - public static final int DPP_EVENT_FAILURE_CONFIGURATION = -4; - - /** - * DPP Failure event: DPP request while in another DPP exchange. - */ - public static final int DPP_EVENT_FAILURE_BUSY = -5; - - /** - * DPP Failure event: No response from the peer. - */ - public static final int DPP_EVENT_FAILURE_TIMEOUT = -6; - - /** - * DPP Failure event: General protocol failure. - */ - public static final int DPP_EVENT_FAILURE = -7; - - /** - * DPP Failure event: Feature or option is not supported. - */ - public static final int DPP_EVENT_FAILURE_NOT_SUPPORTED = -8; - - /** - * DPP Failure event: Invalid network provided to DPP configurator. - * Network must either be WPA3-Personal (SAE) or WPA2-Personal (PSK). - */ - public static final int DPP_EVENT_FAILURE_INVALID_NETWORK = -9; - - - /** @hide */ - @IntDef(prefix = {"DPP_EVENT_FAILURE_"}, value = { - DPP_EVENT_FAILURE_INVALID_URI, - DPP_EVENT_FAILURE_AUTHENTICATION, - DPP_EVENT_FAILURE_NOT_COMPATIBLE, - DPP_EVENT_FAILURE_CONFIGURATION, - DPP_EVENT_FAILURE_BUSY, - DPP_EVENT_FAILURE_TIMEOUT, - DPP_EVENT_FAILURE, - DPP_EVENT_FAILURE_NOT_SUPPORTED, - DPP_EVENT_FAILURE_INVALID_NETWORK, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface DppFailureStatusCode { - } - - /** - * Called when local DPP Enrollee successfully receives a new Wi-Fi configuration from the - * peer DPP configurator. This callback marks the successful end of the DPP current DPP - * session, and no further callbacks will be called. This callback is the successful outcome - * of a DPP flow starting with {@link WifiManager#startDppAsEnrolleeInitiator(String, Handler, - * DppStatusCallback)}. - * - * @param newNetworkId New Wi-Fi configuration with a network ID received from the configurator - */ - public abstract void onEnrolleeSuccess(int newNetworkId); - - /** - * Called when a DPP success event takes place, except for when configuration is received from - * an external Configurator. The callback onSuccessConfigReceived will be used in this case. - * This callback marks the successful end of the current DPP session, and no further - * callbacks will be called. This callback is the successful outcome of a DPP flow starting with - * {@link WifiManager#startDppAsConfiguratorInitiator(String, int, int, Handler, - * DppStatusCallback)}. - * - * @param code DPP success status code. - */ - public abstract void onConfiguratorSuccess(@DppSuccessStatusCode int code); - - /** - * Called when a DPP Failure event takes place. This callback marks the unsuccessful end of the - * current DPP session, and no further callbacks will be called. - * - * @param code DPP failure status code. - */ - public abstract void onFailure(@DppFailureStatusCode int code); - - /** - * Called when DPP events that indicate progress take place. Can be used by UI elements - * to show progress. - * - * @param code DPP progress status code. - */ - public abstract void onProgress(@DppProgressStatusCode int code); -} diff --git a/wifi/java/android/net/wifi/EasyConnectStatusCallback.java b/wifi/java/android/net/wifi/EasyConnectStatusCallback.java new file mode 100644 index 000000000000..b8c82fd9e0ae --- /dev/null +++ b/wifi/java/android/net/wifi/EasyConnectStatusCallback.java @@ -0,0 +1,179 @@ +/* + * 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.annotation.IntDef; +import android.annotation.SystemApi; +import android.os.Handler; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Easy Connect (DPP) Status Callback. Use this callback to get status updates (success, failure, + * progress) from the Easy Connect operation started with + * {@link WifiManager#startEasyConnectAsConfiguratorInitiator(String, + * int, int, Handler, EasyConnectStatusCallback)} or + * {@link WifiManager#startEasyConnectAsEnrolleeInitiator(String, + * Handler, EasyConnectStatusCallback)} + * + * @hide + */ +@SystemApi +public abstract class EasyConnectStatusCallback { + /** + * Easy Connect Success event: Configuration sent (Configurator mode). + */ + public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT = 0; + + /** @hide */ + @IntDef(prefix = {"EASY_CONNECT_EVENT_SUCCESS_"}, value = { + EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface EasyConnectSuccessStatusCode { + } + + /** + * Easy Connect Progress event: Initial authentication with peer succeeded. + */ + public static final int EASY_CONNECT_EVENT_PROGRESS_AUTHENTICATION_SUCCESS = 0; + + /** + * Easy Connect Progress event: Peer requires more time to process bootstrapping. + */ + public static final int EASY_CONNECT_EVENT_PROGRESS_RESPONSE_PENDING = 1; + + /** @hide */ + @IntDef(prefix = {"EASY_CONNECT_EVENT_PROGRESS_"}, value = { + EASY_CONNECT_EVENT_PROGRESS_AUTHENTICATION_SUCCESS, + EASY_CONNECT_EVENT_PROGRESS_RESPONSE_PENDING, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface EasyConnectProgressStatusCode { + } + + /** + * Easy Connect Failure event: Scanned QR code is either not a Easy Connect URI, or the Easy + * Connect URI has errors. + */ + public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_URI = -1; + + /** + * Easy Connect Failure event: Bootstrapping/Authentication initialization process failure. + */ + public static final int EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION = -2; + + /** + * Easy Connect Failure event: Both devices are implementing the same role and are incompatible. + */ + public static final int EASY_CONNECT_EVENT_FAILURE_NOT_COMPATIBLE = -3; + + /** + * Easy Connect Failure event: Configuration process has failed due to malformed message. + */ + public static final int EASY_CONNECT_EVENT_FAILURE_CONFIGURATION = -4; + + /** + * Easy Connect Failure event: Easy Connect request while in another Easy Connect exchange. + */ + public static final int EASY_CONNECT_EVENT_FAILURE_BUSY = -5; + + /** + * Easy Connect Failure event: No response from the peer. + */ + public static final int EASY_CONNECT_EVENT_FAILURE_TIMEOUT = -6; + + /** + * Easy Connect Failure event: General protocol failure. + */ + public static final int EASY_CONNECT_EVENT_FAILURE_GENERIC = -7; + + /** + * Easy Connect Failure event: Feature or option is not supported. + */ + public static final int EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED = -8; + + /** + * Easy Connect Failure event: Invalid network provided to Easy Connect configurator. + * Network must either be WPA3-Personal (SAE) or WPA2-Personal (PSK). + */ + public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK = -9; + + + /** @hide */ + @IntDef(prefix = {"EASY_CONNECT_EVENT_FAILURE_"}, value = { + EASY_CONNECT_EVENT_FAILURE_INVALID_URI, + EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION, + EASY_CONNECT_EVENT_FAILURE_NOT_COMPATIBLE, + EASY_CONNECT_EVENT_FAILURE_CONFIGURATION, + EASY_CONNECT_EVENT_FAILURE_BUSY, + EASY_CONNECT_EVENT_FAILURE_TIMEOUT, + EASY_CONNECT_EVENT_FAILURE_GENERIC, + EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED, + EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface EasyConnectFailureStatusCode { + } + + /** + * Called when local Easy Connect Enrollee successfully receives a new Wi-Fi configuration from + * the + * peer Easy Connect configurator. This callback marks the successful end of the Easy Connect + * current Easy Connect + * session, and no further callbacks will be called. This callback is the successful outcome + * of a Easy Connect flow starting with + * {@link WifiManager#startEasyConnectAsEnrolleeInitiator(String, + * Handler, + * EasyConnectStatusCallback)}. + * + * @param newNetworkId New Wi-Fi configuration with a network ID received from the configurator + */ + public abstract void onEnrolleeSuccess(int newNetworkId); + + /** + * Called when a Easy Connect success event takes place, except for when configuration is + * received from + * an external Configurator. The callback onSuccessConfigReceived will be used in this case. + * This callback marks the successful end of the current Easy Connect session, and no further + * callbacks will be called. This callback is the successful outcome of a Easy Connect flow + * starting with + * {@link WifiManager#startEasyConnectAsConfiguratorInitiator(String, int, int, Handler, + * EasyConnectStatusCallback)}. + * + * @param code Easy Connect success status code. + */ + public abstract void onConfiguratorSuccess(@EasyConnectSuccessStatusCode int code); + + /** + * Called when a Easy Connect Failure event takes place. This callback marks the unsuccessful + * end of the + * current Easy Connect session, and no further callbacks will be called. + * + * @param code Easy Connect failure status code. + */ + public abstract void onFailure(@EasyConnectFailureStatusCode int code); + + /** + * Called when Easy Connect events that indicate progress take place. Can be used by UI elements + * to show progress. + * + * @param code Easy Connect progress status code. + */ + public abstract void onProgress(@EasyConnectProgressStatusCode int code); +} diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 5ed368618449..cb265fd46722 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -16,7 +16,6 @@ package android.net.wifi; - import android.content.pm.ParceledListSlice; import android.net.wifi.hotspot2.OsuProvider; @@ -48,7 +47,7 @@ import android.os.WorkSource; */ interface IWifiManager { - int getSupportedFeatures(); + long getSupportedFeatures(); WifiActivityEnergyInfo reportActivityInfo(); @@ -62,11 +61,11 @@ interface IWifiManager ParceledListSlice getConfiguredNetworks(String packageName); - ParceledListSlice getPrivilegedConfiguredNetworks(); + ParceledListSlice getPrivilegedConfiguredNetworks(String packageName); - List<WifiConfiguration> getAllMatchingWifiConfigs(in List<ScanResult> scanResult); + Map getAllMatchingFqdnsForScanResults(in List<ScanResult> scanResult); - List<OsuProvider> getMatchingOsuProviders(in List<ScanResult> scanResult); + Map getMatchingOsuProviders(in List<ScanResult> scanResult); Map getMatchingPasspointConfigsForOsuProviders(in List<OsuProvider> osuProviders); @@ -78,6 +77,8 @@ interface IWifiManager List<PasspointConfiguration> getPasspointConfigurations(); + List<WifiConfiguration> getWifiConfigsForPasspointProfiles(in List<String> fqdnList); + void queryPasspointIcon(long bssid, String fileName); int matchProviderWithCurrentNetwork(String fqdn); diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 963a42662d55..dd82b715e9a5 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -27,7 +27,6 @@ import android.net.NetworkSpecifier; import android.net.ProxyInfo; import android.net.StaticIpConfiguration; import android.net.Uri; -import android.net.wifi.WifiInfo; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -150,26 +149,40 @@ public class WifiConfiguration implements Parcelable { public static final int SUITE_B_192 = 10; /** + * WPA pre-shared key with stronger SHA256-based algorithms. + * @hide + */ + public static final int WPA_PSK_SHA256 = 11; + + /** + * WPA using EAP authentication with stronger SHA256-based algorithms. + * @hide + */ + public static final int WPA_EAP_SHA256 = 12; + + /** * IEEE 802.11ai FILS SK with SHA256 * @hide */ - public static final int FILS_SHA256 = 11; + public static final int FILS_SHA256 = 13; /** * IEEE 802.11ai FILS SK with SHA384: * @hide */ - public static final int FILS_SHA384 = 12; + public static final int FILS_SHA384 = 14; /** * Device Provisioning Protocol * @hide */ - public static final int DPP = 13; + public static final int DPP = 15; 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", - "SAE", "OWE", "SUITE_B_192", "FILS_SHA256", "FILS_SHA384", "DPP"}; + "SAE", "OWE", "SUITE_B_192", "FILS_SHA256", "FILS_SHA384", + "DPP", "WPA_PSK_SHA256", "WPA_EAP_SHA256", + }; } /** @@ -522,7 +535,7 @@ public class WifiConfiguration implements Parcelable { * The set of group management ciphers supported by this configuration. * See {@link GroupMgmtCipher} for descriptions of the values. */ - public BitSet allowedGroupMgmtCiphers; + public BitSet allowedGroupManagementCiphers; /** * The set of SuiteB ciphers supported by this configuration. * To be used for WPA3-Enterprise mode. @@ -975,9 +988,12 @@ public class WifiConfiguration implements Parcelable { } /** - * @hide * Returns MAC address set to be the local randomized MAC address. * Does not guarantee that the returned address is valid for use. + * <p> + * Information is restricted to Device Owner, Profile Owner, and Carrier apps + * (which will only obtain addresses for configurations which they create). Other callers + * will receive a default "02:00:00:00:00:00" MAC address. */ public @NonNull MacAddress getRandomizedMacAddress() { return mRandomizedMacAddress; @@ -1697,7 +1713,7 @@ public class WifiConfiguration implements Parcelable { allowedAuthAlgorithms = new BitSet(); allowedPairwiseCiphers = new BitSet(); allowedGroupCiphers = new BitSet(); - allowedGroupMgmtCiphers = new BitSet(); + allowedGroupManagementCiphers = new BitSet(); allowedSuiteBCiphers = new BitSet(); wepKeys = new String[4]; for (int i = 0; i < wepKeys.length; i++) { @@ -1894,8 +1910,8 @@ public class WifiConfiguration implements Parcelable { } sbuf.append('\n'); sbuf.append(" GroupMgmtCiphers:"); - for (int gmc = 0; gmc < this.allowedGroupMgmtCiphers.size(); gmc++) { - if (this.allowedGroupMgmtCiphers.get(gmc)) { + for (int gmc = 0; gmc < this.allowedGroupManagementCiphers.size(); gmc++) { + if (this.allowedGroupManagementCiphers.get(gmc)) { sbuf.append(" "); if (gmc < GroupMgmtCipher.strings.length) { sbuf.append(GroupMgmtCipher.strings[gmc]); @@ -1957,6 +1973,7 @@ public class WifiConfiguration implements Parcelable { if (creatorName != null) sbuf.append(" cname=" + creatorName); if (lastUpdateUid != 0) sbuf.append(" luid=" + lastUpdateUid); if (lastUpdateName != null) sbuf.append(" lname=" + lastUpdateName); + if (updateIdentifier != null) sbuf.append(" updateIdentifier=" + updateIdentifier); sbuf.append(" lcuid=" + lastConnectUid); sbuf.append(" userApproved=" + userApprovedAsString(userApproved)); sbuf.append(" noInternetAccessExpected=" + noInternetAccessExpected); @@ -2313,7 +2330,7 @@ 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(); + allowedGroupManagementCiphers = (BitSet) source.allowedGroupManagementCiphers.clone(); allowedSuiteBCiphers = (BitSet) source.allowedSuiteBCiphers.clone(); enterpriseConfig = new WifiEnterpriseConfig(source.enterpriseConfig); @@ -2365,6 +2382,7 @@ public class WifiConfiguration implements Parcelable { macRandomizationSetting = source.macRandomizationSetting; requirePMF = source.requirePMF; + updateIdentifier = source.updateIdentifier; } } @@ -2401,7 +2419,7 @@ public class WifiConfiguration implements Parcelable { writeBitSet(dest, allowedAuthAlgorithms); writeBitSet(dest, allowedPairwiseCiphers); writeBitSet(dest, allowedGroupCiphers); - writeBitSet(dest, allowedGroupMgmtCiphers); + writeBitSet(dest, allowedGroupManagementCiphers); writeBitSet(dest, allowedSuiteBCiphers); dest.writeParcelable(enterpriseConfig, flags); @@ -2478,7 +2496,7 @@ public class WifiConfiguration implements Parcelable { config.allowedAuthAlgorithms = readBitSet(in); config.allowedPairwiseCiphers = readBitSet(in); config.allowedGroupCiphers = readBitSet(in); - config.allowedGroupMgmtCiphers = readBitSet(in); + config.allowedGroupManagementCiphers = readBitSet(in); config.allowedSuiteBCiphers = readBitSet(in); config.enterpriseConfig = in.readParcelable(null); diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index 7cdd16a6a4ed..35fba3dcf7cf 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -16,6 +16,7 @@ package android.net.wifi; +import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.net.NetworkInfo.DetailedState; import android.net.NetworkUtils; @@ -93,12 +94,22 @@ public class WifiInfo implements Parcelable { private int mRssi; /** - * Link speed in Mbps + * The unit in which links speeds are expressed. */ public static final String LINK_SPEED_UNITS = "Mbps"; private int mLinkSpeed; /** + * Tx(transmit) Link speed in Mbps + */ + private int mTxLinkSpeed; + + /** + * Rx(receive) Link speed in Mbps + */ + private int mRxLinkSpeed; + + /** * Frequency in MHz */ public static final String FREQUENCY_UNITS = "MHz"; @@ -114,6 +125,11 @@ public class WifiInfo implements Parcelable { private boolean mTrusted; /** + * OSU (Online Sign Up) AP for Passpoint R2. + */ + private boolean mOsuAp; + + /** * Running total count of lost (not ACKed) transmitted unicast data packets. * @hide */ @@ -187,9 +203,12 @@ public class WifiInfo implements Parcelable { setNetworkId(-1); setRssi(INVALID_RSSI); setLinkSpeed(-1); + setTxLinkSpeedMbps(-1); + setRxLinkSpeedMbps(-1); setFrequency(-1); setMeteredHint(false); setEphemeral(false); + setOsuAp(false); txBad = 0; txSuccess = 0; rxSuccess = 0; @@ -213,12 +232,15 @@ public class WifiInfo implements Parcelable { mNetworkId = source.mNetworkId; mRssi = source.mRssi; mLinkSpeed = source.mLinkSpeed; + mTxLinkSpeed = source.mTxLinkSpeed; + mRxLinkSpeed = source.mRxLinkSpeed; mFrequency = source.mFrequency; mIpAddress = source.mIpAddress; mMacAddress = source.mMacAddress; mMeteredHint = source.mMeteredHint; mEphemeral = source.mEphemeral; mTrusted = source.mTrusted; + mOsuAp = source.mOsuAp; txBad = source.txBad; txRetries = source.txRetries; txSuccess = source.txSuccess; @@ -306,7 +328,7 @@ public class WifiInfo implements Parcelable { /** * Returns the current link speed in {@link #LINK_SPEED_UNITS}. - * @return the link speed. + * @return the link speed or -1 if there is no valid value. * @see #LINK_SPEED_UNITS */ public int getLinkSpeed() { @@ -316,7 +338,39 @@ public class WifiInfo implements Parcelable { /** @hide */ @UnsupportedAppUsage public void setLinkSpeed(int linkSpeed) { - this.mLinkSpeed = linkSpeed; + mLinkSpeed = linkSpeed; + } + + /** + * Returns the current transmit link speed in Mbps. + * @return the Tx link speed or -1 if there is no valid value. + */ + public int getTxLinkSpeedMbps() { + return mTxLinkSpeed; + } + + /** + * Update the last transmitted packet bit rate in Mbps. + * @hide + */ + public void setTxLinkSpeedMbps(int txLinkSpeed) { + mTxLinkSpeed = txLinkSpeed; + } + + /** + * Returns the current receive link speed in Mbps. + * @return the Rx link speed or -1 if there is no valid value. + */ + public int getRxLinkSpeedMbps() { + return mRxLinkSpeed; + } + + /** + * Update the last received packet bit rate in Mbps. + * @hide + */ + public void setRxLinkSpeedMbps(int rxLinkSpeed) { + mRxLinkSpeed = rxLinkSpeed; } /** @@ -411,6 +465,16 @@ public class WifiInfo implements Parcelable { return mTrusted; } + /** {@hide} */ + public void setOsuAp(boolean osuAp) { + mOsuAp = osuAp; + } + + /** {@hide} */ + @SystemApi + public boolean isOsuAp() { + return mOsuAp; + } /** @hide */ @UnsupportedAppUsage @@ -513,17 +577,19 @@ public class WifiInfo implements Parcelable { StringBuffer sb = new StringBuffer(); String none = "<none>"; - sb.append("SSID: ").append(mWifiSsid == null ? WifiSsid.NONE : mWifiSsid). - append(", BSSID: ").append(mBSSID == null ? none : mBSSID). - append(", MAC: ").append(mMacAddress == null ? none : mMacAddress). - append(", Supplicant state: "). - append(mSupplicantState == null ? none : mSupplicantState). - append(", RSSI: ").append(mRssi). - append(", Link speed: ").append(mLinkSpeed).append(LINK_SPEED_UNITS). - append(", Frequency: ").append(mFrequency).append(FREQUENCY_UNITS). - append(", Net ID: ").append(mNetworkId). - append(", Metered hint: ").append(mMeteredHint). - append(", score: ").append(Integer.toString(score)); + sb.append("SSID: ").append(mWifiSsid == null ? WifiSsid.NONE : mWifiSsid) + .append(", BSSID: ").append(mBSSID == null ? none : mBSSID) + .append(", MAC: ").append(mMacAddress == null ? none : mMacAddress) + .append(", Supplicant state: ") + .append(mSupplicantState == null ? none : mSupplicantState) + .append(", RSSI: ").append(mRssi) + .append(", Link speed: ").append(mLinkSpeed).append(LINK_SPEED_UNITS) + .append(", Tx Link speed: ").append(mTxLinkSpeed).append(LINK_SPEED_UNITS) + .append(", Rx Link speed: ").append(mRxLinkSpeed).append(LINK_SPEED_UNITS) + .append(", Frequency: ").append(mFrequency).append(FREQUENCY_UNITS) + .append(", Net ID: ").append(mNetworkId) + .append(", Metered hint: ").append(mMeteredHint) + .append(", score: ").append(Integer.toString(score)); return sb.toString(); } @@ -537,6 +603,8 @@ public class WifiInfo implements Parcelable { dest.writeInt(mNetworkId); dest.writeInt(mRssi); dest.writeInt(mLinkSpeed); + dest.writeInt(mTxLinkSpeed); + dest.writeInt(mRxLinkSpeed); dest.writeInt(mFrequency); if (mIpAddress != null) { dest.writeByte((byte)1); @@ -565,6 +633,7 @@ public class WifiInfo implements Parcelable { dest.writeLong(rxSuccess); dest.writeDouble(rxSuccessRate); mSupplicantState.writeToParcel(dest, flags); + dest.writeInt(mOsuAp ? 1 : 0); } /** Implement the Parcelable interface {@hide} */ @@ -576,6 +645,8 @@ public class WifiInfo implements Parcelable { info.setNetworkId(in.readInt()); info.setRssi(in.readInt()); info.setLinkSpeed(in.readInt()); + info.setTxLinkSpeedMbps(in.readInt()); + info.setRxLinkSpeedMbps(in.readInt()); info.setFrequency(in.readInt()); if (in.readByte() == 1) { try { @@ -600,6 +671,7 @@ public class WifiInfo implements Parcelable { info.rxSuccess = in.readLong(); info.rxSuccessRate = in.readDouble(); info.mSupplicantState = SupplicantState.CREATOR.createFromParcel(in); + info.mOsuAp = in.readInt() != 0; return info; } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 5bbd2687a442..c46e322052a6 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -16,6 +16,11 @@ package android.net.wifi; +import static android.Manifest.permission.ACCESS_COARSE_LOCATION; +import static android.Manifest.permission.ACCESS_WIFI_STATE; +import static android.Manifest.permission.READ_WIFI_CREDENTIAL; + +import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -44,6 +49,7 @@ import android.os.Messenger; import android.os.RemoteException; import android.os.WorkSource; import android.util.Log; +import android.util.Pair; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; @@ -63,6 +69,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executor; /** * This class provides the primary API for managing all aspects of Wi-Fi @@ -184,6 +191,7 @@ public class WifiManager { */ public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID = 5; + /** @hide */ @IntDef(prefix = { "STATUS_NETWORK_SUGGESTIONS_" }, value = { STATUS_NETWORK_SUGGESTIONS_SUCCESS, STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL, @@ -242,6 +250,14 @@ public class WifiManager { @SystemApi public static final int WIFI_CREDENTIAL_FORGOT = 1; + /** @hide */ + @SystemApi + public static final int PASSPOINT_HOME_NETWORK = 0; + + /** @hide */ + @SystemApi + public static final int PASSPOINT_ROAMING_NETWORK = 1; + /** * Broadcast intent action indicating that a Passpoint provider icon has been received. * @@ -1196,6 +1212,10 @@ public class WifiManager { /** * Return a list of all the networks configured for the current foreground * user. + * + * Requires the same permissions as {@link #getScanResults}. + * If such access is not allowed, this API will always return an empty list. + * * Not all fields of WifiConfiguration are returned. Only the following * fields are filled in: * <ul> @@ -1219,9 +1239,12 @@ public class WifiManager { * {@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. + * {@link android.os.Build.VERSION_CODES#Q} or above, this API will return an empty list, + * except to callers with Carrier privilege which will receive a restricted list only + * containing configurations which they created. */ @Deprecated + @RequiresPermission(allOf = {ACCESS_COARSE_LOCATION, ACCESS_WIFI_STATE}) public List<WifiConfiguration> getConfiguredNetworks() { try { ParceledListSlice<WifiConfiguration> parceledList = @@ -1237,11 +1260,11 @@ public class WifiManager { /** @hide */ @SystemApi - @RequiresPermission(android.Manifest.permission.READ_WIFI_CREDENTIAL) + @RequiresPermission(allOf = {ACCESS_COARSE_LOCATION, ACCESS_WIFI_STATE, READ_WIFI_CREDENTIAL}) public List<WifiConfiguration> getPrivilegedConfiguredNetworks() { try { ParceledListSlice<WifiConfiguration> parceledList = - mService.getPrivilegedConfiguredNetworks(); + mService.getPrivilegedConfiguredNetworks(mContext.getOpPackageName()); if (parceledList == null) { return Collections.emptyList(); } @@ -1252,25 +1275,47 @@ public class WifiManager { } /** - * Returns all matching WifiConfigurations for a given list of ScanResult. + * Returns a list of all matching WifiConfigurations for a given list of ScanResult. * * An empty list will be returned when no configurations are installed or if no configurations * match the ScanResult. - + * * @param scanResults a list of scanResult that represents the BSSID - * @return A list of {@link WifiConfiguration} that can have duplicate entries. + * @return List that consists of {@link WifiConfiguration} and corresponding scanResults per + * network type({@link #PASSPOINT_HOME_NETWORK} and {@link #PASSPOINT_ROAMING_NETWORK}). * @throws UnsupportedOperationException if Passpoint is not enabled on the device. * @hide */ @SystemApi - @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public List<WifiConfiguration> getAllMatchingWifiConfigs( + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_SETUP_WIZARD + }) + public List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> getAllMatchingWifiConfigs( @NonNull List<ScanResult> scanResults) { + List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> configs = new ArrayList<>(); try { - return mService.getAllMatchingWifiConfigs(scanResults); + Map<String, Map<Integer, List<ScanResult>>> results = + mService.getAllMatchingFqdnsForScanResults( + scanResults); + if (results.isEmpty()) { + return configs; + } + List<WifiConfiguration> wifiConfigurations = + mService.getWifiConfigsForPasspointProfiles( + new ArrayList<>(results.keySet())); + for (WifiConfiguration configuration : wifiConfigurations) { + Map<Integer, List<ScanResult>> scanResultsPerNetworkType = results.get( + configuration.FQDN); + if (scanResultsPerNetworkType != null) { + configs.add(Pair.create(configuration, scanResultsPerNetworkType)); + } + } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } + + return configs; } /** @@ -1280,12 +1325,17 @@ public class WifiManager { * An empty list will be returned if no match is found. * * @param scanResults a list of ScanResult - * @return A list of {@link OsuProvider} that does not contain duplicate entries. + * @return Map that consists {@link OsuProvider} and a list of matching {@link ScanResult} * @throws UnsupportedOperationException if Passpoint is not enabled on the device. * @hide */ - @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public List<OsuProvider> getMatchingOsuProviders(List<ScanResult> scanResults) { + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_SETUP_WIZARD + }) + public Map<OsuProvider, List<ScanResult>> getMatchingOsuProviders( + List<ScanResult> scanResults) { try { return mService.getMatchingOsuProviders(scanResults); } catch (RemoteException e) { @@ -1306,7 +1356,11 @@ public class WifiManager { * @throws UnsupportedOperationException if Passpoint is not enabled on the device. * @hide */ - @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_SETUP_WIZARD + }) public Map<OsuProvider, PasspointConfiguration> getMatchingPasspointConfigsForOsuProviders( @NonNull Set<OsuProvider> osuProviders) { try { @@ -1724,7 +1778,7 @@ public class WifiManager { * suggestion back using this API.</li> * * @param networkSuggestions List of network suggestions provided by the app. - * @return Status code corresponding to the values in {@link NetworkSuggestionsStatusCode}. + * @return Status code for the operation. One of the STATUS_NETWORK_SUGGESTIONS_ values. * {@link WifiNetworkSuggestion#equals(Object)} any previously provided suggestions by the app. * @throws {@link SecurityException} if the caller is missing required permissions. */ @@ -1745,8 +1799,7 @@ public class WifiManager { * * @param networkSuggestions List of network suggestions to be removed. Pass an empty list * to remove all the previous suggestions provided by the app. - * @return Status code corresponding to the values in - * {@link NetworkSuggestionsStatusCode}. + * @return Status code for the operation. One of the STATUS_NETWORK_SUGGESTIONS_ values. * Any matching suggestions are removed from the device and will not be considered for any * further connection attempts. */ @@ -1799,7 +1852,13 @@ public class WifiManager { * @param fqdn The FQDN of the Passpoint configuration to be removed * @throws IllegalArgumentException if no configuration is associated with the given FQDN. * @throws UnsupportedOperationException if Passpoint is not enabled on the device. + * @deprecated This is no longer supported. */ + @Deprecated + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_SETUP_WIZARD + }) public void removePasspointConfiguration(String fqdn) { try { if (!mService.removePasspointConfiguration(fqdn, mContext.getOpPackageName())) { @@ -1817,7 +1876,13 @@ public class WifiManager { * * @return A list of {@link PasspointConfiguration} * @throws UnsupportedOperationException if Passpoint is not enabled on the device. + * @deprecated This is no longer supported. */ + @Deprecated + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_SETUP_WIZARD + }) public List<PasspointConfiguration> getPasspointConfigurations() { try { return mService.getPasspointConfigurations(); @@ -2127,7 +2192,7 @@ public class WifiManager { /** @hide */ public static final int WIFI_FEATURE_DPP = 0x80000000; // DPP (Easy-Connect) - private int getSupportedFeatures() { + private long getSupportedFeatures() { try { return mService.getSupportedFeatures(); } catch (RemoteException e) { @@ -2135,7 +2200,7 @@ public class WifiManager { } } - private boolean isFeatureSupported(int feature) { + private boolean isFeatureSupported(long feature) { return (getSupportedFeatures() & feature) == feature; } /** @@ -4428,6 +4493,11 @@ public class WifiManager { * @param callback {@link ProvisioningCallback} for updates regarding provisioning flow * @hide */ + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_SETUP_WIZARD + }) public void startSubscriptionProvisioning(OsuProvider provider, ProvisioningCallback callback, @Nullable Handler handler) { Looper looper = (handler == null) ? Looper.getMainLooper() : handler.getLooper(); @@ -4789,9 +4859,14 @@ public class WifiManager { } /** - * @return true if this device supports Wi-Fi Device Provisioning Protocol (Easy-connect) + * Wi-Fi Easy Connect (DPP) introduces standardized mechanisms to simplify the provisioning and + * configuration of Wi-Fi devices. + * For more details, visit <a href="https://www.wi-fi.org/">https://www.wi-fi.org/</a> and + * search for "Easy Connect" or "Device Provisioning Protocol specification". + * + * @return true if this device supports Wi-Fi Easy-connect (Device Provisioning Protocol) */ - public boolean isDppSupported() { + public boolean isEasyConnectSupported() { return isFeatureSupported(WIFI_FEATURE_DPP); } @@ -4875,93 +4950,101 @@ public class WifiManager { } } - /* DPP - Device Provisioning Protocol AKA "Easy Connect" */ + /* Easy Connect - AKA Device Provisioning Protocol (DPP) */ /** - * DPP Network role: Station. + * Easy Connect Network role: Station. + * * @hide */ @SystemApi - public static final int DPP_NETWORK_ROLE_STA = 0; + public static final int EASY_CONNECT_NETWORK_ROLE_STA = 0; /** - * DPP Network role: Access Point. + * Easy Connect Network role: Access Point. + * * @hide */ @SystemApi - public static final int DPP_NETWORK_ROLE_AP = 1; + public static final int EASY_CONNECT_NETWORK_ROLE_AP = 1; /** @hide */ - @IntDef(prefix = {"DPP_NETWORK_ROLE_"}, value = { - DPP_NETWORK_ROLE_STA, - DPP_NETWORK_ROLE_AP, + @IntDef(prefix = {"EASY_CONNECT_NETWORK_ROLE_"}, value = { + EASY_CONNECT_NETWORK_ROLE_STA, + EASY_CONNECT_NETWORK_ROLE_AP, }) @Retention(RetentionPolicy.SOURCE) - public @interface DppNetworkRole {} + public @interface EasyConnectNetworkRole { + } /** - * Start DPP in Configurator-Initiator role. The current device will initiate DPP bootstrapping - * with a peer, and configure the peer with the SSID and password of the specified network using - * the DPP protocol on an encrypted link. + * Start Easy Connect (DPP) in Configurator-Initiator role. The current device will initiate + * Easy Connect bootstrapping with a peer, and configure the peer with the SSID and password of + * the specified network using the Easy Connect protocol on an encrypted link. * - * @param enrolleeUri URI of the Enrollee obtained separately (e.g. QR code scanning) - * @param selectedNetworkId Selected network ID to be sent to the peer + * @param enrolleeUri URI of the Enrollee obtained separately (e.g. QR code scanning) + * @param selectedNetworkId Selected network ID to be sent to the peer * @param enrolleeNetworkRole The network role of the enrollee - * @param callback Callback for status updates - * @param handler The handler on whose thread to execute the callbacks. Null for main thread. + * @param callback Callback for status updates + * @param executor The Executor on which to run the callback. * @hide */ @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) - public void startDppAsConfiguratorInitiator(@NonNull String enrolleeUri, - int selectedNetworkId, @DppNetworkRole int enrolleeNetworkRole, - @Nullable Handler handler, @NonNull DppStatusCallback callback) { - Looper looper = (handler == null) ? Looper.getMainLooper() : handler.getLooper(); + public void startEasyConnectAsConfiguratorInitiator(@NonNull String enrolleeUri, + int selectedNetworkId, @EasyConnectNetworkRole int enrolleeNetworkRole, + @NonNull @CallbackExecutor Executor executor, + @NonNull EasyConnectStatusCallback callback) { Binder binder = new Binder(); try { mService.startDppAsConfiguratorInitiator(binder, enrolleeUri, selectedNetworkId, - enrolleeNetworkRole, new DppCallbackProxy(looper, callback)); + enrolleeNetworkRole, new EasyConnectCallbackProxy(executor, callback)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** - * Start DPP in Enrollee-Initiator role. The current device will initiate DPP bootstrapping - * with a peer, and receive the SSID and password from the peer configurator. + * Start Easy Connect (DPP) in Enrollee-Initiator role. The current device will initiate Easy + * Connect bootstrapping with a peer, and receive the SSID and password from the peer + * configurator. * * @param configuratorUri URI of the Configurator obtained separately (e.g. QR code scanning) - * @param callback Callback for status updates - * @param handler The handler on whose thread to execute the callbacks. Null for main thread. + * @param callback Callback for status updates + * @param executor The Executor on which to run the callback. * @hide */ @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) - public void startDppAsEnrolleeInitiator(@NonNull String configuratorUri, - @Nullable Handler handler, @NonNull DppStatusCallback callback) { - Looper looper = (handler == null) ? Looper.getMainLooper() : handler.getLooper(); + public void startEasyConnectAsEnrolleeInitiator(@NonNull String configuratorUri, + @NonNull @CallbackExecutor Executor executor, + @NonNull EasyConnectStatusCallback callback) { Binder binder = new Binder(); try { mService.startDppAsEnrolleeInitiator(binder, configuratorUri, - new DppCallbackProxy(looper, callback)); + new EasyConnectCallbackProxy(executor, callback)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** - * Stop or abort a current DPP session. + * Stop or abort a current Easy Connect (DPP) session. This call, once processed, will + * terminate any ongoing transaction, and clean up all associated resources. Caller should not + * expect any callbacks once this call is made. However, due to the asynchronous nature of + * this call, a callback may be fired if it was already pending in the queue. + * * @hide */ @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) - public void stopDppSession() { + public void stopEasyConnectSession() { try { /* Request lower layers to stop/abort and clear resources */ mService.stopDppSession(); @@ -4971,48 +5054,50 @@ public class WifiManager { } /** - * Helper class to support DPP callbacks + * Helper class to support Easy Connect (DPP) callbacks + * * @hide */ @SystemApi - private static class DppCallbackProxy extends IDppCallback.Stub { - private final Handler mHandler; - private final DppStatusCallback mDppStatusCallback; + private static class EasyConnectCallbackProxy extends IDppCallback.Stub { + private final Executor mExecutor; + private final EasyConnectStatusCallback mEasyConnectStatusCallback; - DppCallbackProxy(Looper looper, DppStatusCallback dppStatusCallback) { - mHandler = new Handler(looper); - mDppStatusCallback = dppStatusCallback; + EasyConnectCallbackProxy(Executor executor, + EasyConnectStatusCallback easyConnectStatusCallback) { + mExecutor = executor; + mEasyConnectStatusCallback = easyConnectStatusCallback; } @Override public void onSuccessConfigReceived(int newNetworkId) { - Log.d(TAG, "DPP onSuccessConfigReceived callback"); - mHandler.post(() -> { - mDppStatusCallback.onEnrolleeSuccess(newNetworkId); + Log.d(TAG, "Easy Connect onSuccessConfigReceived callback"); + mExecutor.execute(() -> { + mEasyConnectStatusCallback.onEnrolleeSuccess(newNetworkId); }); } @Override public void onSuccess(int status) { - Log.d(TAG, "DPP onSuccess callback"); - mHandler.post(() -> { - mDppStatusCallback.onConfiguratorSuccess(status); + Log.d(TAG, "Easy Connect onSuccess callback"); + mExecutor.execute(() -> { + mEasyConnectStatusCallback.onConfiguratorSuccess(status); }); } @Override public void onFailure(int status) { - Log.d(TAG, "DPP onFailure callback"); - mHandler.post(() -> { - mDppStatusCallback.onFailure(status); + Log.d(TAG, "Easy Connect onFailure callback"); + mExecutor.execute(() -> { + mEasyConnectStatusCallback.onFailure(status); }); } @Override public void onProgress(int status) { - Log.d(TAG, "DPP onProgress callback"); - mHandler.post(() -> { - mDppStatusCallback.onProgress(status); + Log.d(TAG, "Easy Connect onProgress callback"); + mExecutor.execute(() -> { + mEasyConnectStatusCallback.onProgress(status); }); } } diff --git a/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java index 955e040a46f1..aa1669ee6d94 100644 --- a/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java +++ b/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java @@ -168,8 +168,9 @@ public final class WifiNetworkAgentSpecifier extends NetworkSpecifier implements @Override public String toString() { StringBuilder sb = new StringBuilder("WifiNetworkAgentSpecifier ["); - sb.append("WifiConfiguration=").append( - mWifiConfiguration == null ? null : mWifiConfiguration.configKey()) + sb.append("WifiConfiguration=") + .append(", SSID=").append(mWifiConfiguration.SSID) + .append(", BSSID=").append(mWifiConfiguration.BSSID) .append(", mOriginalRequestorUid=").append(mOriginalRequestorUid) .append("]"); return sb.toString(); @@ -180,4 +181,9 @@ public final class WifiNetworkAgentSpecifier extends NetworkSpecifier implements throw new IllegalStateException("WifiNetworkAgentSpecifier should never be used " + "for requests."); } + + @Override + public NetworkSpecifier redact() { + return null; + } } diff --git a/wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java b/wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java index f73b9e5e2a00..ecee5ff0161d 100644 --- a/wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java +++ b/wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java @@ -412,7 +412,7 @@ public class WifiNetworkConfigBuilder { configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192); configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256); // TODO (b/113878056): Verify these params once we verify SuiteB configuration. - configuration.allowedGroupMgmtCiphers.set( + configuration.allowedGroupManagementCiphers.set( WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256); configuration.allowedSuiteBCiphers.set( WifiConfiguration.SuiteBCipher.ECDHE_ECDSA); diff --git a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java index 4348399b404b..6e4eeef4dd55 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java +++ b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java @@ -162,11 +162,11 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc @Override public String toString() { return new StringBuilder() - .append("WifiNetworkSpecifierWifiNetworkSpecifier [") + .append("WifiNetworkSpecifier [") .append(", SSID Match pattern=").append(ssidPatternMatcher) .append(", BSSID Match pattern=").append(bssidPatternMatcher) - .append(", WifiConfiguration=").append( - wifiConfiguration == null ? null : wifiConfiguration.configKey()) + .append(", SSID=").append(wifiConfiguration.SSID) + .append(", BSSID=").append(wifiConfiguration.BSSID) .append(", requestorUid=").append(requestorUid) .append("]") .toString(); diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java index 760f1e6bc5e2..3c90eb763e81 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java +++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java @@ -130,7 +130,8 @@ public final class WifiNetworkSuggestion implements Parcelable { @Override public String toString() { StringBuilder sb = new StringBuilder("WifiNetworkSuggestion [") - .append(", WifiConfiguration=").append(wifiConfiguration) + .append(", SSID=").append(wifiConfiguration.SSID) + .append(", BSSID=").append(wifiConfiguration.BSSID) .append(", isAppInteractionRequired=").append(isAppInteractionRequired) .append(", isUserInteractionRequired=").append(isUserInteractionRequired) .append(", suggestorUid=").append(suggestorUid) diff --git a/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java index 14263830660f..4bee837d6089 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java @@ -149,6 +149,11 @@ public class WifiAwareAgentNetworkSpecifier extends NetworkSpecifier implements "WifiAwareAgentNetworkSpecifier should not be used in network requests"); } + @Override + public NetworkSpecifier redact() { + return null; + } + private void initialize() { try { mDigester = MessageDigest.getInstance("SHA-256"); diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java index 26a6c08bee29..1fa1fd521a8e 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java @@ -35,6 +35,7 @@ import android.os.Looper; import android.os.Message; import android.os.Process; import android.os.RemoteException; +import android.text.TextUtils; import android.util.Log; import libcore.util.HexEncoding; @@ -434,6 +435,8 @@ public class WifiAwareManager { null, // peerMac (not used in this method) pmk, passphrase, + 0, // no port info for deprecated IB APIs + -1, // no transport info for deprecated IB APIs Process.myUid()); } @@ -473,6 +476,8 @@ public class WifiAwareManager { peer, pmk, passphrase, + 0, // no port info for OOB APIs + -1, // no transport protocol info for OOB APIs Process.myUid()); } @@ -824,6 +829,8 @@ public class WifiAwareManager { private PeerHandle mPeerHandle; private String mPskPassphrase; private byte[] mPmk; + private int mPort = 0; // invalid value + private int mTransportProtocol = -1; // invalid value /** * Configure the {@link PublishDiscoverySession} or {@link SubscribeDiscoverySession} @@ -902,6 +909,55 @@ public class WifiAwareManager { } /** + * Configure the port number which will be used to create a connection over this link. This + * configuration should only be done on the server device, e.g. the device creating the + * {@link java.net.ServerSocket}. + * <p>Notes: + * <ul> + * <li>The server device must be the Publisher device! + * <li>The port information can only be specified on secure links, specified using + * {@link #setPskPassphrase(String)}. + * </ul> + * + * @param port A positive integer indicating the port to be used for communication. + * @return the current {@link NetworkSpecifierBuilder} builder, enabling chaining of builder + * methods. + */ + public @NonNull NetworkSpecifierBuilder setPort(int port) { + if (port <= 0 || port > 65535) { + throw new IllegalArgumentException("The port must be a positive value (0, 65535]"); + } + mPort = port; + return this; + } + + /** + * Configure the transport protocol which will be used to create a connection over this + * link. This configuration should only be done on the server device, e.g. the device + * creating the {@link java.net.ServerSocket} for TCP. + * <p>Notes: + * <ul> + * <li>The server device must be the Publisher device! + * <li>The transport protocol information can only be specified on secure links, + * specified using {@link #setPskPassphrase(String)}. + * </ul> + * The transport protocol number is assigned by the Internet Assigned Numbers Authority + * (IANA) https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml. + * + * @param transportProtocol The transport protocol to be used for communication. + * @return the current {@link NetworkSpecifierBuilder} builder, enabling chaining of builder + * methods. + */ + public @NonNull NetworkSpecifierBuilder setTransportProtocol(int transportProtocol) { + if (transportProtocol < 0 || transportProtocol > 255) { + throw new IllegalArgumentException( + "The transport protocol must be in range [0, 255]"); + } + mTransportProtocol = transportProtocol; + return this; + } + + /** * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} * for a WiFi Aware connection (link) to the specified peer. The * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to @@ -929,6 +985,18 @@ public class WifiAwareManager { ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER; + if (mPort != 0 || mTransportProtocol != -1) { + if (role != WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER) { + throw new IllegalStateException( + "Port and transport protocol information can only " + + "be specified on the Publisher device (which is the server"); + } + if (TextUtils.isEmpty(mPskPassphrase) && mPmk == null) { + throw new IllegalStateException("Port and transport protocol information can " + + "only be specified on a secure link"); + } + } + if (role == WIFI_AWARE_DATA_PATH_ROLE_INITIATOR && mPeerHandle == null) { throw new IllegalStateException("Null peerHandle!?"); } @@ -936,7 +1004,7 @@ public class WifiAwareManager { return new WifiAwareNetworkSpecifier( WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB, role, mDiscoverySession.mClientId, mDiscoverySession.mSessionId, mPeerHandle.peerId, - null, mPmk, mPskPassphrase, Process.myUid()); + null, mPmk, mPskPassphrase, mPort, mTransportProtocol, Process.myUid()); } } } diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java index 0f29e081e2a0..b258906df522 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java @@ -38,17 +38,30 @@ import java.util.Objects; * android.net.NetworkCapabilities)} callback. * <p> * The Wi-Fi Aware-specific network information include the peer's scoped link-local IPv6 address - * for the Wi-Fi Aware link. The scoped link-local IPv6 can then be used to create a + * for the Wi-Fi Aware link, as well as (optionally) the port and transport protocol specified by + * the peer. + * The scoped link-local IPv6, port, and transport protocol can then be used to create a * {@link java.net.Socket} connection to the peer. + * <p> + * Note: these are the peer's IPv6 and port information - not the local device's! */ public final class WifiAwareNetworkInfo implements TransportInfo, Parcelable { private Inet6Address mIpv6Addr; + private int mPort = 0; // a value of 0 is considered invalid + private int mTransportProtocol = -1; // a value of -1 is considered invalid /** @hide */ public WifiAwareNetworkInfo(Inet6Address ipv6Addr) { mIpv6Addr = ipv6Addr; } + /** @hide */ + public WifiAwareNetworkInfo(Inet6Address ipv6Addr, int port, int transportProtocol) { + mIpv6Addr = ipv6Addr; + mPort = port; + mTransportProtocol = transportProtocol; + } + /** * Get the scoped link-local IPv6 address of the Wi-Fi Aware peer (not of the local device!). * @@ -59,6 +72,34 @@ public final class WifiAwareNetworkInfo implements TransportInfo, Parcelable { return mIpv6Addr; } + /** + * Get the port number to be used to create a network connection to the Wi-Fi Aware peer. + * The port information is provided by the app running on the peer which requested the + * connection, using the {@link WifiAwareManager.NetworkSpecifierBuilder#setPort(int)}. + * + * @return A port number on the peer. A value of 0 indicates that no port was specified by the + * peer. + */ + public int getPort() { + return mPort; + } + + /** + * Get the transport protocol to be used to communicate over a network connection to the Wi-Fi + * Aware peer. The transport protocol is provided by the app running on the peer which requested + * the connection, using the + * {@link WifiAwareManager.NetworkSpecifierBuilder#setTransportProtocol(int)}. + * <p> + * The transport protocol number is assigned by the Internet Assigned Numbers Authority + * (IANA) https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml. + * + * @return A transport protocol id. A value of -1 indicates that no transport protocol was + * specified by the peer. + */ + public int getTransportProtocol() { + return mTransportProtocol; + } + // parcelable methods @Override @@ -71,6 +112,8 @@ public final class WifiAwareNetworkInfo implements TransportInfo, Parcelable { dest.writeByteArray(mIpv6Addr.getAddress()); NetworkInterface ni = mIpv6Addr.getScopedInterface(); dest.writeString(ni == null ? null : ni.getName()); + dest.writeInt(mPort); + dest.writeInt(mTransportProtocol); } public static final Creator<WifiAwareNetworkInfo> CREATOR = @@ -94,8 +137,10 @@ public final class WifiAwareNetworkInfo implements TransportInfo, Parcelable { e.printStackTrace(); return null; } + int port = in.readInt(); + int transportProtocol = in.readInt(); - return new WifiAwareNetworkInfo(ipv6Addr); + return new WifiAwareNetworkInfo(ipv6Addr, port, transportProtocol); } @Override @@ -109,7 +154,9 @@ public final class WifiAwareNetworkInfo implements TransportInfo, Parcelable { @Override public String toString() { - return new StringBuilder("AwareNetworkInfo: IPv6=").append(mIpv6Addr).toString(); + return new StringBuilder("AwareNetworkInfo: IPv6=").append(mIpv6Addr).append( + ", port=").append(mPort).append(", transportProtocol=").append( + mTransportProtocol).toString(); } /** @hide */ @@ -124,12 +171,13 @@ public final class WifiAwareNetworkInfo implements TransportInfo, Parcelable { } WifiAwareNetworkInfo lhs = (WifiAwareNetworkInfo) obj; - return Objects.equals(mIpv6Addr, lhs.mIpv6Addr); + return Objects.equals(mIpv6Addr, lhs.mIpv6Addr) && mPort == lhs.mPort + && mTransportProtocol == lhs.mTransportProtocol; } /** @hide */ @Override public int hashCode() { - return Objects.hash(mIpv6Addr); + return Objects.hash(mIpv6Addr, mPort, mTransportProtocol); } } diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java index 6e37fcf4d338..a93a6d58a3ec 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java @@ -19,7 +19,6 @@ package android.net.wifi.aware; import android.net.NetworkSpecifier; import android.os.Parcel; import android.os.Parcelable; -import android.util.Log; import java.util.Arrays; import java.util.Objects; @@ -117,6 +116,32 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements public final String passphrase; /** + * The port information to be used for this link. This information will be communicated to the + * peer as part of the layer 2 link setup. + * + * Information only allowed on secure links since a single layer-2 link is set up for all + * requestors. Therefore if multiple apps on a single device request links to the same peer + * device they all get the same link. However, the link is only set up on the first request - + * hence only the first can transmit the port information. But we don't want to expose that + * information to other apps. Limiting to secure links would (usually) imply single app usage. + * + * @hide + */ + public final int port; + + /** + * The transport protocol information to be used for this link. This information will be + * communicated to the peer as part of the layer 2 link setup. + * + * Information only allowed on secure links since a single layer-2 link is set up for all + * requestors. Therefore if multiple apps on a single device request links to the same peer + * device they all get the same link. However, the link is only set up on the first request - + * hence only the first can transmit the port information. But we don't want to expose that + * information to other apps. Limiting to secure links would (usually) imply single app usage. + */ + public final int transportProtocol; + + /** * The UID of the process initializing this network specifier. Validated by receiver using * checkUidIfNecessary() and is used by satisfiedBy() to determine whether matches the * offered network. @@ -127,7 +152,8 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements /** @hide */ public WifiAwareNetworkSpecifier(int type, int role, int clientId, int sessionId, int peerId, - byte[] peerMac, byte[] pmk, String passphrase, int requestorUid) { + byte[] peerMac, byte[] pmk, String passphrase, int port, int transportProtocol, + int requestorUid) { this.type = type; this.role = role; this.clientId = clientId; @@ -136,6 +162,8 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements this.peerMac = peerMac; this.pmk = pmk; this.passphrase = passphrase; + this.port = port; + this.transportProtocol = transportProtocol; this.requestorUid = requestorUid; } @@ -152,6 +180,8 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements in.createByteArray(), // peerMac in.createByteArray(), // pmk in.readString(), // passphrase + in.readInt(), // port + in.readInt(), // transportProtocol in.readInt()); // requestorUid } @@ -186,6 +216,8 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements dest.writeByteArray(peerMac); dest.writeByteArray(pmk); dest.writeString(passphrase); + dest.writeInt(port); + dest.writeInt(transportProtocol); dest.writeInt(requestorUid); } @@ -202,19 +234,8 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements /** @hide */ @Override public int hashCode() { - int result = 17; - - result = 31 * result + type; - result = 31 * result + role; - result = 31 * result + clientId; - result = 31 * result + sessionId; - result = 31 * result + peerId; - result = 31 * result + Arrays.hashCode(peerMac); - result = 31 * result + Arrays.hashCode(pmk); - result = 31 * result + Objects.hashCode(passphrase); - result = 31 * result + requestorUid; - - return result; + return Objects.hash(type, role, clientId, sessionId, peerId, Arrays.hashCode(peerMac), + Arrays.hashCode(pmk), passphrase, port, transportProtocol, requestorUid); } /** @hide */ @@ -238,6 +259,8 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements && Arrays.equals(peerMac, lhs.peerMac) && Arrays.equals(pmk, lhs.pmk) && Objects.equals(passphrase, lhs.passphrase) + && port == lhs.port + && transportProtocol == lhs.transportProtocol && requestorUid == lhs.requestorUid; } @@ -256,7 +279,8 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements .append(", pmk=").append((pmk == null) ? "<null>" : "<non-null>") // masking PII .append(", passphrase=").append((passphrase == null) ? "<null>" : "<non-null>") - .append(", requestorUid=").append(requestorUid) + .append(", port=").append(port).append(", transportProtocol=") + .append(transportProtocol).append(", requestorUid=").append(requestorUid) .append("]"); return sb.toString(); } diff --git a/wifi/java/android/net/wifi/hotspot2/OsuProvider.java b/wifi/java/android/net/wifi/hotspot2/OsuProvider.java index 6d82ca152202..f91790f5b3b1 100644 --- a/wifi/java/android/net/wifi/hotspot2/OsuProvider.java +++ b/wifi/java/android/net/wifi/hotspot2/OsuProvider.java @@ -16,6 +16,7 @@ package android.net.wifi.hotspot2; +import android.annotation.SystemApi; import android.graphics.drawable.Icon; import android.net.Uri; import android.net.wifi.WifiSsid; @@ -36,16 +37,19 @@ import java.util.Objects; * * @hide */ +@SystemApi public final class OsuProvider implements Parcelable { /** * OSU (Online Sign-Up) method: OMA DM (Open Mobile Alliance Device Management). * For more info, refer to Section 8.3 of the Hotspot 2.0 Release 2 Technical Specification. + * @hide */ public static final int METHOD_OMA_DM = 0; /** * OSU (Online Sign-Up) method: SOAP XML SPP (Subscription Provisioning Protocol). * For more info, refer to Section 8.4 of the Hotspot 2.0 Release 2 Technical Specification. + * @hide */ public static final int METHOD_SOAP_XML_SPP = 1; @@ -84,6 +88,7 @@ public final class OsuProvider implements Parcelable { */ private final Icon mIcon; + /** @hide */ public OsuProvider(WifiSsid osuSsid, Map<String, String> friendlyNames, String serviceDescription, Uri serverUri, String nai, List<Integer> methodList, Icon icon) { @@ -104,6 +109,7 @@ public final class OsuProvider implements Parcelable { * Copy constructor. * * @param source The source to copy from + * @hide */ public OsuProvider(OsuProvider source) { if (source == null) { @@ -130,10 +136,12 @@ public final class OsuProvider implements Parcelable { mIcon = source.mIcon; } + /** @hide */ public WifiSsid getOsuSsid() { return mOsuSsid; } + /** @hide */ public void setOsuSsid(WifiSsid osuSsid) { mOsuSsid = osuSsid; } @@ -162,10 +170,12 @@ public final class OsuProvider implements Parcelable { return mFriendlyNames.get(mFriendlyNames.keySet().stream().findFirst().get()); } + /** @hide */ public Map<String, String> getFriendlyNameList() { return mFriendlyNames; } + /** @hide */ public String getServiceDescription() { return mServiceDescription; } @@ -174,14 +184,17 @@ public final class OsuProvider implements Parcelable { return mServerUri; } + /** @hide */ public String getNetworkAccessIdentifier() { return mNetworkAccessIdentifier; } + /** @hide */ public List<Integer> getMethodList() { return mMethodList; } + /** @hide */ public Icon getIcon() { return mIcon; } diff --git a/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java b/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java index a62d63cd8910..1ee874a9698b 100644 --- a/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java +++ b/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java @@ -16,6 +16,7 @@ package android.net.wifi.hotspot2; +import android.annotation.SystemApi; import android.net.wifi.WifiManager; import android.os.Handler; @@ -25,6 +26,7 @@ import android.os.Handler; * * @hide */ +@SystemApi public abstract class ProvisioningCallback { /** diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java index 7689fc34ff5b..59a7290eb8a9 100644 --- a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java +++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java @@ -572,7 +572,7 @@ public final class Credential implements Parcelable { @Override public int hashCode() { - return Objects.hash(mCertType, mCertSha256Fingerprint); + return Objects.hash(mCertType, Arrays.hashCode(mCertSha256Fingerprint)); } @Override @@ -842,24 +842,50 @@ public final class Credential implements Parcelable { } /** - * CA (Certificate Authority) X509 certificate. + * CA (Certificate Authority) X509 certificates. */ - private X509Certificate mCaCertificate = null; + private X509Certificate[] mCaCertificates = null; + /** * Set the CA (Certification Authority) certificate associated with this credential. * * @param caCertificate The CA certificate to set to */ public void setCaCertificate(X509Certificate caCertificate) { - mCaCertificate = caCertificate; + mCaCertificates = null; + if (caCertificate != null) { + mCaCertificates = new X509Certificate[] {caCertificate}; + } } + + /** + * Set the CA (Certification Authority) certificates associated with this credential. + * + * @param caCertificates The list of CA certificates to set to + * @hide + */ + public void setCaCertificates(X509Certificate[] caCertificates) { + mCaCertificates = caCertificates; + } + /** * Get the CA (Certification Authority) certificate associated with this credential. * - * @return CA certificate associated with this credential + * @return CA certificate associated with this credential, {@code null} if certificate is not + * set or certificate is more than one. */ public X509Certificate getCaCertificate() { - return mCaCertificate; + return mCaCertificates == null || mCaCertificates.length > 1 ? null : mCaCertificates[0]; + } + + /** + * Get the CA (Certification Authority) certificates associated with this credential. + * + * @return The list of CA certificates associated with this credential + * @hide + */ + public X509Certificate[] getCaCertificates() { + return mCaCertificates; } /** @@ -933,7 +959,11 @@ public final class Credential implements Parcelable { mClientCertificateChain = Arrays.copyOf(source.mClientCertificateChain, source.mClientCertificateChain.length); } - mCaCertificate = source.mCaCertificate; + if (source.mCaCertificates != null) { + mCaCertificates = Arrays.copyOf(source.mCaCertificates, + source.mCaCertificates.length); + } + mClientPrivateKey = source.mClientPrivateKey; } } @@ -952,7 +982,7 @@ public final class Credential implements Parcelable { dest.writeParcelable(mUserCredential, flags); dest.writeParcelable(mCertCredential, flags); dest.writeParcelable(mSimCredential, flags); - ParcelUtil.writeCertificate(dest, mCaCertificate); + ParcelUtil.writeCertificates(dest, mCaCertificates); ParcelUtil.writeCertificates(dest, mClientCertificateChain); ParcelUtil.writePrivateKey(dest, mClientPrivateKey); } @@ -977,16 +1007,17 @@ public final class Credential implements Parcelable { : mCertCredential.equals(that.mCertCredential)) && (mSimCredential == null ? that.mSimCredential == null : mSimCredential.equals(that.mSimCredential)) - && isX509CertificateEquals(mCaCertificate, that.mCaCertificate) + && isX509CertificatesEquals(mCaCertificates, that.mCaCertificates) && isX509CertificatesEquals(mClientCertificateChain, that.mClientCertificateChain) && isPrivateKeyEquals(mClientPrivateKey, that.mClientPrivateKey); } @Override public int hashCode() { - return Objects.hash(mRealm, mCreationTimeInMillis, mExpirationTimeInMillis, + return Objects.hash(mCreationTimeInMillis, mExpirationTimeInMillis, mRealm, mCheckAaaServerCertStatus, mUserCredential, mCertCredential, mSimCredential, - mCaCertificate, mClientCertificateChain, mClientPrivateKey); + mClientPrivateKey, Arrays.hashCode(mCaCertificates), + Arrays.hashCode(mClientCertificateChain)); } @Override @@ -1067,7 +1098,7 @@ public final class Credential implements Parcelable { credential.setUserCredential(in.readParcelable(null)); credential.setCertCredential(in.readParcelable(null)); credential.setSimCredential(in.readParcelable(null)); - credential.setCaCertificate(ParcelUtil.readCertificate(in)); + credential.setCaCertificates(ParcelUtil.readCertificates(in)); credential.setClientCertificateChain(ParcelUtil.readCertificates(in)); credential.setClientPrivateKey(ParcelUtil.readPrivateKey(in)); return credential; @@ -1100,7 +1131,7 @@ public final class Credential implements Parcelable { // CA certificate is required for R1 Passpoint profile. // For R2, it is downloaded using cert URL provided in PPS MO after validation completes. - if (isR1 && mCaCertificate == null) { + if (isR1 && mCaCertificates == null) { Log.d(TAG, "Missing CA Certificate for user credential"); return false; } @@ -1131,7 +1162,7 @@ public final class Credential implements Parcelable { // Verify required key and certificates for certificate credential. // CA certificate is required for R1 Passpoint profile. // For R2, it is downloaded using cert URL provided in PPS MO after validation completes. - if (isR1 && mCaCertificate == null) { + if (isR1 && mCaCertificates == null) { Log.d(TAG, "Missing CA Certificate for certificate credential"); return false; } diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java index 6631fa806fc6..f931ad2bdf6d 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java @@ -223,7 +223,8 @@ public class WifiP2pConfig implements Parcelable { private MacAddress mDeviceAddress = MAC_ANY_ADDRESS; private String mNetworkName = ""; private String mPassphrase = ""; - private int mGroupOwnerBand = GROUP_OWNER_BAND_AUTO; + private int mGroupOperatingBand = GROUP_OWNER_BAND_AUTO; + private int mGroupOperatingFrequency = GROUP_OWNER_BAND_AUTO; private int mNetId = WifiP2pGroup.TEMPORARY_NET_ID; /** @@ -285,22 +286,84 @@ public class WifiP2pConfig implements Parcelable { } /** - * Specify the band to use for creating the group. This method only applies when - * creating a group as Group Owner using {@link WifiP2pManager#createGroup}. - * The band should be {@link #GROUP_OWNER_BAND_2GHZ} or {@link #GROUP_OWNER_BAND_5GHZ}, - * or allow the system to pick the band by specifying {@link #GROUP_OWNER_BAND_AUTO}. + * Specify the band to use for creating the group or joining the group. The band should + * be {@link #GROUP_OWNER_BAND_2GHZ}, {@link #GROUP_OWNER_BAND_5GHZ} or + * {@link #GROUP_OWNER_BAND_AUTO}. + * <p> + * When creating a group as Group Owner using {@link + * WifiP2pManager#createGroup(WifiP2pManager.Channel, + * WifiP2pConfig, WifiP2pManager.ActionListener)}, + * specifying {@link #GROUP_OWNER_BAND_AUTO} allows the system to pick the operating + * frequency from all supported bands. + * Specifying {@link #GROUP_OWNER_BAND_2GHZ} or {@link #GROUP_OWNER_BAND_5GHZ} + * only allows the system to pick the operating frequency in the specified band. * If the Group Owner cannot create a group in the specified band, the operation will fail. * <p> + * When joining a group as Group Client using {@link + * WifiP2pManager#connect(WifiP2pManager.Channel, WifiP2pConfig, + * WifiP2pManager.ActionListener)}, + * specifying {@link #GROUP_OWNER_BAND_AUTO} allows the system to scan all supported + * frequencies to find the desired group. Specifying {@link #GROUP_OWNER_BAND_2GHZ} or + * {@link #GROUP_OWNER_BAND_5GHZ} only allows the system to scan the specified band. + * <p> + * {@link #setGroupOperatingBand(int)} and {@link #setGroupOperatingFrequency(int)} are + * mutually exclusive. Setting operating band and frequency both is invalid. + * <p> * Optional. {@link #GROUP_OWNER_BAND_AUTO} by default. * - * @param band the required band of group owner. + * @param band the operating band of the group. * This should be one of {@link #GROUP_OWNER_BAND_AUTO}, * {@link #GROUP_OWNER_BAND_2GHZ}, {@link #GROUP_OWNER_BAND_5GHZ}. * @return The builder to facilitate chaining * {@code builder.setXXX(..).setXXX(..)}. */ - public Builder setGroupOwnerBand(int band) { - mGroupOwnerBand = band; + public Builder setGroupOperatingBand(@GroupOwnerBandType int band) { + switch (band) { + case GROUP_OWNER_BAND_AUTO: + case GROUP_OWNER_BAND_2GHZ: + case GROUP_OWNER_BAND_5GHZ: + mGroupOperatingBand = band; + break; + default: + throw new IllegalArgumentException( + "Invalid constant for the group operating band!"); + } + return this; + } + + /** + * Specify the frequency to use for creating the group or joining the group. + * <p> + * When creating a group as Group Owner using {@link WifiP2pManager#createGroup( + * WifiP2pManager.Channel, WifiP2pConfig, WifiP2pManager.ActionListener)}, + * specifying a frequency only allows the system to pick the specified frequency. + * If the Group Owner cannot create a group at the specified frequency, + * the operation will fail. + * When not specifying a frequency, it allows the system to pick operating frequency + * from all supported bands. + * <p> + * When joining a group as Group Client using {@link WifiP2pManager#connect( + * WifiP2pManager.Channel, WifiP2pConfig, WifiP2pManager.ActionListener)}, + * specifying a frequency only allows the system to scan the specified frequency. + * If the frequency is not supported or invalid, the operation will fail. + * When not specifying a frequency, it allows the system to scan all supported + * frequencies to find the desired group. + * <p> + * {@link #setGroupOperatingBand(int)} and {@link #setGroupOperatingFrequency(int)} are + * mutually exclusive. Setting operating band and frequency both is invalid. + * <p> + * Optional. 0 by default. + * + * @param frequency the operating frequency of the group. + * @return The builder to facilitate chaining + * {@code builder.setXXX(..).setXXX(..)}. + */ + public Builder setGroupOperatingFrequency(int frequency) { + if (frequency < 0) { + throw new IllegalArgumentException( + "Invalid group operating frequency!"); + } + mGroupOperatingFrequency = frequency; return this; } @@ -337,11 +400,21 @@ public class WifiP2pConfig implements Parcelable { "passphrase must be non-empty."); } + if (mGroupOperatingFrequency > 0 && mGroupOperatingBand > 0) { + throw new IllegalStateException( + "Preferred frequency and band are mutually exclusive."); + } + WifiP2pConfig config = new WifiP2pConfig(); config.deviceAddress = mDeviceAddress.toString(); config.networkName = mNetworkName; config.passphrase = mPassphrase; - config.groupOwnerBand = mGroupOwnerBand; + config.groupOwnerBand = GROUP_OWNER_BAND_AUTO; + if (mGroupOperatingFrequency > 0) { + config.groupOwnerBand = mGroupOperatingFrequency; + } else if (mGroupOperatingBand > 0) { + config.groupOwnerBand = mGroupOperatingBand; + } config.netId = mNetId; return config; } diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java index 01feb1ef5b42..72e57a16712b 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java @@ -17,15 +17,15 @@ package android.net.wifi.p2p; import android.annotation.UnsupportedAppUsage; -import android.os.Parcelable; import android.os.Parcel; +import android.os.Parcelable; import java.util.ArrayList; -import java.util.List; import java.util.Collection; import java.util.Collections; -import java.util.regex.Pattern; +import java.util.List; import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * A class representing a Wi-Fi P2p group. A p2p group consists of a single group @@ -67,6 +67,9 @@ public class WifiP2pGroup implements Parcelable { /** The network id in the wpa_supplicant */ private int mNetId; + /** The frequency used by this group */ + private int mFrequency; + /** P2P group started string pattern */ private static final Pattern groupStartedPattern = Pattern.compile( "ssid=\"(.+)\" " + @@ -116,8 +119,9 @@ public class WifiP2pGroup implements Parcelable { } mNetworkName = match.group(1); - //freq and psk are unused right now - //int freq = Integer.parseInt(match.group(2)); + // It throws NumberFormatException if the string cannot be parsed as an integer. + mFrequency = Integer.parseInt(match.group(2)); + // psk is unused right now //String psk = match.group(3); mPassphrase = match.group(4); mOwner = new WifiP2pDevice(match.group(5)); @@ -269,6 +273,16 @@ public class WifiP2pGroup implements Parcelable { this.mNetId = netId; } + /** Get the operating frequency of the p2p group */ + public int getFrequency() { + return mFrequency; + } + + /** @hide */ + public void setFrequency(int freq) { + this.mFrequency = freq; + } + public String toString() { StringBuffer sbuf = new StringBuffer(); sbuf.append("network: ").append(mNetworkName); @@ -279,6 +293,7 @@ public class WifiP2pGroup implements Parcelable { } sbuf.append("\n interface: ").append(mInterface); sbuf.append("\n networkId: ").append(mNetId); + sbuf.append("\n frequency: ").append(mFrequency); return sbuf.toString(); } @@ -297,6 +312,7 @@ public class WifiP2pGroup implements Parcelable { mPassphrase = source.getPassphrase(); mInterface = source.getInterface(); mNetId = source.getNetworkId(); + mFrequency = source.getFrequency(); } } @@ -312,6 +328,7 @@ public class WifiP2pGroup implements Parcelable { dest.writeString(mPassphrase); dest.writeString(mInterface); dest.writeInt(mNetId); + dest.writeInt(mFrequency); } /** Implement the Parcelable interface */ @@ -329,6 +346,7 @@ public class WifiP2pGroup implements Parcelable { group.setPassphrase(in.readString()); group.setInterface(in.readString()); group.setNetworkId(in.readInt()); + group.setFrequency(in.readInt()); return group; } diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java index 22f63b542256..1f0b52a835e6 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java @@ -1290,7 +1290,16 @@ public class WifiP2pManager { c.mAsyncChannel.sendMessage(REMOVE_GROUP, 0, c.putListener(listener)); } - /** @hide */ + /** + * Force p2p to enter or exit listen state + * + * @param c is the channel created at {@link #initialize(Context, Looper, ChannelListener)} + * @param enable enables or disables listening + * @param listener for callbacks on success or failure. Can be null. + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void listen(Channel c, boolean enable, ActionListener listener) { checkChannel(c); c.mAsyncChannel.sendMessage(enable ? START_LISTEN : STOP_LISTEN, |