Expose vpn bypassability in VpnTransportInfo
Bug: 256775913 Test: m framework-connectivity.stubs.source.system-update-current-api Test: m lint-check Test: atest FrameworksNetTests Change-Id: I6aaad7b4372aa4f91df4bed89caea674031a6367
This commit is contained in:
parent
e9fb16acde
commit
d12d2011cb
4 changed files with 113 additions and 21 deletions
|
|
@ -228,13 +228,9 @@ package android.net {
|
|||
}
|
||||
|
||||
public final class VpnTransportInfo implements android.os.Parcelable android.net.TransportInfo {
|
||||
ctor public VpnTransportInfo(int, @Nullable String);
|
||||
method public int describeContents();
|
||||
ctor @Deprecated public VpnTransportInfo(int, @Nullable String);
|
||||
method @Nullable public String getSessionId();
|
||||
method public int getType();
|
||||
method @NonNull public android.net.VpnTransportInfo makeCopy(long);
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.net.VpnTransportInfo> CREATOR;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -511,6 +511,15 @@ package android.net {
|
|||
field @NonNull public static final android.os.Parcelable.Creator<android.net.TcpKeepalivePacketData> CREATOR;
|
||||
}
|
||||
|
||||
public final class VpnTransportInfo implements android.os.Parcelable android.net.TransportInfo {
|
||||
ctor public VpnTransportInfo(int, @Nullable String, boolean);
|
||||
method public int describeContents();
|
||||
method public boolean getBypassable();
|
||||
method public int getType();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.net.VpnTransportInfo> CREATOR;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.net.apf {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package android.net;
|
||||
|
||||
import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
|
||||
import static android.annotation.SystemApi.Client.PRIVILEGED_APPS;
|
||||
import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
|
|
@ -27,6 +28,10 @@ import android.os.Parcel;
|
|||
import android.os.Parcelable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.android.modules.utils.build.SdkLevel;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
|
|
@ -37,7 +42,7 @@ import java.util.Objects;
|
|||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi(client = MODULE_LIBRARIES)
|
||||
@SystemApi(client = PRIVILEGED_APPS)
|
||||
public final class VpnTransportInfo implements TransportInfo, Parcelable {
|
||||
/** Type of this VPN. */
|
||||
private final int mType;
|
||||
|
|
@ -45,6 +50,13 @@ public final class VpnTransportInfo implements TransportInfo, Parcelable {
|
|||
@Nullable
|
||||
private final String mSessionId;
|
||||
|
||||
private final boolean mBypassable;
|
||||
|
||||
// TODO: Refer to Build.VERSION_CODES when it's available in every branch.
|
||||
private static final int UPSIDE_DOWN_CAKE = 34;
|
||||
|
||||
/** @hide */
|
||||
@SystemApi(client = MODULE_LIBRARIES)
|
||||
@Override
|
||||
public @RedactionType long getApplicableRedactions() {
|
||||
return REDACT_FOR_NETWORK_SETTINGS;
|
||||
|
|
@ -52,21 +64,58 @@ public final class VpnTransportInfo implements TransportInfo, Parcelable {
|
|||
|
||||
/**
|
||||
* Create a copy of a {@link VpnTransportInfo} with the sessionId redacted if necessary.
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
@SystemApi(client = MODULE_LIBRARIES)
|
||||
public VpnTransportInfo makeCopy(@RedactionType long redactions) {
|
||||
return new VpnTransportInfo(mType,
|
||||
((redactions & REDACT_FOR_NETWORK_SETTINGS) != 0) ? null : mSessionId);
|
||||
((redactions & REDACT_FOR_NETWORK_SETTINGS) != 0) ? null : mSessionId, mBypassable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated please use {@link VpnTransportInfo(int,String,boolean)} instead.
|
||||
* @hide
|
||||
*/
|
||||
@Deprecated
|
||||
@SystemApi(client = MODULE_LIBRARIES)
|
||||
public VpnTransportInfo(int type, @Nullable String sessionId) {
|
||||
// When the module runs on older SDKs, |bypassable| will always be false since the old Vpn
|
||||
// code will call this constructor. For Settings VPNs, this is always correct as they are
|
||||
// never bypassable. For VpnManager and VpnService types, this may be wrong since both of
|
||||
// them have a choice. However, on these SDKs VpnTransportInfo#getBypassable is not
|
||||
// available anyway, so this should be harmless. False is a better choice than true here
|
||||
// regardless because it is the default value for both VpnManager and VpnService if the app
|
||||
// does not do anything about it.
|
||||
this(type, sessionId, false /* bypassable */);
|
||||
}
|
||||
|
||||
public VpnTransportInfo(int type, @Nullable String sessionId, boolean bypassable) {
|
||||
this.mType = type;
|
||||
this.mSessionId = sessionId;
|
||||
this.mBypassable = bypassable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the VPN is allowing bypass.
|
||||
*
|
||||
* This method is not supported in SDK below U, and will throw
|
||||
* {@code UnsupportedOperationException} if called.
|
||||
*/
|
||||
@RequiresApi(UPSIDE_DOWN_CAKE)
|
||||
public boolean getBypassable() {
|
||||
if (!SdkLevel.isAtLeastU()) {
|
||||
throw new UnsupportedOperationException("Not supported before U");
|
||||
}
|
||||
|
||||
return mBypassable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the session Id of this VpnTransportInfo.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi(client = MODULE_LIBRARIES)
|
||||
@Nullable
|
||||
public String getSessionId() {
|
||||
return mSessionId;
|
||||
|
|
@ -84,17 +133,19 @@ public final class VpnTransportInfo implements TransportInfo, Parcelable {
|
|||
if (!(o instanceof VpnTransportInfo)) return false;
|
||||
|
||||
VpnTransportInfo that = (VpnTransportInfo) o;
|
||||
return (this.mType == that.mType) && TextUtils.equals(this.mSessionId, that.mSessionId);
|
||||
return (this.mType == that.mType) && TextUtils.equals(this.mSessionId, that.mSessionId)
|
||||
&& (this.mBypassable == that.mBypassable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mType, mSessionId);
|
||||
return Objects.hash(mType, mSessionId, mBypassable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("VpnTransportInfo{type=%d, sessionId=%s}", mType, mSessionId);
|
||||
return String.format("VpnTransportInfo{type=%d, sessionId=%s, bypassable=%b}",
|
||||
mType, mSessionId, mBypassable);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -106,12 +157,13 @@ public final class VpnTransportInfo implements TransportInfo, Parcelable {
|
|||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeInt(mType);
|
||||
dest.writeString(mSessionId);
|
||||
dest.writeBoolean(mBypassable);
|
||||
}
|
||||
|
||||
public static final @NonNull Creator<VpnTransportInfo> CREATOR =
|
||||
new Creator<VpnTransportInfo>() {
|
||||
public VpnTransportInfo createFromParcel(Parcel in) {
|
||||
return new VpnTransportInfo(in.readInt(), in.readString());
|
||||
return new VpnTransportInfo(in.readInt(), in.readString(), in.readBoolean());
|
||||
}
|
||||
public VpnTransportInfo[] newArray(int size) {
|
||||
return new VpnTransportInfo[size];
|
||||
|
|
|
|||
|
|
@ -19,10 +19,13 @@ package android.net;
|
|||
import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
|
||||
import static android.net.NetworkCapabilities.REDACT_NONE;
|
||||
|
||||
import static com.android.testutils.MiscAsserts.assertThrows;
|
||||
import static com.android.testutils.ParcelUtils.assertParcelSane;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.os.Build;
|
||||
|
||||
|
|
@ -31,6 +34,7 @@ import androidx.test.filters.SmallTest;
|
|||
import com.android.testutils.DevSdkIgnoreRule;
|
||||
import com.android.testutils.DevSdkIgnoreRunner;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
|
|
@ -38,36 +42,67 @@ import org.junit.runner.RunWith;
|
|||
@SmallTest
|
||||
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
|
||||
public class VpnTransportInfoTest {
|
||||
@Rule
|
||||
public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
|
||||
|
||||
@Test
|
||||
public void testParceling() {
|
||||
VpnTransportInfo v = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, "12345");
|
||||
assertParcelSane(v, 2 /* fieldCount */);
|
||||
final VpnTransportInfo v = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, "12345");
|
||||
assertParcelSane(v, 3 /* fieldCount */);
|
||||
|
||||
final VpnTransportInfo v2 =
|
||||
new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, "12345", true);
|
||||
assertParcelSane(v2, 3 /* fieldCount */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEqualsAndHashCode() {
|
||||
String session1 = "12345";
|
||||
String session2 = "6789";
|
||||
VpnTransportInfo v11 = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, session1);
|
||||
VpnTransportInfo v12 = new VpnTransportInfo(VpnManager.TYPE_VPN_SERVICE, session1);
|
||||
VpnTransportInfo v13 = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, session1);
|
||||
VpnTransportInfo v14 = new VpnTransportInfo(VpnManager.TYPE_VPN_LEGACY, session1);
|
||||
VpnTransportInfo v15 = new VpnTransportInfo(VpnManager.TYPE_VPN_OEM, session1);
|
||||
VpnTransportInfo v21 = new VpnTransportInfo(VpnManager.TYPE_VPN_LEGACY, session2);
|
||||
final VpnTransportInfo v11 = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, session1);
|
||||
final VpnTransportInfo v12 = new VpnTransportInfo(VpnManager.TYPE_VPN_SERVICE, session1);
|
||||
final VpnTransportInfo v13 = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, session1);
|
||||
final VpnTransportInfo v14 = new VpnTransportInfo(VpnManager.TYPE_VPN_LEGACY, session1);
|
||||
final VpnTransportInfo v15 = new VpnTransportInfo(VpnManager.TYPE_VPN_OEM, session1);
|
||||
final VpnTransportInfo v16 = new VpnTransportInfo(VpnManager.TYPE_VPN_OEM, session1, true);
|
||||
final VpnTransportInfo v17 = new VpnTransportInfo(VpnManager.TYPE_VPN_OEM, session1, true);
|
||||
final VpnTransportInfo v21 = new VpnTransportInfo(VpnManager.TYPE_VPN_LEGACY, session2);
|
||||
|
||||
VpnTransportInfo v31 = v11.makeCopy(REDACT_FOR_NETWORK_SETTINGS);
|
||||
VpnTransportInfo v32 = v13.makeCopy(REDACT_FOR_NETWORK_SETTINGS);
|
||||
final VpnTransportInfo v31 = v11.makeCopy(REDACT_FOR_NETWORK_SETTINGS);
|
||||
final VpnTransportInfo v32 = v13.makeCopy(REDACT_FOR_NETWORK_SETTINGS);
|
||||
final VpnTransportInfo v33 = v16.makeCopy(REDACT_FOR_NETWORK_SETTINGS);
|
||||
final VpnTransportInfo v34 = v17.makeCopy(REDACT_FOR_NETWORK_SETTINGS);
|
||||
|
||||
assertNotEquals(v11, v12);
|
||||
assertNotEquals(v13, v14);
|
||||
assertNotEquals(v14, v15);
|
||||
assertNotEquals(v14, v21);
|
||||
assertNotEquals(v15, v16);
|
||||
|
||||
assertEquals(v11, v13);
|
||||
assertEquals(v31, v32);
|
||||
assertEquals(v33, v34);
|
||||
assertEquals(v11.hashCode(), v13.hashCode());
|
||||
assertEquals(v16.hashCode(), v17.hashCode());
|
||||
assertEquals(REDACT_FOR_NETWORK_SETTINGS, v32.getApplicableRedactions());
|
||||
assertEquals(session1, v15.makeCopy(REDACT_NONE).getSessionId());
|
||||
}
|
||||
|
||||
@DevSdkIgnoreRule.IgnoreAfter(Build.VERSION_CODES.TIRAMISU)
|
||||
@Test
|
||||
public void testGetBypassable_beforeU() {
|
||||
final VpnTransportInfo v = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, "12345");
|
||||
assertThrows(UnsupportedOperationException.class, () -> v.getBypassable());
|
||||
}
|
||||
|
||||
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
|
||||
@Test
|
||||
public void testGetBypassable_afterU() {
|
||||
final VpnTransportInfo v = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, "12345");
|
||||
assertFalse(v.getBypassable());
|
||||
|
||||
final VpnTransportInfo v2 =
|
||||
new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, "12345", true);
|
||||
assertTrue(v2.getBypassable());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue