From ffe15f981e08f388953c73d456961c894a0d9e06 Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Tue, 1 Oct 2024 02:11:28 +0000 Subject: Expose VCN APIs for framework code As the first step of mainlining VCN, VCN will be moved from framework to its own java_sdk_library and hidden APIs will no longer be accessible to framework code. This CL exposes these classes, methods and constants as @SystemApi so that framework code can continue accessing them. Note, these APIs are temporarily exposed from framework.jar. Followup CLs will move them to the framework-connectivity-b.jar Bug: 376339506 Test: atest FrameworksVcnTests && atest CtsVcnTestCases Flag: android.net.vcn.mainline_vcn_module_api API-Coverage-Bug: 376553318 Change-Id: Ibf8a2d32ec3eae73cfb279dde2a0c74e4b4c5b33 Merged-In: Ibf8a2d32ec3eae73cfb279dde2a0c74e4b4c5b33 (cherry picked from commit 75fda3f4e8ba14107aef9152ed4c7693ccff422d) --- core/api/current.txt | 1 + core/api/module-lib-current.txt | 23 ++++ core/java/android/app/SystemServiceRegistry.java | 4 +- .../ConnectivityFrameworkInitializerBaklava.java | 116 +++++++++++++++++++++ .../android/net/vcn/VcnFrameworkInitializer.java | 106 ------------------- .../net/vcn/VcnGatewayConnectionConfig.java | 19 +++- core/java/android/net/vcn/VcnTransportInfo.java | 100 +++++++++++++++--- 7 files changed, 242 insertions(+), 127 deletions(-) create mode 100644 core/java/android/net/ConnectivityFrameworkInitializerBaklava.java delete mode 100644 core/java/android/net/vcn/VcnFrameworkInitializer.java diff --git a/core/api/current.txt b/core/api/current.txt index f1db5eaa076f..b918d96b424d 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -29564,6 +29564,7 @@ package android.net.vcn { method @NonNull public java.util.List getVcnUnderlyingNetworkPriorities(); method public boolean hasGatewayOption(int); method @FlaggedApi("android.net.vcn.safe_mode_config") public boolean isSafeModeEnabled(); + field @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public static final int MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET = -1; // 0xffffffff field public static final int VCN_GATEWAY_OPTION_ENABLE_DATA_STALL_RECOVERY_WITH_MOBILITY = 0; // 0x0 } diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index ae9f1faa288e..c5a7be313125 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -260,6 +260,10 @@ package android.media.session { package android.net { + @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public final class ConnectivityFrameworkInitializerBaklava { + method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public static void registerServiceWrappers(); + } + public class LocalSocket implements java.io.Closeable { ctor public LocalSocket(@NonNull java.io.FileDescriptor); } @@ -319,6 +323,25 @@ package android.net.netstats { } +package android.net.vcn { + + @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public final class VcnTransportInfo implements android.os.Parcelable android.net.TransportInfo { + method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public int describeContents(); + method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public long getApplicableRedactions(); + method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public int getMinUdpPort4500NatTimeoutSeconds(); + method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") @NonNull public android.net.TransportInfo makeCopy(long); + method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public void writeToParcel(@NonNull android.os.Parcel, int); + field @FlaggedApi("android.net.vcn.mainline_vcn_module_api") @NonNull public static final android.os.Parcelable.Creator CREATOR; + } + + @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public static final class VcnTransportInfo.Builder { + ctor @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public VcnTransportInfo.Builder(); + method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") @NonNull public android.net.vcn.VcnTransportInfo build(); + method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") @NonNull public android.net.vcn.VcnTransportInfo.Builder setMinUdpPort4500NatTimeoutSeconds(@IntRange(from=0x78) int); + } + +} + package android.net.wifi { public final class WifiMigration { diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index d3d1477d3ffd..8f84ee879b1a 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -158,6 +158,7 @@ import android.media.tv.tunerresourcemanager.ITunerResourceManager; import android.media.tv.tunerresourcemanager.TunerResourceManager; import android.nearby.NearbyFrameworkInitializer; import android.net.ConnectivityFrameworkInitializer; +import android.net.ConnectivityFrameworkInitializerBaklava; import android.net.ConnectivityFrameworkInitializerTiramisu; import android.net.INetworkPolicyManager; import android.net.IPacProxyManager; @@ -168,7 +169,6 @@ import android.net.NetworkWatchlistManager; import android.net.PacProxyManager; import android.net.TetheringManager; import android.net.VpnManager; -import android.net.vcn.VcnFrameworkInitializer; import android.net.wifi.WifiFrameworkInitializer; import android.net.wifi.nl80211.WifiNl80211Manager; import android.net.wifi.sharedconnectivity.app.SharedConnectivityManager; @@ -1754,7 +1754,7 @@ public final class SystemServiceRegistry { OnDevicePersonalizationFrameworkInitializer.registerServiceWrappers(); DeviceLockFrameworkInitializer.registerServiceWrappers(); VirtualizationFrameworkInitializer.registerServiceWrappers(); - VcnFrameworkInitializer.registerServiceWrappers(); + ConnectivityFrameworkInitializerBaklava.registerServiceWrappers(); if (com.android.server.telecom.flags.Flags.telecomMainlineBlockedNumbersManager()) { ProviderFrameworkInitializer.registerServiceWrappers(); diff --git a/core/java/android/net/ConnectivityFrameworkInitializerBaklava.java b/core/java/android/net/ConnectivityFrameworkInitializerBaklava.java new file mode 100644 index 000000000000..1f0fa92d7976 --- /dev/null +++ b/core/java/android/net/ConnectivityFrameworkInitializerBaklava.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net; + +import static android.net.vcn.Flags.FLAG_MAINLINE_VCN_MODULE_API; + +import android.annotation.FlaggedApi; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.app.SystemServiceRegistry; +import android.compat.Compatibility; +import android.compat.annotation.ChangeId; +import android.compat.annotation.EnabledSince; +import android.content.Context; +import android.content.pm.PackageManager; +import android.net.vcn.IVcnManagementService; +import android.net.vcn.VcnManager; +import android.os.Build; +import android.os.SystemProperties; + +/** + * Class for performing registration for VCN service. + * + * @hide + */ +@FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) +@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) +public final class ConnectivityFrameworkInitializerBaklava { + /** + * Starting with {@link VANILLA_ICE_CREAM}, Telephony feature flags (e.g. {@link + * PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}) are being checked before returning managers + * that depend on them. If the feature is missing, {@link Context#getSystemService} will return + * null. + * + *

This change is specific to VcnManager. + */ + @ChangeId + @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM) + private static final long ENABLE_CHECKING_TELEPHONY_FEATURES_FOR_VCN = 330902016; + + /** + * The corresponding vendor API for Android V + * + *

Starting with Android V, the vendor API format has switched to YYYYMM. + * + * @see Vendor API + * level + */ + private static final int VENDOR_API_FOR_ANDROID_V = 202404; + + private ConnectivityFrameworkInitializerBaklava() {} + + // Suppressing AndroidFrameworkCompatChange because we're querying vendor + // partition SDK level, not application's target SDK version (which BTW we + // also check through Compatibility framework a few lines below). + @Nullable + private static String getVcnFeatureDependency() { + // Check SDK version of the client app. Apps targeting pre-V SDK might + // have not checked for existence of these features. + if (!Compatibility.isChangeEnabled(ENABLE_CHECKING_TELEPHONY_FEATURES_FOR_VCN)) { + return null; + } + + // Check SDK version of the vendor partition. Pre-V devices might have + // incorrectly under-declared telephony features. + final int vendorApiLevel = + SystemProperties.getInt( + "ro.vendor.api_level", Build.VERSION.DEVICE_INITIAL_SDK_INT); + if (vendorApiLevel < VENDOR_API_FOR_ANDROID_V) { + return PackageManager.FEATURE_TELEPHONY; + } else { + return PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION; + } + } + + /** + * Register VCN service to {@link Context}, so that {@link Context#getSystemService} can return + * a VcnManager. + * + * @throws IllegalStateException if this is called anywhere besides {@link + * SystemServiceRegistry}. + * @hide + */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public static void registerServiceWrappers() { + SystemServiceRegistry.registerContextAwareService( + VcnManager.VCN_MANAGEMENT_SERVICE_STRING, + VcnManager.class, + (context, serviceBinder) -> { + final String telephonyFeatureToCheck = getVcnFeatureDependency(); + if (telephonyFeatureToCheck != null + && !context.getPackageManager() + .hasSystemFeature(telephonyFeatureToCheck)) { + return null; + } + IVcnManagementService service = + IVcnManagementService.Stub.asInterface(serviceBinder); + return new VcnManager(context, service); + }); + } +} diff --git a/core/java/android/net/vcn/VcnFrameworkInitializer.java b/core/java/android/net/vcn/VcnFrameworkInitializer.java deleted file mode 100644 index 8cb213b306be..000000000000 --- a/core/java/android/net/vcn/VcnFrameworkInitializer.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.vcn; - -import android.annotation.Nullable; -import android.app.SystemServiceRegistry; -import android.compat.Compatibility; -import android.compat.annotation.ChangeId; -import android.compat.annotation.EnabledSince; -import android.content.Context; -import android.content.pm.PackageManager; -import android.os.Build; -import android.os.SystemProperties; - -/** - * Class for performing registration for VCN service. - * - * @hide - */ -// TODO: Expose it as @SystemApi(client = MODULE_LIBRARIES) -public final class VcnFrameworkInitializer { - /** - * Starting with {@link VANILLA_ICE_CREAM}, Telephony feature flags (e.g. {@link - * PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}) are being checked before returning managers - * that depend on them. If the feature is missing, {@link Context#getSystemService} will return - * null. - * - *

