From eae9b5d0c46ff78b00b5346be20b11a9a4f6227f Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Wed, 8 Dec 2021 10:53:20 -0800 Subject: [PATCH] Support parsing VcnGatewayConnectionConfig without UnderlyingNetworkPriorities This commit fixes the NullPointerException issue in converting a PersistableBundle without UnderlyingNetworkPriorities to a VcnGatewayConnectionConfig, by adding a null check and building the VcnGatewayConnectionConfig with the default UnderlyingNetworkPriority list. Bug: 209142575 Test: atest FrameworksVcnTests (new tests), CtsVcnTestCases Change-Id: I888d2994c86ba250c3fc9ee1851dccb5e6ef3e77 --- .../net/vcn/VcnGatewayConnectionConfig.java | 34 ++++++++++++++----- .../vcn/VcnGatewayConnectionConfigTest.java | 13 +++++++ 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java index 0bd146cbc1b4..55d3ecd2c92f 100644 --- a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java +++ b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java @@ -198,7 +198,10 @@ public final class VcnGatewayConnectionConfig { private static final String EXPOSED_CAPABILITIES_KEY = "mExposedCapabilities"; @NonNull private final SortedSet mExposedCapabilities; - private static final String UNDERLYING_NETWORK_PRIORITIES_KEY = "mUnderlyingNetworkPriorities"; + /** @hide */ + @VisibleForTesting(visibility = Visibility.PRIVATE) + public static final String UNDERLYING_NETWORK_PRIORITIES_KEY = "mUnderlyingNetworkPriorities"; + @NonNull private final LinkedHashSet mUnderlyingNetworkPriorities; private static final String MAX_MTU_KEY = "mMaxMtu"; @@ -229,6 +232,8 @@ public final class VcnGatewayConnectionConfig { validate(); } + // Null check MUST be done for all new fields added to VcnGatewayConnectionConfig, to avoid + // crashes when parsing PersistableBundle built on old platforms. /** @hide */ @VisibleForTesting(visibility = Visibility.PRIVATE) public VcnGatewayConnectionConfig(@NonNull PersistableBundle in) { @@ -239,19 +244,30 @@ public final class VcnGatewayConnectionConfig { final PersistableBundle exposedCapsBundle = in.getPersistableBundle(EXPOSED_CAPABILITIES_KEY); - final PersistableBundle networkPrioritiesBundle = - in.getPersistableBundle(UNDERLYING_NETWORK_PRIORITIES_KEY); - mGatewayConnectionName = in.getString(GATEWAY_CONNECTION_NAME_KEY); mTunnelConnectionParams = TunnelConnectionParamsUtils.fromPersistableBundle(tunnelConnectionParamsBundle); mExposedCapabilities = new TreeSet<>(PersistableBundleUtils.toList( exposedCapsBundle, PersistableBundleUtils.INTEGER_DESERIALIZER)); - mUnderlyingNetworkPriorities = - new LinkedHashSet<>( - PersistableBundleUtils.toList( - networkPrioritiesBundle, - VcnUnderlyingNetworkPriority::fromPersistableBundle)); + + final PersistableBundle networkPrioritiesBundle = + in.getPersistableBundle(UNDERLYING_NETWORK_PRIORITIES_KEY); + + if (networkPrioritiesBundle == null) { + // UNDERLYING_NETWORK_PRIORITIES_KEY was added in Android T. Thus + // VcnGatewayConnectionConfig created on old platforms will not have this data and will + // be assigned with the default value + mUnderlyingNetworkPriorities = + new LinkedHashSet<>(DEFAULT_UNDERLYING_NETWORK_PRIORITIES); + + } else { + mUnderlyingNetworkPriorities = + new LinkedHashSet<>( + PersistableBundleUtils.toList( + networkPrioritiesBundle, + VcnUnderlyingNetworkPriority::fromPersistableBundle)); + } + mRetryIntervalsMs = in.getLongArray(RETRY_INTERVAL_MS_KEY); mMaxMtu = in.getInt(MAX_MTU_KEY); diff --git a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java index 18518aac7757..377f526a9825 100644 --- a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java +++ b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java @@ -17,6 +17,8 @@ package android.net.vcn; import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_MOBIKE; +import static android.net.vcn.VcnGatewayConnectionConfig.DEFAULT_UNDERLYING_NETWORK_PRIORITIES; +import static android.net.vcn.VcnGatewayConnectionConfig.UNDERLYING_NETWORK_PRIORITIES_KEY; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -30,6 +32,7 @@ import android.net.ipsec.ike.IkeSessionParams; import android.net.ipsec.ike.IkeTunnelConnectionParams; import android.net.vcn.persistablebundleutils.IkeSessionParamsUtilsTest; import android.net.vcn.persistablebundleutils.TunnelConnectionParamsUtilsTest; +import android.os.PersistableBundle; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -230,6 +233,16 @@ public class VcnGatewayConnectionConfigTest { assertEquals(config, new VcnGatewayConnectionConfig(config.toPersistableBundle())); } + @Test + public void testParsePersistableBundleWithoutVcnUnderlyingNetworkPriorities() { + PersistableBundle configBundle = buildTestConfig().toPersistableBundle(); + configBundle.putPersistableBundle(UNDERLYING_NETWORK_PRIORITIES_KEY, null); + + final VcnGatewayConnectionConfig config = new VcnGatewayConnectionConfig(configBundle); + assertEquals( + DEFAULT_UNDERLYING_NETWORK_PRIORITIES, config.getVcnUnderlyingNetworkPriorities()); + } + private static IkeTunnelConnectionParams buildTunnelConnectionParams(String ikePsk) { final IkeSessionParams ikeParams = IkeSessionParamsUtilsTest.createBuilderMinimum()