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
diff --git a/framework/api/module-lib-current.txt b/framework/api/module-lib-current.txt
index a2a1ac0..988947a 100644
--- a/framework/api/module-lib-current.txt
+++ b/framework/api/module-lib-current.txt
@@ -228,13 +228,9 @@
}
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;
}
}
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index 8b35197..c7872a0 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -511,6 +511,15 @@
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 {
diff --git a/framework/src/android/net/VpnTransportInfo.java b/framework/src/android/net/VpnTransportInfo.java
index 4071c9a..ebad477 100644
--- a/framework/src/android/net/VpnTransportInfo.java
+++ b/framework/src/android/net/VpnTransportInfo.java
@@ -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.Parcelable;
import android.text.TextUtils;
+import androidx.annotation.RequiresApi;
+
+import com.android.modules.utils.build.SdkLevel;
+
import java.util.Objects;
/**
@@ -37,7 +42,7 @@
*
* @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 @@
@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 @@
/**
* 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 @@
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 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];