Merge "Allow VcnTransportInfo to be parcelled"
This commit is contained in:
@@ -16,14 +16,23 @@
|
|||||||
|
|
||||||
package android.net.vcn;
|
package android.net.vcn;
|
||||||
|
|
||||||
|
import static android.net.NetworkCapabilities.REDACT_ALL;
|
||||||
|
import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
|
||||||
|
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||||
|
|
||||||
|
import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
import android.net.NetworkCapabilities;
|
||||||
import android.net.TransportInfo;
|
import android.net.TransportInfo;
|
||||||
import android.net.wifi.WifiInfo;
|
import android.net.wifi.WifiInfo;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.telephony.SubscriptionManager;
|
import android.telephony.SubscriptionManager;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,28 +46,41 @@ import java.util.Objects;
|
|||||||
* SubscriptionManager#INVALID_SUBSCRIPTION_ID}. If the underlying Network is Cellular, the WifiInfo
|
* SubscriptionManager#INVALID_SUBSCRIPTION_ID}. If the underlying Network is Cellular, the WifiInfo
|
||||||
* will be {@code null}.
|
* will be {@code null}.
|
||||||
*
|
*
|
||||||
|
* <p>Receipt of a VcnTransportInfo requires the NETWORK_SETTINGS permission; else the entire
|
||||||
|
* VcnTransportInfo instance will be redacted.
|
||||||
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public class VcnTransportInfo implements TransportInfo, Parcelable {
|
public class VcnTransportInfo implements TransportInfo, Parcelable {
|
||||||
@Nullable private final WifiInfo mWifiInfo;
|
@Nullable private final WifiInfo mWifiInfo;
|
||||||
private final int mSubId;
|
private final int mSubId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The redaction scheme to use when parcelling.
|
||||||
|
*
|
||||||
|
* <p>The TransportInfo/NetworkCapabilities redaction mechanisms rely on redaction being
|
||||||
|
* performed at parcelling time. This means that the redaction scheme must be stored for later
|
||||||
|
* use.
|
||||||
|
*
|
||||||
|
* <p>Since the redaction scheme itself is not parcelled, this field is listed as a transient.
|
||||||
|
*
|
||||||
|
* <p>Defaults to REDACT_ALL when constructed using public constructors, or creating from
|
||||||
|
* parcels.
|
||||||
|
*/
|
||||||
|
private final transient long mRedactions;
|
||||||
|
|
||||||
public VcnTransportInfo(@NonNull WifiInfo wifiInfo) {
|
public VcnTransportInfo(@NonNull WifiInfo wifiInfo) {
|
||||||
this(wifiInfo, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
|
this(wifiInfo, INVALID_SUBSCRIPTION_ID, REDACT_ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
public VcnTransportInfo(int subId) {
|
public VcnTransportInfo(int subId) {
|
||||||
this(null /* wifiInfo */, subId);
|
this(null /* wifiInfo */, subId, REDACT_ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
private VcnTransportInfo(@Nullable WifiInfo wifiInfo, int subId) {
|
private VcnTransportInfo(@Nullable WifiInfo wifiInfo, int subId, long redactions) {
|
||||||
if (wifiInfo == null && subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"VcnTransportInfo requires either non-null WifiInfo or valid subId");
|
|
||||||
}
|
|
||||||
|
|
||||||
mWifiInfo = wifiInfo;
|
mWifiInfo = wifiInfo;
|
||||||
mSubId = subId;
|
mSubId = subId;
|
||||||
|
mRedactions = redactions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -86,8 +108,19 @@ public class VcnTransportInfo implements TransportInfo, Parcelable {
|
|||||||
return mSubId;
|
return mSubId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the redaction scheme
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@VisibleForTesting(visibility = PRIVATE)
|
||||||
|
public long getRedaction() {
|
||||||
|
return mRedactions;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
|
// mRedactions not hashed, as it is a transient, for control of parcelling
|
||||||
return Objects.hash(mWifiInfo, mSubId);
|
return Objects.hash(mWifiInfo, mSubId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,6 +129,7 @@ public class VcnTransportInfo implements TransportInfo, Parcelable {
|
|||||||
if (!(o instanceof VcnTransportInfo)) return false;
|
if (!(o instanceof VcnTransportInfo)) return false;
|
||||||
final VcnTransportInfo that = (VcnTransportInfo) o;
|
final VcnTransportInfo that = (VcnTransportInfo) o;
|
||||||
|
|
||||||
|
// mRedactions not compared, as it is a transient, for control of parcelling
|
||||||
return Objects.equals(mWifiInfo, that.mWifiInfo) && mSubId == that.mSubId;
|
return Objects.equals(mWifiInfo, that.mWifiInfo) && mSubId == that.mSubId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,17 +139,59 @@ public class VcnTransportInfo implements TransportInfo, Parcelable {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NonNull
|
||||||
|
public TransportInfo makeCopy(long redactions) {
|
||||||
|
return new VcnTransportInfo(
|
||||||
|
mWifiInfo == null ? null : mWifiInfo.makeCopy(redactions), mSubId, redactions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getApplicableRedactions() {
|
||||||
|
long redactions = REDACT_FOR_NETWORK_SETTINGS;
|
||||||
|
|
||||||
|
// Add additional wifi redactions if necessary
|
||||||
|
if (mWifiInfo != null) {
|
||||||
|
redactions |= mWifiInfo.getApplicableRedactions();
|
||||||
|
}
|
||||||
|
|
||||||
|
return redactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shouldParcelNetworkSettingsFields() {
|
||||||
|
return (mRedactions & NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public void writeToParcel(@NonNull Parcel dest, int flags) {}
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||||
|
dest.writeInt(shouldParcelNetworkSettingsFields() ? mSubId : INVALID_SUBSCRIPTION_ID);
|
||||||
|
dest.writeParcelable(
|
||||||
|
shouldParcelNetworkSettingsFields() ? (Parcelable) mWifiInfo : null, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "VcnTransportInfo { mWifiInfo = " + mWifiInfo + ", mSubId = " + mSubId + " }";
|
||||||
|
}
|
||||||
|
|
||||||
/** Implement the Parcelable interface */
|
/** Implement the Parcelable interface */
|
||||||
public static final @NonNull Creator<VcnTransportInfo> CREATOR =
|
public static final @NonNull Creator<VcnTransportInfo> CREATOR =
|
||||||
new Creator<VcnTransportInfo>() {
|
new Creator<VcnTransportInfo>() {
|
||||||
public VcnTransportInfo createFromParcel(Parcel in) {
|
public VcnTransportInfo createFromParcel(Parcel in) {
|
||||||
// return null instead of a default VcnTransportInfo to avoid leaking
|
final int subId = in.readInt();
|
||||||
// information about this being a VCN Network (instead of macro cellular, etc)
|
final WifiInfo wifiInfo = in.readParcelable(null);
|
||||||
return null;
|
|
||||||
|
// If all fields are their null values, return null TransportInfo to avoid
|
||||||
|
// leaking information about this being a VCN Network (instead of macro
|
||||||
|
// cellular, etc)
|
||||||
|
if (wifiInfo == null && subId == INVALID_SUBSCRIPTION_ID) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent further forwarding by redacting everything in future parcels from
|
||||||
|
// this VcnTransportInfo
|
||||||
|
return new VcnTransportInfo(wifiInfo, subId, REDACT_ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
public VcnTransportInfo[] newArray(int size) {
|
public VcnTransportInfo[] newArray(int size) {
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package android.net.vcn;
|
package android.net.vcn;
|
||||||
|
|
||||||
|
import static android.net.NetworkCapabilities.REDACT_ALL;
|
||||||
|
import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
|
||||||
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
@@ -36,6 +38,12 @@ public class VcnTransportInfoTest {
|
|||||||
private static final VcnTransportInfo CELL_UNDERLYING_INFO = new VcnTransportInfo(SUB_ID);
|
private static final VcnTransportInfo CELL_UNDERLYING_INFO = new VcnTransportInfo(SUB_ID);
|
||||||
private static final VcnTransportInfo WIFI_UNDERLYING_INFO = new VcnTransportInfo(WIFI_INFO);
|
private static final VcnTransportInfo WIFI_UNDERLYING_INFO = new VcnTransportInfo(WIFI_INFO);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRedactionDefaults() {
|
||||||
|
assertEquals(REDACT_ALL, CELL_UNDERLYING_INFO.getRedaction());
|
||||||
|
assertEquals(REDACT_ALL, WIFI_UNDERLYING_INFO.getRedaction());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetWifiInfo() {
|
public void testGetWifiInfo() {
|
||||||
assertEquals(WIFI_INFO, WIFI_UNDERLYING_INFO.getWifiInfo());
|
assertEquals(WIFI_INFO, WIFI_UNDERLYING_INFO.getWifiInfo());
|
||||||
@@ -50,6 +58,18 @@ public class VcnTransportInfoTest {
|
|||||||
assertEquals(INVALID_SUBSCRIPTION_ID, WIFI_UNDERLYING_INFO.getSubId());
|
assertEquals(INVALID_SUBSCRIPTION_ID, WIFI_UNDERLYING_INFO.getSubId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMakeCopySetsRedactions() {
|
||||||
|
assertEquals(
|
||||||
|
REDACT_FOR_NETWORK_SETTINGS,
|
||||||
|
((VcnTransportInfo) CELL_UNDERLYING_INFO.makeCopy(REDACT_FOR_NETWORK_SETTINGS))
|
||||||
|
.getRedaction());
|
||||||
|
assertEquals(
|
||||||
|
REDACT_FOR_NETWORK_SETTINGS,
|
||||||
|
((VcnTransportInfo) WIFI_UNDERLYING_INFO.makeCopy(REDACT_FOR_NETWORK_SETTINGS))
|
||||||
|
.getRedaction());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEquals() {
|
public void testEquals() {
|
||||||
assertEquals(CELL_UNDERLYING_INFO, CELL_UNDERLYING_INFO);
|
assertEquals(CELL_UNDERLYING_INFO, CELL_UNDERLYING_INFO);
|
||||||
@@ -64,8 +84,29 @@ public class VcnTransportInfoTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void verifyParcelingIsNull(VcnTransportInfo vcnTransportInfo) {
|
private void verifyParcelingIsNull(VcnTransportInfo vcnTransportInfo) {
|
||||||
|
// Verify redacted by default
|
||||||
Parcel parcel = Parcel.obtain();
|
Parcel parcel = Parcel.obtain();
|
||||||
vcnTransportInfo.writeToParcel(parcel, 0 /* flags */);
|
vcnTransportInfo.writeToParcel(parcel, 0 /* flags */);
|
||||||
|
parcel.setDataPosition(0);
|
||||||
|
|
||||||
assertNull(VcnTransportInfo.CREATOR.createFromParcel(parcel));
|
assertNull(VcnTransportInfo.CREATOR.createFromParcel(parcel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParcelUnparcelNotRedactedForSysUi() {
|
||||||
|
verifyParcelingForSysUi(CELL_UNDERLYING_INFO);
|
||||||
|
verifyParcelingForSysUi(WIFI_UNDERLYING_INFO);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyParcelingForSysUi(VcnTransportInfo vcnTransportInfo) {
|
||||||
|
// Allow fully unredacted; SysUI will have all the relevant permissions.
|
||||||
|
final VcnTransportInfo unRedacted = (VcnTransportInfo) vcnTransportInfo.makeCopy(0);
|
||||||
|
final Parcel parcel = Parcel.obtain();
|
||||||
|
unRedacted.writeToParcel(parcel, 0 /* flags */);
|
||||||
|
parcel.setDataPosition(0);
|
||||||
|
|
||||||
|
final VcnTransportInfo unparceled = VcnTransportInfo.CREATOR.createFromParcel(parcel);
|
||||||
|
assertEquals(vcnTransportInfo, unparceled);
|
||||||
|
assertEquals(REDACT_ALL, unparceled.getRedaction());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user