Loading core/java/android/net/vcn/VcnManager.java +15 −0 Original line number Diff line number Diff line Loading @@ -114,6 +114,20 @@ public class VcnManager { public static final String VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY = "vcn_restricted_transports"; /** * Key for number of seconds to wait before entering safe mode * * <p>A VcnGatewayConnection will enter safe mode when it takes over the configured timeout to * enter {@link ConnectedState}. * * <p>Defaults to 30, unless overridden by carrier config * * @hide */ @NonNull public static final String VCN_SAFE_MODE_TIMEOUT_SECONDS_KEY = "vcn_safe_mode_timeout_seconds_key"; /** * Key for maximum number of parallel SAs for tunnel aggregation * Loading @@ -135,6 +149,7 @@ public class VcnManager { VCN_NETWORK_SELECTION_WIFI_ENTRY_RSSI_THRESHOLD_KEY, VCN_NETWORK_SELECTION_WIFI_EXIT_RSSI_THRESHOLD_KEY, VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY, VCN_SAFE_MODE_TIMEOUT_SECONDS_KEY, VCN_TUNNEL_AGGREGATION_SA_COUNT_MAX_KEY, }; Loading core/java/android/net/vcn/flags.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -6,3 +6,10 @@ flag { description: "Feature flag for safe mode configurability" bug: "276358140" } flag { name: "safe_mode_timeout_config" namespace: "vcn" description: "Feature flag for adjustable safe mode timeout" bug: "317406085" } No newline at end of file services/core/java/com/android/server/vcn/VcnContext.java +4 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,10 @@ public class VcnContext { return mFeatureFlags; } public boolean isFlagSafeModeTimeoutConfigEnabled() { return mFeatureFlags.safeModeTimeoutConfig(); } /** * Verifies that the caller is running on the VcnContext Thread. * Loading services/core/java/com/android/server/vcn/VcnGatewayConnection.java +22 −3 Original line number Diff line number Diff line Loading @@ -1242,9 +1242,28 @@ public class VcnGatewayConnection extends StateMachine { createScheduledAlarm( SAFEMODE_TIMEOUT_ALARM, delayedMessage, mVcnContext.isInTestMode() ? TimeUnit.SECONDS.toMillis(SAFEMODE_TIMEOUT_SECONDS_TEST_MODE) : TimeUnit.SECONDS.toMillis(SAFEMODE_TIMEOUT_SECONDS)); getSafeModeTimeoutMs(mVcnContext, mLastSnapshot, mSubscriptionGroup)); } /** Gets the safe mode timeout */ @VisibleForTesting(visibility = Visibility.PRIVATE) public static long getSafeModeTimeoutMs( VcnContext vcnContext, TelephonySubscriptionSnapshot snapshot, ParcelUuid subGrp) { final int defaultSeconds = vcnContext.isInTestMode() ? SAFEMODE_TIMEOUT_SECONDS_TEST_MODE : SAFEMODE_TIMEOUT_SECONDS; final PersistableBundleWrapper carrierConfig = snapshot.getCarrierConfigForSubGrp(subGrp); int resultSeconds = defaultSeconds; if (vcnContext.isFlagSafeModeTimeoutConfigEnabled() && carrierConfig != null) { resultSeconds = carrierConfig.getInt( VcnManager.VCN_SAFE_MODE_TIMEOUT_SECONDS_KEY, defaultSeconds); } return TimeUnit.SECONDS.toMillis(resultSeconds); } private void cancelSafeModeAlarm() { Loading tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java +72 −0 Original line number Diff line number Diff line Loading @@ -27,15 +27,18 @@ import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.net.vcn.VcnGatewayConnectionConfig.VCN_GATEWAY_OPTION_ENABLE_DATA_STALL_RECOVERY_WITH_MOBILITY; import static com.android.server.vcn.VcnGatewayConnection.DUMMY_ADDR; import static com.android.server.vcn.VcnGatewayConnection.SAFEMODE_TIMEOUT_SECONDS; import static com.android.server.vcn.VcnGatewayConnection.VcnChildSessionConfiguration; import static com.android.server.vcn.VcnGatewayConnection.VcnIkeSession; import static com.android.server.vcn.VcnGatewayConnection.VcnNetworkAgent; import static com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.CALLS_REAL_METHODS; Loading @@ -55,6 +58,7 @@ import android.net.NetworkRequest; import android.net.TelephonyNetworkSpecifier; import android.net.vcn.VcnGatewayConnectionConfig; import android.net.vcn.VcnGatewayConnectionConfigTest; import android.net.vcn.VcnManager; import android.net.vcn.VcnTransportInfo; import android.net.wifi.WifiInfo; import android.os.ParcelUuid; Loading @@ -81,6 +85,7 @@ import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; /** Tests for TelephonySubscriptionTracker */ @RunWith(AndroidJUnit4.class) Loading Loading @@ -352,4 +357,71 @@ public class VcnGatewayConnectionTest extends VcnGatewayConnectionTestBase { any(Executor.class), any(ConnectivityDiagnosticsCallback.class)); } private void verifyGetSafeModeTimeoutMs( boolean isInTestMode, boolean isConfigTimeoutSupported, PersistableBundleWrapper carrierConfig, long expectedTimeoutMs) throws Exception { doReturn(isInTestMode).when(mVcnContext).isInTestMode(); doReturn(isConfigTimeoutSupported).when(mVcnContext).isFlagSafeModeTimeoutConfigEnabled(); final TelephonySubscriptionSnapshot snapshot = mock(TelephonySubscriptionSnapshot.class); doReturn(carrierConfig).when(snapshot).getCarrierConfigForSubGrp(TEST_SUB_GRP); final long result = VcnGatewayConnection.getSafeModeTimeoutMs(mVcnContext, snapshot, TEST_SUB_GRP); assertEquals(expectedTimeoutMs, result); } @Test public void testGetSafeModeTimeoutMs_configTimeoutUnsupported() throws Exception { verifyGetSafeModeTimeoutMs( false /* isInTestMode */, false /* isConfigTimeoutSupported */, null /* carrierConfig */, TimeUnit.SECONDS.toMillis(SAFEMODE_TIMEOUT_SECONDS)); } @Test public void testGetSafeModeTimeoutMs_configTimeoutSupported() throws Exception { final int carrierConfigTimeoutSeconds = 20; final PersistableBundleWrapper carrierConfig = mock(PersistableBundleWrapper.class); doReturn(carrierConfigTimeoutSeconds) .when(carrierConfig) .getInt(eq(VcnManager.VCN_SAFE_MODE_TIMEOUT_SECONDS_KEY), anyInt()); verifyGetSafeModeTimeoutMs( false /* isInTestMode */, true /* isConfigTimeoutSupported */, carrierConfig, TimeUnit.SECONDS.toMillis(carrierConfigTimeoutSeconds)); } @Test public void testGetSafeModeTimeoutMs_configTimeoutSupported_carrierConfigNull() throws Exception { verifyGetSafeModeTimeoutMs( false /* isInTestMode */, true /* isConfigTimeoutSupported */, null /* carrierConfig */, TimeUnit.SECONDS.toMillis(SAFEMODE_TIMEOUT_SECONDS)); } @Test public void testGetSafeModeTimeoutMs_configTimeoutOverrideTestModeDefault() throws Exception { final int carrierConfigTimeoutSeconds = 20; final PersistableBundleWrapper carrierConfig = mock(PersistableBundleWrapper.class); doReturn(carrierConfigTimeoutSeconds) .when(carrierConfig) .getInt(eq(VcnManager.VCN_SAFE_MODE_TIMEOUT_SECONDS_KEY), anyInt()); verifyGetSafeModeTimeoutMs( true /* isInTestMode */, true /* isConfigTimeoutSupported */, carrierConfig, TimeUnit.SECONDS.toMillis(carrierConfigTimeoutSeconds)); } } Loading
core/java/android/net/vcn/VcnManager.java +15 −0 Original line number Diff line number Diff line Loading @@ -114,6 +114,20 @@ public class VcnManager { public static final String VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY = "vcn_restricted_transports"; /** * Key for number of seconds to wait before entering safe mode * * <p>A VcnGatewayConnection will enter safe mode when it takes over the configured timeout to * enter {@link ConnectedState}. * * <p>Defaults to 30, unless overridden by carrier config * * @hide */ @NonNull public static final String VCN_SAFE_MODE_TIMEOUT_SECONDS_KEY = "vcn_safe_mode_timeout_seconds_key"; /** * Key for maximum number of parallel SAs for tunnel aggregation * Loading @@ -135,6 +149,7 @@ public class VcnManager { VCN_NETWORK_SELECTION_WIFI_ENTRY_RSSI_THRESHOLD_KEY, VCN_NETWORK_SELECTION_WIFI_EXIT_RSSI_THRESHOLD_KEY, VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY, VCN_SAFE_MODE_TIMEOUT_SECONDS_KEY, VCN_TUNNEL_AGGREGATION_SA_COUNT_MAX_KEY, }; Loading
core/java/android/net/vcn/flags.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -6,3 +6,10 @@ flag { description: "Feature flag for safe mode configurability" bug: "276358140" } flag { name: "safe_mode_timeout_config" namespace: "vcn" description: "Feature flag for adjustable safe mode timeout" bug: "317406085" } No newline at end of file
services/core/java/com/android/server/vcn/VcnContext.java +4 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,10 @@ public class VcnContext { return mFeatureFlags; } public boolean isFlagSafeModeTimeoutConfigEnabled() { return mFeatureFlags.safeModeTimeoutConfig(); } /** * Verifies that the caller is running on the VcnContext Thread. * Loading
services/core/java/com/android/server/vcn/VcnGatewayConnection.java +22 −3 Original line number Diff line number Diff line Loading @@ -1242,9 +1242,28 @@ public class VcnGatewayConnection extends StateMachine { createScheduledAlarm( SAFEMODE_TIMEOUT_ALARM, delayedMessage, mVcnContext.isInTestMode() ? TimeUnit.SECONDS.toMillis(SAFEMODE_TIMEOUT_SECONDS_TEST_MODE) : TimeUnit.SECONDS.toMillis(SAFEMODE_TIMEOUT_SECONDS)); getSafeModeTimeoutMs(mVcnContext, mLastSnapshot, mSubscriptionGroup)); } /** Gets the safe mode timeout */ @VisibleForTesting(visibility = Visibility.PRIVATE) public static long getSafeModeTimeoutMs( VcnContext vcnContext, TelephonySubscriptionSnapshot snapshot, ParcelUuid subGrp) { final int defaultSeconds = vcnContext.isInTestMode() ? SAFEMODE_TIMEOUT_SECONDS_TEST_MODE : SAFEMODE_TIMEOUT_SECONDS; final PersistableBundleWrapper carrierConfig = snapshot.getCarrierConfigForSubGrp(subGrp); int resultSeconds = defaultSeconds; if (vcnContext.isFlagSafeModeTimeoutConfigEnabled() && carrierConfig != null) { resultSeconds = carrierConfig.getInt( VcnManager.VCN_SAFE_MODE_TIMEOUT_SECONDS_KEY, defaultSeconds); } return TimeUnit.SECONDS.toMillis(resultSeconds); } private void cancelSafeModeAlarm() { Loading
tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java +72 −0 Original line number Diff line number Diff line Loading @@ -27,15 +27,18 @@ import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.net.vcn.VcnGatewayConnectionConfig.VCN_GATEWAY_OPTION_ENABLE_DATA_STALL_RECOVERY_WITH_MOBILITY; import static com.android.server.vcn.VcnGatewayConnection.DUMMY_ADDR; import static com.android.server.vcn.VcnGatewayConnection.SAFEMODE_TIMEOUT_SECONDS; import static com.android.server.vcn.VcnGatewayConnection.VcnChildSessionConfiguration; import static com.android.server.vcn.VcnGatewayConnection.VcnIkeSession; import static com.android.server.vcn.VcnGatewayConnection.VcnNetworkAgent; import static com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.CALLS_REAL_METHODS; Loading @@ -55,6 +58,7 @@ import android.net.NetworkRequest; import android.net.TelephonyNetworkSpecifier; import android.net.vcn.VcnGatewayConnectionConfig; import android.net.vcn.VcnGatewayConnectionConfigTest; import android.net.vcn.VcnManager; import android.net.vcn.VcnTransportInfo; import android.net.wifi.WifiInfo; import android.os.ParcelUuid; Loading @@ -81,6 +85,7 @@ import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; /** Tests for TelephonySubscriptionTracker */ @RunWith(AndroidJUnit4.class) Loading Loading @@ -352,4 +357,71 @@ public class VcnGatewayConnectionTest extends VcnGatewayConnectionTestBase { any(Executor.class), any(ConnectivityDiagnosticsCallback.class)); } private void verifyGetSafeModeTimeoutMs( boolean isInTestMode, boolean isConfigTimeoutSupported, PersistableBundleWrapper carrierConfig, long expectedTimeoutMs) throws Exception { doReturn(isInTestMode).when(mVcnContext).isInTestMode(); doReturn(isConfigTimeoutSupported).when(mVcnContext).isFlagSafeModeTimeoutConfigEnabled(); final TelephonySubscriptionSnapshot snapshot = mock(TelephonySubscriptionSnapshot.class); doReturn(carrierConfig).when(snapshot).getCarrierConfigForSubGrp(TEST_SUB_GRP); final long result = VcnGatewayConnection.getSafeModeTimeoutMs(mVcnContext, snapshot, TEST_SUB_GRP); assertEquals(expectedTimeoutMs, result); } @Test public void testGetSafeModeTimeoutMs_configTimeoutUnsupported() throws Exception { verifyGetSafeModeTimeoutMs( false /* isInTestMode */, false /* isConfigTimeoutSupported */, null /* carrierConfig */, TimeUnit.SECONDS.toMillis(SAFEMODE_TIMEOUT_SECONDS)); } @Test public void testGetSafeModeTimeoutMs_configTimeoutSupported() throws Exception { final int carrierConfigTimeoutSeconds = 20; final PersistableBundleWrapper carrierConfig = mock(PersistableBundleWrapper.class); doReturn(carrierConfigTimeoutSeconds) .when(carrierConfig) .getInt(eq(VcnManager.VCN_SAFE_MODE_TIMEOUT_SECONDS_KEY), anyInt()); verifyGetSafeModeTimeoutMs( false /* isInTestMode */, true /* isConfigTimeoutSupported */, carrierConfig, TimeUnit.SECONDS.toMillis(carrierConfigTimeoutSeconds)); } @Test public void testGetSafeModeTimeoutMs_configTimeoutSupported_carrierConfigNull() throws Exception { verifyGetSafeModeTimeoutMs( false /* isInTestMode */, true /* isConfigTimeoutSupported */, null /* carrierConfig */, TimeUnit.SECONDS.toMillis(SAFEMODE_TIMEOUT_SECONDS)); } @Test public void testGetSafeModeTimeoutMs_configTimeoutOverrideTestModeDefault() throws Exception { final int carrierConfigTimeoutSeconds = 20; final PersistableBundleWrapper carrierConfig = mock(PersistableBundleWrapper.class); doReturn(carrierConfigTimeoutSeconds) .when(carrierConfig) .getInt(eq(VcnManager.VCN_SAFE_MODE_TIMEOUT_SECONDS_KEY), anyInt()); verifyGetSafeModeTimeoutMs( true /* isInTestMode */, true /* isConfigTimeoutSupported */, carrierConfig, TimeUnit.SECONDS.toMillis(carrierConfigTimeoutSeconds)); } }