diff --git a/core/api/current.txt b/core/api/current.txt index ac538a0f7008..6d24d87d04cb 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -26608,6 +26608,8 @@ package android.net { method @Nullable public java.security.cert.X509Certificate getUserCert(); method @NonNull public String getUserIdentity(); method @Nullable public String getUsername(); + method public boolean isAutomaticIpVersionSelectionEnabled(); + method public boolean isAutomaticNattKeepaliveTimerEnabled(); method public boolean isBypassable(); method public boolean isMetered(); } @@ -26620,6 +26622,8 @@ package android.net { method @NonNull public android.net.Ikev2VpnProfile.Builder setAuthDigitalSignature(@NonNull java.security.cert.X509Certificate, @NonNull java.security.PrivateKey, @Nullable java.security.cert.X509Certificate); method @NonNull public android.net.Ikev2VpnProfile.Builder setAuthPsk(@NonNull byte[]); method @NonNull public android.net.Ikev2VpnProfile.Builder setAuthUsernamePassword(@NonNull String, @NonNull String, @Nullable java.security.cert.X509Certificate); + method @NonNull public android.net.Ikev2VpnProfile.Builder setAutomaticIpVersionSelectionEnabled(boolean); + method @NonNull public android.net.Ikev2VpnProfile.Builder setAutomaticNattKeepaliveTimerEnabled(boolean); method @NonNull public android.net.Ikev2VpnProfile.Builder setBypassable(boolean); method @NonNull public android.net.Ikev2VpnProfile.Builder setLocalRoutesExcluded(boolean); method @NonNull public android.net.Ikev2VpnProfile.Builder setMaxMtu(int); diff --git a/core/java/android/net/Ikev2VpnProfile.java b/core/java/android/net/Ikev2VpnProfile.java index 10ce3bf78b2a..647514486750 100644 --- a/core/java/android/net/Ikev2VpnProfile.java +++ b/core/java/android/net/Ikev2VpnProfile.java @@ -138,6 +138,8 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { private final int mMaxMtu; // Defaults in builder private final boolean mIsRestrictedToTestNetworks; @Nullable private final IkeTunnelConnectionParams mIkeTunConnParams; + private final boolean mAutomaticNattKeepaliveTimerEnabled; + private final boolean mAutomaticIpVersionSelectionEnabled; private Ikev2VpnProfile( int type, @@ -157,7 +159,9 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { boolean restrictToTestNetworks, boolean excludeLocalRoutes, boolean requiresInternetValidation, - @Nullable IkeTunnelConnectionParams ikeTunConnParams) { + @Nullable IkeTunnelConnectionParams ikeTunConnParams, + boolean automaticNattKeepaliveTimerEnabled, + boolean automaticIpVersionSelectionEnabled) { super(type, excludeLocalRoutes, requiresInternetValidation); checkNotNull(allowedAlgorithms, MISSING_PARAM_MSG_TMPL, "Allowed Algorithms"); @@ -185,6 +189,8 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { mMaxMtu = maxMtu; mIsRestrictedToTestNetworks = restrictToTestNetworks; mIkeTunConnParams = ikeTunConnParams; + mAutomaticNattKeepaliveTimerEnabled = automaticNattKeepaliveTimerEnabled; + mAutomaticIpVersionSelectionEnabled = automaticIpVersionSelectionEnabled; validate(); } @@ -420,6 +426,16 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { return mIsRestrictedToTestNetworks; } + /** Returns whether automatic NAT-T keepalive timers are enabled. */ + public boolean isAutomaticNattKeepaliveTimerEnabled() { + return mAutomaticNattKeepaliveTimerEnabled; + } + + /** Returns whether automatic IP version selection is enabled. */ + public boolean isAutomaticIpVersionSelectionEnabled() { + return mAutomaticIpVersionSelectionEnabled; + } + @Override public int hashCode() { return Objects.hash( @@ -440,7 +456,9 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { mIsRestrictedToTestNetworks, mExcludeLocalRoutes, mRequiresInternetValidation, - mIkeTunConnParams); + mIkeTunConnParams, + mAutomaticNattKeepaliveTimerEnabled, + mAutomaticIpVersionSelectionEnabled); } @Override @@ -467,7 +485,9 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { && mIsRestrictedToTestNetworks == other.mIsRestrictedToTestNetworks && mExcludeLocalRoutes == other.mExcludeLocalRoutes && mRequiresInternetValidation == other.mRequiresInternetValidation - && Objects.equals(mIkeTunConnParams, other.mIkeTunConnParams); + && Objects.equals(mIkeTunConnParams, other.mIkeTunConnParams) + && mAutomaticNattKeepaliveTimerEnabled == other.mAutomaticNattKeepaliveTimerEnabled + && mAutomaticIpVersionSelectionEnabled == other.mAutomaticIpVersionSelectionEnabled; } /** @@ -482,7 +502,8 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { public VpnProfile toVpnProfile() throws IOException, GeneralSecurityException { final VpnProfile profile = new VpnProfile("" /* Key; value unused by IKEv2VpnProfile(s) */, mIsRestrictedToTestNetworks, mExcludeLocalRoutes, mRequiresInternetValidation, - mIkeTunConnParams); + mIkeTunConnParams, mAutomaticNattKeepaliveTimerEnabled, + mAutomaticIpVersionSelectionEnabled); profile.proxy = mProxyInfo; profile.isBypassable = mIsBypassable; profile.isMetered = mIsMetered; @@ -603,6 +624,9 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { builder.setLocalRoutesExcluded(profile.excludeLocalRoutes && profile.isBypassable); builder.setRequiresInternetValidation(profile.requiresInternetValidation); + builder.setAutomaticNattKeepaliveTimerEnabled(profile.automaticNattKeepaliveTimerEnabled); + builder.setAutomaticIpVersionSelectionEnabled(profile.automaticIpVersionSelectionEnabled); + return builder.build(); } @@ -773,6 +797,8 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { private int mMaxMtu = PlatformVpnProfile.MAX_MTU_DEFAULT; private boolean mIsRestrictedToTestNetworks = false; private boolean mExcludeLocalRoutes = false; + private boolean mAutomaticNattKeepaliveTimerEnabled = false; + private boolean mAutomaticIpVersionSelectionEnabled = false; @Nullable private final IkeTunnelConnectionParams mIkeTunConnParams; /** @@ -1079,6 +1105,34 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { return this; } + /** + * Sets the enabled state of the automatic NAT-T keepalive timers + * + * @param isEnabled {@code true} to enable automatic keepalive timers, based on internal + * platform signals. Defaults to {@code false}. + * @return this {@link Builder} object to facilitate chaining of method calls + */ + @NonNull + @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS) + public Builder setAutomaticNattKeepaliveTimerEnabled(boolean isEnabled) { + mAutomaticNattKeepaliveTimerEnabled = isEnabled; + return this; + } + + /** + * Sets the enabled state of the automatic IP version selection + * + * @param isEnabled {@code true} to enable automatic IP version selection, based on internal + * platform signals. Defaults to {@code false}. + * @return this {@link Builder} object to facilitate chaining of method calls + */ + @NonNull + @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS) + public Builder setAutomaticIpVersionSelectionEnabled(boolean isEnabled) { + mAutomaticIpVersionSelectionEnabled = isEnabled; + return this; + } + /** * Sets whether the local traffic is exempted from the VPN. * @@ -1129,7 +1183,9 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { mIsRestrictedToTestNetworks, mExcludeLocalRoutes, mRequiresInternetValidation, - mIkeTunConnParams); + mIkeTunConnParams, + mAutomaticNattKeepaliveTimerEnabled, + mAutomaticIpVersionSelectionEnabled); } } } diff --git a/core/java/com/android/internal/net/VpnProfile.java b/core/java/com/android/internal/net/VpnProfile.java index b334e9172729..545b26114b0c 100644 --- a/core/java/com/android/internal/net/VpnProfile.java +++ b/core/java/com/android/internal/net/VpnProfile.java @@ -152,6 +152,8 @@ public final class VpnProfile implements Cloneable, Parcelable { public final boolean excludeLocalRoutes; // 25 public final boolean requiresInternetValidation; // 26 public final IkeTunnelConnectionParams ikeTunConnParams; // 27 + public final boolean automaticNattKeepaliveTimerEnabled; // 28 + public final boolean automaticIpVersionSelectionEnabled; // 29 // Helper fields. @UnsupportedAppUsage @@ -167,11 +169,21 @@ public final class VpnProfile implements Cloneable, Parcelable { public VpnProfile(String key, boolean isRestrictedToTestNetworks, boolean excludeLocalRoutes, boolean requiresInternetValidation, IkeTunnelConnectionParams ikeTunConnParams) { + this(key, isRestrictedToTestNetworks, excludeLocalRoutes, requiresInternetValidation, + ikeTunConnParams, false, false); + } + + public VpnProfile(String key, boolean isRestrictedToTestNetworks, boolean excludeLocalRoutes, + boolean requiresInternetValidation, IkeTunnelConnectionParams ikeTunConnParams, + boolean automaticNattKeepaliveTimerEnabled, + boolean automaticIpVersionSelectionEnabled) { this.key = key; this.isRestrictedToTestNetworks = isRestrictedToTestNetworks; this.excludeLocalRoutes = excludeLocalRoutes; this.requiresInternetValidation = requiresInternetValidation; this.ikeTunConnParams = ikeTunConnParams; + this.automaticNattKeepaliveTimerEnabled = automaticNattKeepaliveTimerEnabled; + this.automaticIpVersionSelectionEnabled = automaticIpVersionSelectionEnabled; } @UnsupportedAppUsage @@ -207,6 +219,8 @@ public final class VpnProfile implements Cloneable, Parcelable { in.readParcelable(PersistableBundle.class.getClassLoader()); ikeTunConnParams = (bundle == null) ? null : TunnelConnectionParamsUtils.fromPersistableBundle(bundle); + automaticNattKeepaliveTimerEnabled = in.readBoolean(); + automaticIpVersionSelectionEnabled = in.readBoolean(); } /** @@ -258,6 +272,8 @@ public final class VpnProfile implements Cloneable, Parcelable { out.writeBoolean(requiresInternetValidation); out.writeParcelable(ikeTunConnParams == null ? null : TunnelConnectionParamsUtils.toPersistableBundle(ikeTunConnParams), flags); + out.writeBoolean(automaticNattKeepaliveTimerEnabled); + out.writeBoolean(automaticIpVersionSelectionEnabled); } /** @@ -282,8 +298,9 @@ public final class VpnProfile implements Cloneable, Parcelable { // 27: ...and requiresInternetValidation // (26,27 can only be found on dogfood devices) // 28: ...and ikeTunConnParams + // 29-30: ...and automatic NATT/IP version if ((values.length < 14 || (values.length > 19 && values.length < 24) - || values.length > 28)) { + || (values.length > 28 && values.length < 30) || values.length > 30)) { return null; } @@ -322,8 +339,19 @@ public final class VpnProfile implements Cloneable, Parcelable { tempIkeTunConnParams = null; } + final boolean automaticNattKeepaliveTimerEnabled; + final boolean automaticIpVersionSelectionEnabled; + if (values.length >= 30) { + automaticNattKeepaliveTimerEnabled = Boolean.parseBoolean(values[28]); + automaticIpVersionSelectionEnabled = Boolean.parseBoolean(values[29]); + } else { + automaticNattKeepaliveTimerEnabled = false; + automaticIpVersionSelectionEnabled = false; + } + VpnProfile profile = new VpnProfile(key, isRestrictedToTestNetworks, - excludeLocalRoutes, requiresInternetValidation, tempIkeTunConnParams); + excludeLocalRoutes, requiresInternetValidation, tempIkeTunConnParams, + automaticNattKeepaliveTimerEnabled, automaticIpVersionSelectionEnabled); profile.name = values[0]; profile.type = Integer.parseInt(values[1]); if (profile.type < 0 || profile.type > TYPE_MAX) { @@ -447,6 +475,8 @@ public final class VpnProfile implements Cloneable, Parcelable { } else { builder.append(VALUE_DELIMITER).append(""); } + builder.append(VALUE_DELIMITER).append(automaticNattKeepaliveTimerEnabled); + builder.append(VALUE_DELIMITER).append(automaticIpVersionSelectionEnabled); return builder.toString().getBytes(StandardCharsets.UTF_8); } @@ -529,7 +559,8 @@ public final class VpnProfile implements Cloneable, Parcelable { l2tpSecret, ipsecIdentifier, ipsecSecret, ipsecUserCert, ipsecCaCert, ipsecServerCert, proxy, mAllowedAlgorithms, isBypassable, isMetered, maxMtu, areAuthParamsInline, isRestrictedToTestNetworks, excludeLocalRoutes, requiresInternetValidation, - ikeTunConnParams); + ikeTunConnParams, automaticNattKeepaliveTimerEnabled, + automaticIpVersionSelectionEnabled); } /** Checks VPN profiles for interior equality. */ @@ -565,7 +596,9 @@ public final class VpnProfile implements Cloneable, Parcelable { && isRestrictedToTestNetworks == other.isRestrictedToTestNetworks && excludeLocalRoutes == other.excludeLocalRoutes && requiresInternetValidation == other.requiresInternetValidation - && Objects.equals(ikeTunConnParams, other.ikeTunConnParams); + && Objects.equals(ikeTunConnParams, other.ikeTunConnParams) + && automaticNattKeepaliveTimerEnabled == other.automaticNattKeepaliveTimerEnabled + && automaticIpVersionSelectionEnabled == other.automaticIpVersionSelectionEnabled; } @NonNull