From e955accd13ed70b074bb10c0bc1da234ffd40afa Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 13 Nov 2019 10:47:44 -0800 Subject: [PATCH] Expose ScanResult/WifiInfo @hide APIs as @SystemApi Expose @hide APIs in ScanResult/WifiInfo as @SystemApi. These APIs are mostly used by Settings. Bug: 144311098 Test: atest FrameworksWifiApiTests Change-Id: Ifdfa78ed59f6a42a3646defa5a9f164d146ceada --- api/current.txt | 1 + api/system-current.txt | 10 + wifi/java/android/net/wifi/ScanResult.java | 32 ++-- wifi/java/android/net/wifi/WifiInfo.java | 171 +++++++++++++----- wifi/java/android/net/wifi/WifiManager.java | 5 +- wifi/java/android/net/wifi/WifiSsid.java | 62 ++++--- .../net/wifi/hotspot2/OsuProvider.java | 9 + .../src/android/net/wifi/WifiInfoTest.java | 4 +- .../net/wifi/hotspot2/OsuProviderTest.java | 4 +- 9 files changed, 209 insertions(+), 89 deletions(-) diff --git a/api/current.txt b/api/current.txt index 336114737057b..041774f2ed89e 100644 --- a/api/current.txt +++ b/api/current.txt @@ -30133,6 +30133,7 @@ package android.net.wifi { field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN = 0; // 0x0 field @Deprecated public static final String SUPPLICANT_CONNECTION_CHANGE_ACTION = "android.net.wifi.supplicant.CONNECTION_CHANGE"; field @Deprecated public static final String SUPPLICANT_STATE_CHANGED_ACTION = "android.net.wifi.supplicant.STATE_CHANGE"; + field public static final String UNKNOWN_SSID = ""; field @Deprecated public static final int WIFI_MODE_FULL = 1; // 0x1 field public static final int WIFI_MODE_FULL_HIGH_PERF = 3; // 0x3 field public static final int WIFI_MODE_FULL_LOW_LATENCY = 4; // 0x4 diff --git a/api/system-current.txt b/api/system-current.txt index 412e0959570c1..36915e2ff7062 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -4829,8 +4829,18 @@ package android.net.wifi { } public class WifiInfo implements android.os.Parcelable { + method @Nullable public String getAppPackageName(); + method public double getRxSuccessRate(); + method public int getScore(); + method public double getTxBadRate(); + method public double getTxRetriesRate(); + method public double getTxSuccessRate(); + method public boolean isEphemeral(); method public boolean isOsuAp(); method public boolean isPasspointAp(); + method @Nullable public static String removeDoubleQuotes(@Nullable String); + field public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00"; + field public static final int INVALID_RSSI = -127; // 0xffffff81 } public class WifiManager { diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java index ed1a2f9f16ca9..9956901434d0f 100644 --- a/wifi/java/android/net/wifi/ScanResult.java +++ b/wifi/java/android/net/wifi/ScanResult.java @@ -585,6 +585,7 @@ public class ScanResult implements Parcelable { * * @hide */ + // TODO(b/144431927): remove once migrated to Suggestions public boolean isCarrierAp; /** @@ -592,6 +593,7 @@ public class ScanResult implements Parcelable { * * @hide */ + // TODO(b/144431927): remove once migrated to Suggestions public int carrierApEapType; /** @@ -599,13 +601,14 @@ public class ScanResult implements Parcelable { * * @hide */ + // TODO(b/144431927): remove once migrated to Suggestions public String carrierName; /** {@hide} */ public ScanResult(WifiSsid wifiSsid, String BSSID, long hessid, int anqpDomainId, byte[] osuProviders, String caps, int level, int frequency, long tsf) { this.wifiSsid = wifiSsid; - this.SSID = (wifiSsid != null) ? wifiSsid.toString() : WifiSsid.NONE; + this.SSID = (wifiSsid != null) ? wifiSsid.toString() : WifiManager.UNKNOWN_SSID; this.BSSID = BSSID; this.hessid = hessid; this.anqpDomainId = anqpDomainId; @@ -636,7 +639,7 @@ public class ScanResult implements Parcelable { public ScanResult(WifiSsid wifiSsid, String BSSID, String caps, int level, int frequency, long tsf, int distCm, int distSdCm) { this.wifiSsid = wifiSsid; - this.SSID = (wifiSsid != null) ? wifiSsid.toString() : WifiSsid.NONE; + this.SSID = (wifiSsid != null) ? wifiSsid.toString() : WifiManager.UNKNOWN_SSID; this.BSSID = BSSID; this.capabilities = caps; this.level = level; @@ -740,19 +743,18 @@ public class ScanResult implements Parcelable { StringBuffer sb = new StringBuffer(); String none = ""; - sb.append("SSID: "). - append(wifiSsid == null ? WifiSsid.NONE : wifiSsid). - append(", BSSID: "). - append(BSSID == null ? none : BSSID). - append(", capabilities: "). - append(capabilities == null ? none : capabilities). - append(", level: "). - append(level). - append(", frequency: "). - append(frequency). - append(", timestamp: "). - append(timestamp); - + sb.append("SSID: ") + .append(wifiSsid == null ? WifiManager.UNKNOWN_SSID : wifiSsid) + .append(", BSSID: ") + .append(BSSID == null ? none : BSSID) + .append(", capabilities: ") + .append(capabilities == null ? none : capabilities) + .append(", level: ") + .append(level) + .append(", frequency: ") + .append(frequency) + .append(", timestamp: ") + .append(timestamp); sb.append(", distance: ").append((distanceCm != UNSPECIFIED ? distanceCm : "?")). append("(cm)"); sb.append(", distanceSd: ").append((distanceSdCm != UNSPECIFIED ? distanceSdCm : "?")). diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index 86e51227575b7..f3f873b4ead8b 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -53,7 +53,7 @@ public class WifiInfo implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @SystemApi public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00"; static { @@ -79,8 +79,12 @@ public class WifiInfo implements Parcelable { private WifiSsid mWifiSsid; private int mNetworkId; - /** @hide **/ - @UnsupportedAppUsage + /** + * Used to indicate that the RSSI is invalid, for example if no RSSI measurements are available + * yet. + * @hide + */ + @SystemApi public static final int INVALID_RSSI = -127; /** @hide **/ @@ -161,7 +165,7 @@ public class WifiInfo implements Parcelable { * If connected to a network suggestion or specifier, store the package name of the app, * else null. */ - private String mNetworkSuggestionOrSpecifierPackageName; + private String mAppPackageName; /** * Running total count of lost (not ACKed) transmitted unicast data packets. @@ -184,33 +188,90 @@ public class WifiInfo implements Parcelable { */ public long rxSuccess; + private double mTxBadRate; + /** * Average rate of lost transmitted packets, in units of packets per second. * @hide */ - public double txBadRate; + @SystemApi + public double getTxBadRate() { + return mTxBadRate; + } + + /** @hide */ + public void setTxBadRate(double txBadRate) { + mTxBadRate = txBadRate; + } + + private double mTxRetriesRate; + /** * Average rate of transmitted retry packets, in units of packets per second. * @hide */ - public double txRetriesRate; + @SystemApi + public double getTxRetriesRate() { + return mTxRetriesRate; + } + + /** @hide */ + public void setTxRetriesRate(double txRetriesRate) { + mTxRetriesRate = txRetriesRate; + } + + private double mTxSuccessRate; + /** * Average rate of successfully transmitted unicast packets, in units of packets per second. * @hide */ - public double txSuccessRate; + @SystemApi + public double getTxSuccessRate() { + return mTxSuccessRate; + } + + /** @hide */ + public void setTxSuccessRate(double txSuccessRate) { + mTxSuccessRate = txSuccessRate; + } + + private double mRxSuccessRate; + /** * Average rate of received unicast data packets, in units of packets per second. * @hide */ - public double rxSuccessRate; + @SystemApi + public double getRxSuccessRate() { + return mRxSuccessRate; + } - /** - * @hide - */ + /** @hide */ + public void setRxSuccessRate(double rxSuccessRate) { + mRxSuccessRate = rxSuccessRate; + } + + /** @hide */ @UnsupportedAppUsage public int score; + /** + * The current Wifi score. + * NOTE: this value should only be used for debugging purposes. Do not rely on this value for + * any computations. The meaning of this value can and will change at any time without warning. + * @hide + */ + @SystemApi + public int getScore() { + return score; + } + + /** @hide */ + public void setScore(int score) { + this.score = score; + } + /** * Flag indicating that AP has hinted that upstream connection is metered, * and sensitive to heavy data transfers. @@ -243,17 +304,17 @@ public class WifiInfo implements Parcelable { setMeteredHint(false); setEphemeral(false); setOsuAp(false); - setNetworkSuggestionOrSpecifierPackageName(null); + setAppPackageName(null); setFQDN(null); setProviderFriendlyName(null); txBad = 0; txSuccess = 0; rxSuccess = 0; txRetries = 0; - txBadRate = 0; - txSuccessRate = 0; - rxSuccessRate = 0; - txRetriesRate = 0; + mTxBadRate = 0; + mTxSuccessRate = 0; + mRxSuccessRate = 0; + mTxRetriesRate = 0; score = 0; } @@ -277,8 +338,8 @@ public class WifiInfo implements Parcelable { mMeteredHint = source.mMeteredHint; mEphemeral = source.mEphemeral; mTrusted = source.mTrusted; - mNetworkSuggestionOrSpecifierPackageName = - source.mNetworkSuggestionOrSpecifierPackageName; + mAppPackageName = + source.mAppPackageName; mOsuAp = source.mOsuAp; mFqdn = source.mFqdn; mProviderFriendlyName = source.mProviderFriendlyName; @@ -286,10 +347,10 @@ public class WifiInfo implements Parcelable { txRetries = source.txRetries; txSuccess = source.txSuccess; rxSuccess = source.rxSuccess; - txBadRate = source.txBadRate; - txRetriesRate = source.txRetriesRate; - txSuccessRate = source.txSuccessRate; - rxSuccessRate = source.rxSuccessRate; + mTxBadRate = source.mTxBadRate; + mTxRetriesRate = source.mTxRetriesRate; + mTxSuccessRate = source.mTxSuccessRate; + mRxSuccessRate = source.mRxSuccessRate; score = source.score; mWifiStandard = source.mWifiStandard; } @@ -323,10 +384,10 @@ public class WifiInfo implements Parcelable { return "\"" + unicode + "\""; } else { String hex = mWifiSsid.getHexString(); - return (hex != null) ? hex : WifiSsid.NONE; + return (hex != null) ? hex : WifiManager.UNKNOWN_SSID; } } - return WifiSsid.NONE; + return WifiManager.UNKNOWN_SSID; } /** @hide */ @@ -523,8 +584,15 @@ public class WifiInfo implements Parcelable { mEphemeral = ephemeral; } - /** {@hide} */ - @UnsupportedAppUsage + /** + * Returns true if the current Wifi network is ephemeral, false otherwise. + * An ephemeral network is a network that is temporary and not persisted in the system. + * Ephemeral networks cannot be forgotten, only disabled with + * {@link WifiManager#disableEphemeralNetwork(String)}. + * + * @hide + */ + @SystemApi public boolean isEphemeral() { return mEphemeral; } @@ -581,13 +649,19 @@ public class WifiInfo implements Parcelable { } /** {@hide} */ - public void setNetworkSuggestionOrSpecifierPackageName(@Nullable String packageName) { - mNetworkSuggestionOrSpecifierPackageName = packageName; + public void setAppPackageName(@Nullable String packageName) { + mAppPackageName = packageName; } - /** {@hide} */ - public @Nullable String getNetworkSuggestionOrSpecifierPackageName() { - return mNetworkSuggestionOrSpecifierPackageName; + /** + * If this network was created in response to an app request (e.g. through Network Suggestion + * or Network Specifier), return the package name of the app that made the request. + * Null otherwise. + * @hide + */ + @SystemApi + public @Nullable String getAppPackageName() { + return mAppPackageName; } @@ -648,7 +722,7 @@ public class WifiInfo implements Parcelable { return mWifiSsid.isHidden(); } - /** + /** * Map a supplicant state into a fine-grained network connectivity state. * @param suppState the supplicant state * @return the corresponding {@link DetailedState} @@ -680,9 +754,14 @@ public class WifiInfo implements Parcelable { } } - /** {@hide} */ - @UnsupportedAppUsage - public static String removeDoubleQuotes(String string) { + /** + * Remove double quotes (") surrounding a SSID string, if present. Otherwise, return the + * string unmodified. Return null if the input string was null. + * @hide + */ + @Nullable + @SystemApi + public static String removeDoubleQuotes(@Nullable String string) { if (string == null) return null; final int length = string.length(); if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) { @@ -696,7 +775,7 @@ public class WifiInfo implements Parcelable { StringBuffer sb = new StringBuffer(); String none = ""; - sb.append("SSID: ").append(mWifiSsid == null ? WifiSsid.NONE : mWifiSsid) + sb.append("SSID: ").append(mWifiSsid == null ? WifiManager.UNKNOWN_SSID : mWifiSsid) .append(", BSSID: ").append(mBSSID == null ? none : mBSSID) .append(", MAC: ").append(mMacAddress == null ? none : mMacAddress) .append(", Supplicant state: ") @@ -745,16 +824,16 @@ public class WifiInfo implements Parcelable { dest.writeInt(mTrusted ? 1 : 0); dest.writeInt(score); dest.writeLong(txSuccess); - dest.writeDouble(txSuccessRate); + dest.writeDouble(mTxSuccessRate); dest.writeLong(txRetries); - dest.writeDouble(txRetriesRate); + dest.writeDouble(mTxRetriesRate); dest.writeLong(txBad); - dest.writeDouble(txBadRate); + dest.writeDouble(mTxBadRate); dest.writeLong(rxSuccess); - dest.writeDouble(rxSuccessRate); + dest.writeDouble(mRxSuccessRate); mSupplicantState.writeToParcel(dest, flags); dest.writeInt(mOsuAp ? 1 : 0); - dest.writeString(mNetworkSuggestionOrSpecifierPackageName); + dest.writeString(mAppPackageName); dest.writeString(mFqdn); dest.writeString(mProviderFriendlyName); dest.writeInt(mWifiStandard); @@ -787,16 +866,16 @@ public class WifiInfo implements Parcelable { info.mTrusted = in.readInt() != 0; info.score = in.readInt(); info.txSuccess = in.readLong(); - info.txSuccessRate = in.readDouble(); + info.mTxSuccessRate = in.readDouble(); info.txRetries = in.readLong(); - info.txRetriesRate = in.readDouble(); + info.mTxRetriesRate = in.readDouble(); info.txBad = in.readLong(); - info.txBadRate = in.readDouble(); + info.mTxBadRate = in.readDouble(); info.rxSuccess = in.readLong(); - info.rxSuccessRate = in.readDouble(); + info.mRxSuccessRate = in.readDouble(); info.mSupplicantState = SupplicantState.CREATOR.createFromParcel(in); info.mOsuAp = in.readInt() != 0; - info.mNetworkSuggestionOrSpecifierPackageName = in.readString(); + info.mAppPackageName = in.readString(); info.mFqdn = in.readString(); info.mProviderFriendlyName = in.readString(); info.mWifiStandard = in.readInt(); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 8482b069616de..1a01f6a4ec9d8 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1181,6 +1181,9 @@ public class WifiManager { */ private static final int MAX_ACTIVE_LOCKS = 50; + /** Indicates an invalid SSID. */ + public static final String UNKNOWN_SSID = ""; + /* Number of currently active WifiLocks and MulticastLocks */ @UnsupportedAppUsage private int mActiveLockCount; @@ -2539,7 +2542,7 @@ public class WifiManager { *

* In the connected state, access to the SSID and BSSID requires * the same permissions as {@link #getScanResults}. If such access is not allowed, - * {@link WifiInfo#getSSID} will return {@code ""} and + * {@link WifiInfo#getSSID} will return {@link #UNKNOWN_SSID} and * {@link WifiInfo#getBSSID} will return {@code "02:00:00:00:00:00"}. * * @return the Wi-Fi information, contained in {@link WifiInfo}. diff --git a/wifi/java/android/net/wifi/WifiSsid.java b/wifi/java/android/net/wifi/WifiSsid.java index 70ca0882d7dab..90756d860a214 100644 --- a/wifi/java/android/net/wifi/WifiSsid.java +++ b/wifi/java/android/net/wifi/WifiSsid.java @@ -16,6 +16,8 @@ package android.net.wifi; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; @@ -40,23 +42,29 @@ import java.util.Locale; * * @hide */ -public class WifiSsid implements Parcelable { +public final class WifiSsid implements Parcelable { private static final String TAG = "WifiSsid"; @UnsupportedAppUsage public final ByteArrayOutputStream octets = new ByteArrayOutputStream(32); private static final int HEX_RADIX = 16; + @UnsupportedAppUsage - public static final String NONE = ""; + public static final String NONE = WifiManager.UNKNOWN_SSID; private WifiSsid() { } - public static WifiSsid createFromByteArray(byte ssid[]) { + /** + * Create a WifiSsid from a raw byte array. If the byte array is null, return an empty WifiSsid + * object. + */ + @NonNull + public static WifiSsid createFromByteArray(@Nullable byte[] ssid) { WifiSsid wifiSsid = new WifiSsid(); if (ssid != null) { - wifiSsid.octets.write(ssid, 0/* the start offset */, ssid.length);; + wifiSsid.octets.write(ssid, 0 /* the start offset */, ssid.length); } return wifiSsid; } @@ -174,6 +182,10 @@ public class WifiSsid implements Parcelable { } } + /** + * Converts this SSID to an unquoted UTF-8 String representation. + * @return the SSID string, or {@link WifiManager#UNKNOWN_SSID} if there was an error. + */ @Override public String toString() { byte[] ssidBytes = octets.toByteArray(); @@ -191,7 +203,7 @@ public class WifiSsid implements Parcelable { CoderResult result = decoder.decode(ByteBuffer.wrap(ssidBytes), out, true); out.flip(); if (result.isError()) { - return NONE; + return WifiManager.UNKNOWN_SSID; } return out.toString(); } @@ -241,32 +253,36 @@ public class WifiSsid implements Parcelable { return (octets.size() > 0) ? out : null; } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ + @Override public int describeContents() { return 0; } - /** Implement the Parcelable interface {@hide} */ - public void writeToParcel(Parcel dest, int flags) { + /** Implement the Parcelable interface */ + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(octets.size()); dest.writeByteArray(octets.toByteArray()); } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ @UnsupportedAppUsage - public static final @android.annotation.NonNull Creator CREATOR = - new Creator() { - public WifiSsid createFromParcel(Parcel in) { - WifiSsid ssid = new WifiSsid(); - int length = in.readInt(); - byte b[] = new byte[length]; - in.readByteArray(b); - ssid.octets.write(b, 0, length); - return ssid; - } + public static final @NonNull Creator CREATOR = + new Creator() { + @Override + public WifiSsid createFromParcel(Parcel in) { + WifiSsid ssid = new WifiSsid(); + int length = in.readInt(); + byte[] b = new byte[length]; + in.readByteArray(b); + ssid.octets.write(b, 0, length); + return ssid; + } - public WifiSsid[] newArray(int size) { - return new WifiSsid[size]; - } - }; + @Override + public WifiSsid[] newArray(int size) { + return new WifiSsid[size]; + } + }; } diff --git a/wifi/java/android/net/wifi/hotspot2/OsuProvider.java b/wifi/java/android/net/wifi/hotspot2/OsuProvider.java index a32bd547e1e29..3bef50211015e 100644 --- a/wifi/java/android/net/wifi/hotspot2/OsuProvider.java +++ b/wifi/java/android/net/wifi/hotspot2/OsuProvider.java @@ -27,6 +27,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -90,6 +91,14 @@ public final class OsuProvider implements Parcelable { */ private final Icon mIcon; + /** @hide */ + public OsuProvider(String osuSsid, Map friendlyNames, + String serviceDescription, Uri serverUri, String nai, List methodList, + Icon icon) { + this(WifiSsid.createFromByteArray(osuSsid.getBytes(StandardCharsets.UTF_8)), + friendlyNames, serviceDescription, serverUri, nai, methodList, icon); + } + /** @hide */ public OsuProvider(WifiSsid osuSsid, Map friendlyNames, String serviceDescription, Uri serverUri, String nai, List methodList, diff --git a/wifi/tests/src/android/net/wifi/WifiInfoTest.java b/wifi/tests/src/android/net/wifi/WifiInfoTest.java index 22a5faaac112d..f7612341d4b31 100644 --- a/wifi/tests/src/android/net/wifi/WifiInfoTest.java +++ b/wifi/tests/src/android/net/wifi/WifiInfoTest.java @@ -54,7 +54,7 @@ public class WifiInfoTest { writeWifiInfo.setOsuAp(true); writeWifiInfo.setFQDN(TEST_FQDN); writeWifiInfo.setProviderFriendlyName(TEST_PROVIDER_NAME); - writeWifiInfo.setNetworkSuggestionOrSpecifierPackageName(TEST_PACKAGE_NAME); + writeWifiInfo.setAppPackageName(TEST_PACKAGE_NAME); writeWifiInfo.setWifiStandard(TEST_WIFI_STANDARD); Parcel parcel = Parcel.obtain(); @@ -71,7 +71,7 @@ public class WifiInfoTest { assertTrue(readWifiInfo.isTrusted()); assertTrue(readWifiInfo.isOsuAp()); assertTrue(readWifiInfo.isPasspointAp()); - assertEquals(TEST_PACKAGE_NAME, readWifiInfo.getNetworkSuggestionOrSpecifierPackageName()); + assertEquals(TEST_PACKAGE_NAME, readWifiInfo.getAppPackageName()); assertEquals(TEST_FQDN, readWifiInfo.getPasspointFqdn()); assertEquals(TEST_PROVIDER_NAME, readWifiInfo.getPasspointProviderFriendlyName()); assertEquals(TEST_WIFI_STANDARD, readWifiInfo.getWifiStandard()); diff --git a/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java b/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java index c7e009ee98647..43ee24943e121 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java @@ -82,7 +82,7 @@ public class OsuProviderTest { */ @Test public void verifyParcelWithEmptyProviderInfo() throws Exception { - verifyParcel(new OsuProvider(null, null, null, null, null, null, null)); + verifyParcel(new OsuProvider((WifiSsid) null, null, null, null, null, null, null)); } /** @@ -102,7 +102,7 @@ public class OsuProviderTest { */ @Test public void verifyCopyConstructorWithNullSource() throws Exception { - OsuProvider expected = new OsuProvider(null, null, null, null, null, null, null); + OsuProvider expected = new OsuProvider((WifiSsid) null, null, null, null, null, null, null); assertEquals(expected, new OsuProvider(null)); }