This change is specific to VcnManager. - */ - @ChangeId - @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM) - private static final long ENABLE_CHECKING_TELEPHONY_FEATURES_FOR_VCN = 330902016; - - /** - * The corresponding vendor API for Android V - * - *

Starting with Android V, the vendor API format has switched to YYYYMM. - * - * @see Vendor API - * level - */ - private static final int VENDOR_API_FOR_ANDROID_V = 202404; - - private VcnFrameworkInitializer() {} - - // Suppressing AndroidFrameworkCompatChange because we're querying vendor - // partition SDK level, not application's target SDK version (which BTW we - // also check through Compatibility framework a few lines below). - @Nullable - private static String getVcnFeatureDependency() { - // Check SDK version of the client app. Apps targeting pre-V SDK might - // have not checked for existence of these features. - if (!Compatibility.isChangeEnabled(ENABLE_CHECKING_TELEPHONY_FEATURES_FOR_VCN)) { - return null; - } - - // Check SDK version of the vendor partition. Pre-V devices might have - // incorrectly under-declared telephony features. - final int vendorApiLevel = - SystemProperties.getInt( - "ro.vendor.api_level", Build.VERSION.DEVICE_INITIAL_SDK_INT); - if (vendorApiLevel < VENDOR_API_FOR_ANDROID_V) { - return PackageManager.FEATURE_TELEPHONY; - } else { - return PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION; - } - } - - /** - * Register VCN service to {@link Context}, so that {@link Context#getSystemService} can return - * a VcnManager. - * - * @throws IllegalStateException if this is called anywhere besides {@link - * SystemServiceRegistry}. - */ - public static void registerServiceWrappers() { - SystemServiceRegistry.registerContextAwareService( - VcnManager.VCN_MANAGEMENT_SERVICE_STRING, - VcnManager.class, - (context, serviceBinder) -> { - final String telephonyFeatureToCheck = getVcnFeatureDependency(); - if (telephonyFeatureToCheck != null - && !context.getPackageManager() - .hasSystemFeature(telephonyFeatureToCheck)) { - return null; - } - IVcnManagementService service = - IVcnManagementService.Stub.asInterface(serviceBinder); - return new VcnManager(context, service); - }); - } -} diff --git a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java index af93c964a8ba..3219ce81c256 100644 --- a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java +++ b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java @@ -16,6 +16,7 @@ package android.net.vcn; import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_MOBIKE; +import static android.net.vcn.Flags.FLAG_MAINLINE_VCN_MODULE_API; import static android.net.vcn.Flags.FLAG_SAFE_MODE_CONFIG; import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_REQUIRED; @@ -82,7 +83,15 @@ import java.util.concurrent.TimeUnit; * */ public final class VcnGatewayConnectionConfig { - /** @hide */ + /** + * Minimum NAT timeout not set. + * + *

