Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3e633b78 authored by Benedict Wong's avatar Benedict Wong Committed by Automerger Merge Worker
Browse files

Merge "Allow VcnTransportInfo to be parcelled" am: eecd1d9c

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1686985

Change-Id: I6eb37e9cce547246402dc24563ecb99ec29dd690
parents f6bbf126 eecd1d9c
Loading
Loading
Loading
Loading
+88 −12
Original line number Original line Diff line number Diff line
@@ -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) {
        if (wifiInfo == null && subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
            throw new IllegalArgumentException(
                    "VcnTransportInfo requires either non-null WifiInfo or valid subId");
    }
    }


    private VcnTransportInfo(@Nullable WifiInfo wifiInfo, int subId, long redactions) {
        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,19 +139,61 @@ 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);

                    // 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;
                        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) {
                    return new VcnTransportInfo[size];
                    return new VcnTransportInfo[size];
                }
                }
+41 −0
Original line number Original line Diff line number Diff line
@@ -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());
    }
}
}