WifiInfo: Embed location sensitive TransportInfo
Migrate existing WifiInfo masking to use this new mechanism
(instead of existing masking in WifiService).
Bug: 162602799
Test: atest android.net.wifi
Test: atest android.net.wifi.cts.WifiLocationTest
Change-Id: Ibcf0c67114f09cbc25bf56b8ea5b63113defecc4
Merged-In: Ibcf0c67114f09cbc25bf56b8ea5b63113defecc4
diff --git a/framework/api/current.txt b/framework/api/current.txt
index 28224cf..9e2bf94 100644
--- a/framework/api/current.txt
+++ b/framework/api/current.txt
@@ -284,6 +284,7 @@
method public android.net.wifi.SupplicantState getSupplicantState();
method @IntRange(from=0xffffffff) public int getTxLinkSpeedMbps();
method public int getWifiStandard();
+ method @NonNull public android.net.wifi.WifiInfo makeCopy(boolean);
method public void writeToParcel(android.os.Parcel, int);
field public static final String FREQUENCY_UNITS = "MHz";
field public static final String LINK_SPEED_UNITS = "Mbps";
@@ -661,6 +662,7 @@
method @Nullable public java.net.Inet6Address getPeerIpv6Addr();
method public int getPort();
method public int getTransportProtocol();
+ method @NonNull public android.net.wifi.aware.WifiAwareNetworkInfo makeCopy(boolean);
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.WifiAwareNetworkInfo> CREATOR;
}
diff --git a/framework/java/android/net/wifi/WifiInfo.java b/framework/java/android/net/wifi/WifiInfo.java
index 7437082..f0a9d60 100644
--- a/framework/java/android/net/wifi/WifiInfo.java
+++ b/framework/java/android/net/wifi/WifiInfo.java
@@ -16,11 +16,14 @@
package android.net.wifi;
+import static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID;
+
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
+import android.net.NetworkCapabilities;
import android.net.NetworkInfo.DetailedState;
import android.net.TransportInfo;
import android.os.Build;
@@ -85,6 +88,12 @@
stateMap.put(SupplicantState.INVALID, DetailedState.FAILED);
}
+ /**
+ * Indicates whether parceling should preserve fields that are set based on permissions of
+ * the process receiving the {@link NetworkCapabilities}.
+ */
+ private final boolean mParcelLocationSenstiveFields;
+
private SupplicantState mSupplicantState;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
private String mBSSID;
@@ -309,6 +318,7 @@
/** @hide */
@UnsupportedAppUsage
public WifiInfo() {
+ mParcelLocationSenstiveFields = false;
mWifiSsid = null;
mBSSID = null;
mNetworkId = -1;
@@ -320,6 +330,12 @@
/** @hide */
public void reset() {
+ if (mParcelLocationSenstiveFields) {
+ // To ensure that we don't accidentally set this bit on the master copy of WifiInfo
+ // (reset is only invoked in the master copy)
+ throw new UnsupportedOperationException(
+ "Cannot clear WifiInfo when parcelSensitiveLocationFields is set");
+ }
setInetAddress(null);
setBSSID(null);
setSSID(null);
@@ -354,6 +370,15 @@
* @hide
*/
public WifiInfo(WifiInfo source) {
+ this(source, true);
+ }
+
+ /**
+ * Copy constructor
+ * @hide
+ */
+ private WifiInfo(WifiInfo source, boolean parcelSensitiveFields) {
+ mParcelLocationSenstiveFields = parcelSensitiveFields;
if (source != null) {
mSupplicantState = source.mSupplicantState;
mBSSID = source.mBSSID;
@@ -918,7 +943,7 @@
StringBuffer sb = new StringBuffer();
String none = "<none>";
- sb.append("SSID: ").append(mWifiSsid == null ? WifiManager.UNKNOWN_SSID : mWifiSsid)
+ sb.append("SSID: ").append(getSSID())
.append(", BSSID: ").append(mBSSID == null ? none : mBSSID)
.append(", MAC: ").append(mMacAddress == null ? none : mMacAddress)
.append(", Supplicant state: ")
@@ -946,7 +971,7 @@
/** Implement the Parcelable interface {@hide} */
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mNetworkId);
+ dest.writeInt(mParcelLocationSenstiveFields ? mNetworkId : INVALID_NETWORK_ID);
dest.writeInt(mRssi);
dest.writeInt(mLinkSpeed);
dest.writeInt(mTxLinkSpeed);
@@ -960,11 +985,17 @@
}
if (mWifiSsid != null) {
dest.writeInt(1);
- mWifiSsid.writeToParcel(dest, flags);
+ final WifiSsid ssid;
+ if (mParcelLocationSenstiveFields) {
+ ssid = mWifiSsid;
+ } else {
+ ssid = WifiSsid.createFromHex(null);
+ }
+ ssid.writeToParcel(dest, flags);
} else {
dest.writeInt(0);
}
- dest.writeString(mBSSID);
+ dest.writeString(mParcelLocationSenstiveFields ? mBSSID : DEFAULT_MAC_ADDRESS);
dest.writeString(mMacAddress);
dest.writeInt(mMeteredHint ? 1 : 0);
dest.writeInt(mEphemeral ? 1 : 0);
@@ -981,12 +1012,12 @@
mSupplicantState.writeToParcel(dest, flags);
dest.writeInt(mOsuAp ? 1 : 0);
dest.writeString(mRequestingPackageName);
- dest.writeString(mFqdn);
- dest.writeString(mProviderFriendlyName);
+ dest.writeString(mParcelLocationSenstiveFields ? mFqdn : null);
+ dest.writeString(mParcelLocationSenstiveFields ? mProviderFriendlyName : null);
dest.writeInt(mWifiStandard);
dest.writeInt(mMaxSupportedTxLinkSpeed);
dest.writeInt(mMaxSupportedRxLinkSpeed);
- dest.writeString(mPasspointUniqueId);
+ dest.writeString(mParcelLocationSenstiveFields ? mPasspointUniqueId : null);
}
/** Implement the Parcelable interface {@hide} */
@@ -1143,4 +1174,30 @@
mMaxSupportedRxLinkSpeed,
mPasspointUniqueId);
}
+
+ /**
+ * Make a copy of WifiInfo instance.
+ *
+ * @param parcelSensitiveFields Whether to parcel location sensitive fields or not.
+ * @return instance of {@link WifiInfo}.
+ */
+ @Override
+ @NonNull
+ public WifiInfo makeCopy(boolean parcelSensitiveFields) {
+ if (!SdkLevel.isAtLeastS()) {
+ throw new UnsupportedOperationException();
+ }
+ return new WifiInfo(this, parcelSensitiveFields);
+ }
+
+ /**
+ * Whether it has location sensitive data or not.
+ */
+ @Override
+ public boolean hasLocationSensitiveFields() {
+ if (!SdkLevel.isAtLeastS()) {
+ throw new UnsupportedOperationException();
+ }
+ return true;
+ }
}
diff --git a/framework/java/android/net/wifi/aware/WifiAwareNetworkInfo.java b/framework/java/android/net/wifi/aware/WifiAwareNetworkInfo.java
index 60fe604..095c0de 100644
--- a/framework/java/android/net/wifi/aware/WifiAwareNetworkInfo.java
+++ b/framework/java/android/net/wifi/aware/WifiAwareNetworkInfo.java
@@ -16,12 +16,15 @@
package android.net.wifi.aware;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.net.NetworkCapabilities;
import android.net.TransportInfo;
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.modules.utils.build.SdkLevel;
+
import java.net.Inet6Address;
import java.net.NetworkInterface;
import java.net.SocketException;
@@ -46,13 +49,22 @@
* 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
+ private final Inet6Address mIpv6Addr;
+ private final int mPort;
+ private final int mTransportProtocol;
+
+ /** @hide */
+ public WifiAwareNetworkInfo() {
+ mIpv6Addr = null;
+ mPort = 0; // a value of 0 is considered invalid
+ mTransportProtocol = -1; // a value of -1 is considered invalid
+ }
/** @hide */
public WifiAwareNetworkInfo(Inet6Address ipv6Addr) {
mIpv6Addr = ipv6Addr;
+ mPort = 0; // a value of 0 is considered invalid
+ mTransportProtocol = -1; // a value of -1 is considered invalid
}
/** @hide */
@@ -62,6 +74,12 @@
mTransportProtocol = transportProtocol;
}
+ private WifiAwareNetworkInfo(@Nullable WifiAwareNetworkInfo source) {
+ mIpv6Addr = source != null ? source.mIpv6Addr : null;
+ mPort = source != null ? source.mPort : 0;
+ mTransportProtocol = source != null ? source.mTransportProtocol : -1;
+ }
+
/**
* Get the scoped link-local IPv6 address of the Wi-Fi Aware peer (not of the local device!).
*
@@ -137,7 +155,7 @@
ipv6Addr = Inet6Address.getByAddress(null, addr, ni);
} catch (UnknownHostException e) {
e.printStackTrace();
- return new WifiAwareNetworkInfo(null);
+ return new WifiAwareNetworkInfo();
}
return new WifiAwareNetworkInfo(ipv6Addr, port, transportProtocol);
}
@@ -179,4 +197,31 @@
public int hashCode() {
return Objects.hash(mIpv6Addr, mPort, mTransportProtocol);
}
+
+ /**
+ * Make a copy of WifiAwareNetworkInfo instance.
+ *
+ * @param parcelSensitiveFields Whether to parcel location sensitive fields or not.
+ * @return instance of {@link WifiAwareNetworkInfo}.
+ */
+ @Override
+ @NonNull
+ public WifiAwareNetworkInfo makeCopy(boolean parcelSensitiveFields) {
+ if (!SdkLevel.isAtLeastS()) {
+ throw new UnsupportedOperationException();
+ }
+ // No location sensitive data, ignore parcelSensitiveFields.
+ return new WifiAwareNetworkInfo(this);
+ }
+
+ /**
+ * Whether it has location sensitive data or not.
+ */
+ @Override
+ public boolean hasLocationSensitiveFields() {
+ if (!SdkLevel.isAtLeastS()) {
+ throw new UnsupportedOperationException();
+ }
+ return false;
+ }
}
diff --git a/framework/tests/src/android/net/wifi/WifiInfoTest.java b/framework/tests/src/android/net/wifi/WifiInfoTest.java
index cf1f83a..5cb16a5 100644
--- a/framework/tests/src/android/net/wifi/WifiInfoTest.java
+++ b/framework/tests/src/android/net/wifi/WifiInfoTest.java
@@ -17,10 +17,13 @@
package android.net.wifi;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
import android.os.Parcel;
@@ -57,7 +60,112 @@
* Verify parcel write/read with WifiInfo.
*/
@Test
- public void testWifiInfoParcelWriteRead() throws Exception {
+ public void testWifiInfoParcelWriteReadWithLocationSensitiveInfo() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastS());
+
+ WifiInfo writeWifiInfo = new WifiInfo();
+ writeWifiInfo.txSuccess = TEST_TX_SUCCESS;
+ writeWifiInfo.txRetries = TEST_TX_RETRIES;
+ writeWifiInfo.txBad = TEST_TX_BAD;
+ writeWifiInfo.rxSuccess = TEST_RX_SUCCESS;
+ writeWifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(TEST_SSID));
+ writeWifiInfo.setBSSID(TEST_BSSID);
+ writeWifiInfo.setNetworkId(TEST_NETWORK_ID);
+ writeWifiInfo.setTrusted(true);
+ writeWifiInfo.setOsuAp(true);
+ writeWifiInfo.setFQDN(TEST_FQDN);
+ writeWifiInfo.setProviderFriendlyName(TEST_PROVIDER_NAME);
+ writeWifiInfo.setRequestingPackageName(TEST_PACKAGE_NAME);
+ writeWifiInfo.setWifiStandard(TEST_WIFI_STANDARD);
+ writeWifiInfo.setMaxSupportedTxLinkSpeedMbps(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS);
+ writeWifiInfo.setMaxSupportedRxLinkSpeedMbps(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS);
+
+ // Make a copy which allows parcelling of location sensitive data.
+ WifiInfo writeWifiInfoWithLocationSensitiveInfo = writeWifiInfo.makeCopy(true);
+
+ Parcel parcel = Parcel.obtain();
+ writeWifiInfoWithLocationSensitiveInfo.writeToParcel(parcel, 0);
+ // Rewind the pointer to the head of the parcel.
+ parcel.setDataPosition(0);
+ WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel);
+
+ assertNotNull(readWifiInfo);
+ assertEquals(TEST_TX_SUCCESS, readWifiInfo.txSuccess);
+ assertEquals(TEST_TX_RETRIES, readWifiInfo.txRetries);
+ assertEquals(TEST_TX_BAD, readWifiInfo.txBad);
+ assertEquals(TEST_RX_SUCCESS, readWifiInfo.rxSuccess);
+ assertEquals("\"" + TEST_SSID + "\"", readWifiInfo.getSSID());
+ assertEquals(TEST_BSSID, readWifiInfo.getBSSID());
+ assertEquals(TEST_NETWORK_ID, readWifiInfo.getNetworkId());
+ assertTrue(readWifiInfo.isTrusted());
+ assertTrue(readWifiInfo.isOsuAp());
+ assertTrue(readWifiInfo.isPasspointAp());
+ assertEquals(TEST_PACKAGE_NAME, readWifiInfo.getRequestingPackageName());
+ assertEquals(TEST_FQDN, readWifiInfo.getPasspointFqdn());
+ assertEquals(TEST_PROVIDER_NAME, readWifiInfo.getPasspointProviderFriendlyName());
+ assertEquals(TEST_WIFI_STANDARD, readWifiInfo.getWifiStandard());
+ assertEquals(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS,
+ readWifiInfo.getMaxSupportedTxLinkSpeedMbps());
+ assertEquals(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS,
+ readWifiInfo.getMaxSupportedRxLinkSpeedMbps());
+ }
+
+ /**
+ * Verify parcel write/read with WifiInfo.
+ */
+ @Test
+ public void testWifiInfoParcelWriteReadWithoutLocationSensitiveInfo() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastS());
+
+ WifiInfo writeWifiInfo = new WifiInfo();
+ writeWifiInfo.txSuccess = TEST_TX_SUCCESS;
+ writeWifiInfo.txRetries = TEST_TX_RETRIES;
+ writeWifiInfo.txBad = TEST_TX_BAD;
+ writeWifiInfo.rxSuccess = TEST_RX_SUCCESS;
+ writeWifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(TEST_SSID));
+ writeWifiInfo.setBSSID(TEST_BSSID);
+ writeWifiInfo.setNetworkId(TEST_NETWORK_ID);
+ writeWifiInfo.setTrusted(true);
+ writeWifiInfo.setOsuAp(true);
+ writeWifiInfo.setFQDN(TEST_FQDN);
+ writeWifiInfo.setProviderFriendlyName(TEST_PROVIDER_NAME);
+ writeWifiInfo.setRequestingPackageName(TEST_PACKAGE_NAME);
+ writeWifiInfo.setWifiStandard(TEST_WIFI_STANDARD);
+ writeWifiInfo.setMaxSupportedTxLinkSpeedMbps(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS);
+ writeWifiInfo.setMaxSupportedRxLinkSpeedMbps(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS);
+
+ // Make a copy which allows parcelling of location sensitive data.
+ WifiInfo writeWifiInfoWithoutLocationSensitiveInfo = writeWifiInfo.makeCopy(false);
+
+ Parcel parcel = Parcel.obtain();
+ writeWifiInfoWithoutLocationSensitiveInfo.writeToParcel(parcel, 0);
+ // Rewind the pointer to the head of the parcel.
+ parcel.setDataPosition(0);
+ WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel);
+
+ assertNotNull(readWifiInfo);
+ assertEquals(TEST_TX_SUCCESS, readWifiInfo.txSuccess);
+ assertEquals(TEST_TX_RETRIES, readWifiInfo.txRetries);
+ assertEquals(TEST_TX_BAD, readWifiInfo.txBad);
+ assertEquals(TEST_RX_SUCCESS, readWifiInfo.rxSuccess);
+ assertEquals(WifiManager.UNKNOWN_SSID, readWifiInfo.getSSID());
+ assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, readWifiInfo.getBSSID());
+ assertEquals(WifiConfiguration.INVALID_NETWORK_ID, readWifiInfo.getNetworkId());
+ assertTrue(readWifiInfo.isTrusted());
+ assertTrue(readWifiInfo.isOsuAp());
+ assertFalse(readWifiInfo.isPasspointAp()); // fqdn & friendly name is masked.
+ assertEquals(TEST_PACKAGE_NAME, readWifiInfo.getRequestingPackageName());
+ assertNull(readWifiInfo.getPasspointFqdn());
+ assertNull(readWifiInfo.getPasspointProviderFriendlyName());
+ assertEquals(TEST_WIFI_STANDARD, readWifiInfo.getWifiStandard());
+ assertEquals(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS,
+ readWifiInfo.getMaxSupportedTxLinkSpeedMbps());
+ assertEquals(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS,
+ readWifiInfo.getMaxSupportedRxLinkSpeedMbps());
+ }
+
+ @Test
+ public void testWifiInfoCopyConstructor() throws Exception {
WifiInfo writeWifiInfo = new WifiInfo();
writeWifiInfo.txSuccess = TEST_TX_SUCCESS;
writeWifiInfo.txRetries = TEST_TX_RETRIES;
@@ -72,13 +180,8 @@
writeWifiInfo.setMaxSupportedTxLinkSpeedMbps(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS);
writeWifiInfo.setMaxSupportedRxLinkSpeedMbps(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS);
- Parcel parcel = Parcel.obtain();
- writeWifiInfo.writeToParcel(parcel, 0);
- // Rewind the pointer to the head of the parcel.
- parcel.setDataPosition(0);
- WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel);
+ WifiInfo readWifiInfo = new WifiInfo(writeWifiInfo);
- assertNotNull(readWifiInfo);
assertEquals(TEST_TX_SUCCESS, readWifiInfo.txSuccess);
assertEquals(TEST_TX_RETRIES, readWifiInfo.txRetries);
assertEquals(TEST_TX_BAD, readWifiInfo.txBad);