When the timeout is not set, the device will automatically choose a keepalive interval and + * may reduce the keepalive frequency for power-optimization. + */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + // This constant does not represent a minimum value. It indicates the value is not configured. + @SuppressLint("MinMaxConstant") public static final int MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET = -1; /** @hide */ @@ -773,7 +782,7 @@ public final class VcnGatewayConnectionConfig { * * @param minUdpPort4500NatTimeoutSeconds the maximum keepalive timeout supported by the VCN * Gateway Connection, generally the minimum duration a NAT mapping is cached on the VCN - * Gateway. + * Gateway; or {@link MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET} to clear this value. * @return this {@link Builder} instance, for chaining */ @NonNull @@ -781,8 +790,10 @@ public final class VcnGatewayConnectionConfig { @IntRange(from = MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS) int minUdpPort4500NatTimeoutSeconds) { Preconditions.checkArgument( - minUdpPort4500NatTimeoutSeconds >= MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS, - "Timeout must be at least 120s"); + minUdpPort4500NatTimeoutSeconds == MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET + || minUdpPort4500NatTimeoutSeconds + >= MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS, + "Timeout must be at least 120s or MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET"); mMinUdpPort4500NatTimeoutSeconds = minUdpPort4500NatTimeoutSeconds; return this; diff --git a/core/java/android/net/vcn/VcnTransportInfo.java b/core/java/android/net/vcn/VcnTransportInfo.java index 1fc91eea3138..3638429f33fb 100644 --- a/core/java/android/net/vcn/VcnTransportInfo.java +++ b/core/java/android/net/vcn/VcnTransportInfo.java @@ -17,13 +17,16 @@ package android.net.vcn; import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; +import static android.net.vcn.Flags.FLAG_MAINLINE_VCN_MODULE_API; import static android.net.vcn.VcnGatewayConnectionConfig.MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS; import static android.net.vcn.VcnGatewayConnectionConfig.MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; +import android.annotation.FlaggedApi; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.net.NetworkCapabilities; import android.net.TransportInfo; import android.net.wifi.WifiInfo; @@ -52,23 +55,29 @@ import java.util.Objects; * @hide */ // TODO: Do not store WifiInfo and subscription ID in VcnTransportInfo anymore -public class VcnTransportInfo implements TransportInfo, Parcelable { +@FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) +@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) +public final class VcnTransportInfo implements TransportInfo, Parcelable { @Nullable private final WifiInfo mWifiInfo; private final int mSubId; private final int mMinUdpPort4500NatTimeoutSeconds; + /** @hide */ public VcnTransportInfo(@NonNull WifiInfo wifiInfo) { this(wifiInfo, INVALID_SUBSCRIPTION_ID, MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET); } + /** @hide */ public VcnTransportInfo(@NonNull WifiInfo wifiInfo, int minUdpPort4500NatTimeoutSeconds) { this(wifiInfo, INVALID_SUBSCRIPTION_ID, minUdpPort4500NatTimeoutSeconds); } + /** @hide */ public VcnTransportInfo(int subId) { this(null /* wifiInfo */, subId, MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET); } + /** @hide */ public VcnTransportInfo(int subId, int minUdpPort4500NatTimeoutSeconds) { this(null /* wifiInfo */, subId, minUdpPort4500NatTimeoutSeconds); } @@ -86,6 +95,7 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { *

If the underlying Network for the associated VCN is Cellular, returns null. * * @return the WifiInfo if there is an underlying WiFi connection, else null. + * @hide */ @Nullable public WifiInfo getWifiInfo() { @@ -100,17 +110,27 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { * * @return the Subscription ID if a cellular underlying Network is present, else {@link * android.telephony.SubscriptionManager#INVALID_SUBSCRIPTION_ID}. + * @hide */ public int getSubId() { return mSubId; } /** - * Get the VCN provided UDP port 4500 NAT timeout + * Get the minimum duration that the VCN Gateway guarantees to preserve a NAT mapping. * - * @return the UDP 4500 NAT timeout, or + *

To ensure uninterrupted connectivity, the device must send keepalive packets before the + * timeout. Failure to do so may result in the mapping being cleared and connection termination. + * This value is used as a power-optimization hint for other IKEv2/IPsec use cases (e.g. VPNs, + * or IWLAN) to reduce the necessary keepalive frequency, thus conserving power and data. + * + * @return the minimum duration that the VCN Gateway guarantees to preserve a NAT mapping, or * VcnGatewayConnectionConfig.MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET if not set. + * @see VcnGatewayConnectionConfig.Builder#setMinUdpPort4500NatTimeoutSeconds(int) + * @hide */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public int getMinUdpPort4500NatTimeoutSeconds() { return mMinUdpPort4500NatTimeoutSeconds; } @@ -129,12 +149,21 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { && mMinUdpPort4500NatTimeoutSeconds == that.mMinUdpPort4500NatTimeoutSeconds; } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + * + * @hide + */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @Override public int describeContents() { return 0; } + /** @hide */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @Override @NonNull public TransportInfo makeCopy(long redactions) { @@ -149,6 +178,9 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { mMinUdpPort4500NatTimeoutSeconds); } + /** @hide */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @Override public long getApplicableRedactions() { long redactions = REDACT_FOR_NETWORK_SETTINGS; @@ -161,7 +193,13 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { return redactions; } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + * + * @hide + */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mSubId); @@ -174,7 +212,13 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { return "VcnTransportInfo { mWifiInfo = " + mWifiInfo + ", mSubId = " + mSubId + " }"; } - /** Implement the Parcelable interface */ + /** + * Implement the Parcelable interface + * + * @hide + */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final @NonNull Creator CREATOR = new Creator() { public VcnTransportInfo createFromParcel(Parcel in) { @@ -201,37 +245,63 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { } }; - /** This class can be used to construct a {@link VcnTransportInfo}. */ + /** + * This class can be used to construct a {@link VcnTransportInfo}. + * + * @hide + */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final class Builder { private int mMinUdpPort4500NatTimeoutSeconds = MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET; - /** Construct Builder */ + /** + * Construct Builder + * + * @hide + */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public Builder() {} /** - * Sets the maximum supported IKEv2/IPsec NATT keepalive timeout. + * Set the minimum duration that the VCN Gateway guarantees to preserve a NAT mapping. * *

This is used as a power-optimization hint for other IKEv2/IPsec use cases (e.g. VPNs, * or IWLAN) to reduce the necessary keepalive frequency, thus conserving power and data. * - * @param minUdpPort4500NatTimeoutSeconds the maximum keepalive timeout supported by the VCN - * Gateway Connection, generally the minimum duration a NAT mapping is cached on the VCN - * Gateway. + * @param minUdpPort4500NatTimeoutSeconds the minimum duration that the VCN Gateway + * guarantees to preserve a NAT mapping, or {@link MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET} + * to clear this value. To ensure uninterrupted connectivity, the device must send + * keepalive packets within this interval. Failure to do so may result in the mapping + * being cleared and connection termination. * @return this {@link Builder} instance, for chaining + * @see VcnGatewayConnectionConfig.Builder#setMinUdpPort4500NatTimeoutSeconds(int) + * @hide */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @NonNull public Builder setMinUdpPort4500NatTimeoutSeconds( @IntRange(from = MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS) int minUdpPort4500NatTimeoutSeconds) { Preconditions.checkArgument( - minUdpPort4500NatTimeoutSeconds >= MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS, - "Timeout must be at least 120s"); + minUdpPort4500NatTimeoutSeconds == MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET + || minUdpPort4500NatTimeoutSeconds + >= MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS, + "Timeout must be at least 120s or MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET"); mMinUdpPort4500NatTimeoutSeconds = minUdpPort4500NatTimeoutSeconds; return Builder.this; } - /** Build a VcnTransportInfo instance */ + /** + * Build a VcnTransportInfo instance + * + * @hide + */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @NonNull public VcnTransportInfo build() { return new VcnTransportInfo( -- cgit v1.2.3-59-g8ed1b