diff options
| author | 2021-03-12 18:29:19 -0800 | |
|---|---|---|
| committer | 2021-03-31 14:22:54 -0700 | |
| commit | 52265aab7657baa38c43efb6f130dae318a3587c (patch) | |
| tree | 848c4fbb41018343726d6d341ee6891f3363e65d | |
| parent | 01a61615d84cc4c80f78f9bc78308c9a39b9f656 (diff) | |
Update identification for onGatewayConnectionError().
This CL updates the identification method for
VcnStatusCallback#onGatewayConnectionErrror. Previously,
GatewayConnections were identified by an int[] specifying the
GatewayConnection's exposed NetworkCapabilities. Following API Council
feedback, this is updated to identify GatewayConnections by a
caller-provided String set in the VcnGatewayConnectionConfig.Builder.
Bug: 182345902
Bug: 180522464
Test: atest FrameworksVcnTests
Change-Id: I933c2330edb9bfc1b6bb62276debac02460e24f8
12 files changed, 126 insertions, 26 deletions
diff --git a/core/java/android/net/vcn/IVcnStatusCallback.aidl b/core/java/android/net/vcn/IVcnStatusCallback.aidl index 236ae8bb11b2..11bc443c9dd6 100644 --- a/core/java/android/net/vcn/IVcnStatusCallback.aidl +++ b/core/java/android/net/vcn/IVcnStatusCallback.aidl @@ -20,7 +20,7 @@ package android.net.vcn; oneway interface IVcnStatusCallback { void onVcnStatusChanged(int statusCode); void onGatewayConnectionError( - in int[] gatewayNetworkCapabilities, + in String gatewayConnectionName, int errorCode, in String exceptionClass, in String exceptionMessage); diff --git a/core/java/android/net/vcn/VcnConfig.java b/core/java/android/net/vcn/VcnConfig.java index 52cc2182b094..d41c0b4fbdb3 100644 --- a/core/java/android/net/vcn/VcnConfig.java +++ b/core/java/android/net/vcn/VcnConfig.java @@ -183,12 +183,25 @@ public final class VcnConfig implements Parcelable { * * @param gatewayConnectionConfig the configuration for an individual gateway connection * @return this {@link Builder} instance, for chaining + * @throws IllegalArgumentException if a VcnGatewayConnectionConfig has already been set for + * this {@link VcnConfig} with the same GatewayConnection name (as returned via {@link + * VcnGatewayConnectionConfig#getGatewayConnectionName()}). */ @NonNull public Builder addGatewayConnectionConfig( @NonNull VcnGatewayConnectionConfig gatewayConnectionConfig) { Objects.requireNonNull(gatewayConnectionConfig, "gatewayConnectionConfig was null"); + for (final VcnGatewayConnectionConfig vcnGatewayConnectionConfig : + mGatewayConnectionConfigs) { + if (vcnGatewayConnectionConfig + .getGatewayConnectionName() + .equals(gatewayConnectionConfig.getGatewayConnectionName())) { + throw new IllegalArgumentException( + "GatewayConnection for specified name already exists"); + } + } + mGatewayConnectionConfigs.add(gatewayConnectionConfig); return this; } diff --git a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java index d4e8e2dca296..ae52cc45a986 100644 --- a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java +++ b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java @@ -148,6 +148,8 @@ public final class VcnGatewayConnectionConfig { TimeUnit.MINUTES.toMillis(5), TimeUnit.MINUTES.toMillis(15) }; + private static final String GATEWAY_CONNECTION_NAME_KEY = "mGatewayConnectionName"; + @NonNull private final String mGatewayConnectionName; private static final String CTRL_PLANE_CONFIG_KEY = "mCtrlPlaneConfig"; @NonNull private VcnControlPlaneConfig mCtrlPlaneConfig; @@ -166,11 +168,13 @@ public final class VcnGatewayConnectionConfig { /** Builds a VcnGatewayConnectionConfig with the specified parameters. */ private VcnGatewayConnectionConfig( + @NonNull String gatewayConnectionName, @NonNull VcnControlPlaneConfig ctrlPlaneConfig, @NonNull Set<Integer> exposedCapabilities, @NonNull Set<Integer> underlyingCapabilities, @NonNull long[] retryIntervalsMs, @IntRange(from = MIN_MTU_V6) int maxMtu) { + mGatewayConnectionName = gatewayConnectionName; mCtrlPlaneConfig = ctrlPlaneConfig; mExposedCapabilities = new TreeSet(exposedCapabilities); mUnderlyingCapabilities = new TreeSet(underlyingCapabilities); @@ -192,6 +196,7 @@ public final class VcnGatewayConnectionConfig { final PersistableBundle underlyingCapsBundle = in.getPersistableBundle(UNDERLYING_CAPABILITIES_KEY); + mGatewayConnectionName = in.getString(GATEWAY_CONNECTION_NAME_KEY); mCtrlPlaneConfig = VcnControlPlaneConfig.fromPersistableBundle(ctrlPlaneConfigBundle); mExposedCapabilities = new TreeSet<>(PersistableBundleUtils.toList( exposedCapsBundle, PersistableBundleUtils.INTEGER_DESERIALIZER)); @@ -204,6 +209,7 @@ public final class VcnGatewayConnectionConfig { } private void validate() { + Objects.requireNonNull(mGatewayConnectionName, "gatewayConnectionName was null"); Objects.requireNonNull(mCtrlPlaneConfig, "control plane config was null"); Preconditions.checkArgument( @@ -242,6 +248,21 @@ public final class VcnGatewayConnectionConfig { } /** + * Returns the configured Gateway Connection name. + * + * <p>This name is used by the configuring apps to distinguish between + * VcnGatewayConnectionConfigs configured on a single {@link VcnConfig}. This will be used as + * the identifier in VcnStatusCallback invocations. + * + * @see VcnManager.VcnStatusCallback#onGatewayConnectionError + * @hide + */ + @NonNull + public String getGatewayConnectionName() { + return mGatewayConnectionName; + } + + /** * Returns control plane configuration. * * @hide @@ -364,6 +385,7 @@ public final class VcnGatewayConnectionConfig { new ArrayList<>(mUnderlyingCapabilities), PersistableBundleUtils.INTEGER_SERIALIZER); + result.putString(GATEWAY_CONNECTION_NAME_KEY, mGatewayConnectionName); result.putPersistableBundle(CTRL_PLANE_CONFIG_KEY, ctrlPlaneConfigBundle); result.putPersistableBundle(EXPOSED_CAPABILITIES_KEY, exposedCapsBundle); result.putPersistableBundle(UNDERLYING_CAPABILITIES_KEY, underlyingCapsBundle); @@ -376,6 +398,7 @@ public final class VcnGatewayConnectionConfig { @Override public int hashCode() { return Objects.hash( + mGatewayConnectionName, mExposedCapabilities, mUnderlyingCapabilities, Arrays.hashCode(mRetryIntervalsMs), @@ -389,7 +412,8 @@ public final class VcnGatewayConnectionConfig { } final VcnGatewayConnectionConfig rhs = (VcnGatewayConnectionConfig) other; - return mExposedCapabilities.equals(rhs.mExposedCapabilities) + return mGatewayConnectionName.equals(rhs.mGatewayConnectionName) + && mExposedCapabilities.equals(rhs.mExposedCapabilities) && mUnderlyingCapabilities.equals(rhs.mUnderlyingCapabilities) && Arrays.equals(mRetryIntervalsMs, rhs.mRetryIntervalsMs) && mMaxMtu == rhs.mMaxMtu; @@ -399,6 +423,7 @@ public final class VcnGatewayConnectionConfig { * This class is used to incrementally build {@link VcnGatewayConnectionConfig} objects. */ public static final class Builder { + @NonNull private final String mGatewayConnectionName; @NonNull private final VcnControlPlaneConfig mCtrlPlaneConfig; @NonNull private final Set<Integer> mExposedCapabilities = new ArraySet(); @NonNull private final Set<Integer> mUnderlyingCapabilities = new ArraySet(); @@ -416,8 +441,29 @@ public final class VcnGatewayConnectionConfig { * @see VcnControlPlaneConfig */ public Builder(@NonNull VcnControlPlaneConfig ctrlPlaneConfig) { + this("" /* gatewayConnectionName */, ctrlPlaneConfig); + } + + /** + * Construct a Builder object. + * + * @param gatewayConnectionName the String GatewayConnection name for this + * VcnGatewayConnectionConfig. Each VcnGatewayConnectionConfig within a {@link + * VcnConfig} must be given a unique name. This name is used by the caller to + * distinguish between VcnGatewayConnectionConfigs configured on a single {@link + * VcnConfig}. This will be used as the identifier in VcnStatusCallback invocations. + * @param ctrlPlaneConfig the control plane configuration + * @see VcnControlPlaneConfig + * @see VcnManager.VcnStatusCallback#onGatewayConnectionError + * @hide + */ + public Builder( + @NonNull String gatewayConnectionName, + @NonNull VcnControlPlaneConfig ctrlPlaneConfig) { + Objects.requireNonNull(gatewayConnectionName, "gatewayConnectionName was null"); Objects.requireNonNull(ctrlPlaneConfig, "ctrlPlaneConfig was null"); + mGatewayConnectionName = gatewayConnectionName; mCtrlPlaneConfig = ctrlPlaneConfig; } @@ -562,6 +608,7 @@ public final class VcnGatewayConnectionConfig { @NonNull public VcnGatewayConnectionConfig build() { return new VcnGatewayConnectionConfig( + mGatewayConnectionName, mCtrlPlaneConfig, mExposedCapabilities, mUnderlyingCapabilities, diff --git a/core/java/android/net/vcn/VcnManager.java b/core/java/android/net/vcn/VcnManager.java index abd41dacdeb6..36be16f57741 100644 --- a/core/java/android/net/vcn/VcnManager.java +++ b/core/java/android/net/vcn/VcnManager.java @@ -586,7 +586,7 @@ public class VcnManager { // TODO(b/180521637): use ServiceSpecificException for safer Exception 'parceling' @Override public void onGatewayConnectionError( - @NonNull int[] networkCapabilities, + @NonNull String gatewayConnectionName, @VcnErrorCode int errorCode, @Nullable String exceptionClass, @Nullable String exceptionMessage) { @@ -597,7 +597,7 @@ public class VcnManager { mExecutor.execute( () -> mCallback.onGatewayConnectionError( - networkCapabilities, errorCode, cause))); + new int[0], errorCode, cause))); } private static Throwable createThrowableByClassName( diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java index 4622e98bbbb2..bb333c78d1f7 100644 --- a/services/core/java/com/android/server/VcnManagementService.java +++ b/services/core/java/com/android/server/VcnManagementService.java @@ -926,7 +926,7 @@ public class VcnManagementService extends IVcnManagementService.Stub { /** Called by a Vcn to signal that an error occurred. */ void onGatewayConnectionError( - @NonNull int[] networkCapabilities, + @NonNull String gatewayConnectionName, @VcnErrorCode int errorCode, @Nullable String exceptionClass, @Nullable String exceptionMessage); @@ -955,7 +955,7 @@ public class VcnManagementService extends IVcnManagementService.Stub { @Override public void onGatewayConnectionError( - @NonNull int[] networkCapabilities, + @NonNull String gatewayConnectionName, @VcnErrorCode int errorCode, @Nullable String exceptionClass, @Nullable String exceptionMessage) { @@ -971,7 +971,7 @@ public class VcnManagementService extends IVcnManagementService.Stub { Binder.withCleanCallingIdentity( () -> cbInfo.mCallback.onGatewayConnectionError( - networkCapabilities, + gatewayConnectionName, errorCode, exceptionClass, exceptionMessage)); diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/services/core/java/com/android/server/vcn/Vcn.java index 89ed956b3aef..c0130da7ddbc 100644 --- a/services/core/java/com/android/server/vcn/Vcn.java +++ b/services/core/java/com/android/server/vcn/Vcn.java @@ -417,7 +417,7 @@ public class Vcn extends Handler { /** Callback by a VcnGatewayConnection to indicate that an error occurred. */ void onGatewayConnectionError( - @NonNull int[] networkCapabilities, + @NonNull String gatewayConnectionName, @VcnErrorCode int errorCode, @Nullable String exceptionClass, @Nullable String exceptionMessage); @@ -445,12 +445,12 @@ public class Vcn extends Handler { @Override public void onGatewayConnectionError( - @NonNull int[] networkCapabilities, + @NonNull String gatewayConnectionName, @VcnErrorCode int errorCode, @Nullable String exceptionClass, @Nullable String exceptionMessage) { mVcnCallback.onGatewayConnectionError( - networkCapabilities, errorCode, exceptionClass, exceptionMessage); + gatewayConnectionName, errorCode, exceptionClass, exceptionMessage); } } diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java index 9589505ef251..2ba8edd3b1d0 100644 --- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java +++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java @@ -980,7 +980,7 @@ public class VcnGatewayConnection extends StateMachine { // IkeSessionCallback.onClosedExceptionally(), which calls sessionClosed() if (exception != null) { mGatewayStatusCallback.onGatewayConnectionError( - mConnectionConfig.getExposedCapabilities(), + mConnectionConfig.getGatewayConnectionName(), VCN_ERROR_CODE_INTERNAL_ERROR, RuntimeException.class.getName(), "Received " @@ -1017,7 +1017,7 @@ public class VcnGatewayConnection extends StateMachine { } mGatewayStatusCallback.onGatewayConnectionError( - mConnectionConfig.getExposedCapabilities(), + mConnectionConfig.getGatewayConnectionName(), errorCode, exceptionClass, exceptionMessage); diff --git a/tests/vcn/java/android/net/vcn/VcnConfigTest.java b/tests/vcn/java/android/net/vcn/VcnConfigTest.java index c1ef350e5c4a..7ac51b7e3342 100644 --- a/tests/vcn/java/android/net/vcn/VcnConfigTest.java +++ b/tests/vcn/java/android/net/vcn/VcnConfigTest.java @@ -79,6 +79,18 @@ public class VcnConfigTest { } @Test + public void testBuilderRequiresUniqueGatewayConnectionNames() { + final VcnGatewayConnectionConfig config = VcnGatewayConnectionConfigTest.buildTestConfig(); + try { + new VcnConfig.Builder(mContext) + .addGatewayConnectionConfig(config) + .addGatewayConnectionConfig(config); + fail("Expected exception due to duplicate gateway connection name"); + } catch (IllegalArgumentException e) { + } + } + + @Test public void testBuilderAndGetters() { final VcnConfig config = buildTestConfig(mContext); diff --git a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java index 8a0c923d5fb0..4ee4d611e9b0 100644 --- a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java +++ b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java @@ -19,6 +19,7 @@ package android.net.vcn; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.net.NetworkCapabilities; @@ -61,13 +62,20 @@ public class VcnGatewayConnectionConfigTest { public static final VcnControlPlaneConfig CONTROL_PLANE_CONFIG = VcnControlPlaneIkeConfigTest.buildTestConfig(); + public static final String GATEWAY_CONNECTION_NAME_PREFIX = "gatewayConnectionName-"; + private static int sGatewayConnectionConfigCount = 0; + // Public for use in VcnGatewayConnectionTest public static VcnGatewayConnectionConfig buildTestConfig() { return buildTestConfigWithExposedCaps(EXPOSED_CAPS); } private static VcnGatewayConnectionConfig.Builder newBuilder() { - return new VcnGatewayConnectionConfig.Builder(CONTROL_PLANE_CONFIG); + // Append a unique identifier to the name prefix to guarantee that all created + // VcnGatewayConnectionConfigs have a unique name (required by VcnConfig). + return new VcnGatewayConnectionConfig.Builder( + GATEWAY_CONNECTION_NAME_PREFIX + sGatewayConnectionConfigCount++, + CONTROL_PLANE_CONFIG); } // Public for use in VcnGatewayConnectionTest @@ -87,9 +95,23 @@ public class VcnGatewayConnectionConfigTest { } @Test + public void testBuilderRequiresNonNullGatewayConnectionName() { + try { + new VcnGatewayConnectionConfig.Builder( + null /* gatewayConnectionName */, CONTROL_PLANE_CONFIG) + .build(); + + fail("Expected exception due to invalid gateway connection name"); + } catch (NullPointerException e) { + } + } + + @Test public void testBuilderRequiresNonNullControlPlaneConfig() { try { - new VcnGatewayConnectionConfig.Builder(null).build(); + new VcnGatewayConnectionConfig.Builder( + GATEWAY_CONNECTION_NAME_PREFIX, null /* ctrlPlaneConfig */) + .build(); fail("Expected exception due to invalid control plane config"); } catch (NullPointerException e) { @@ -139,6 +161,8 @@ public class VcnGatewayConnectionConfigTest { public void testBuilderAndGetters() { final VcnGatewayConnectionConfig config = buildTestConfig(); + assertTrue(config.getGatewayConnectionName().startsWith(GATEWAY_CONNECTION_NAME_PREFIX)); + int[] exposedCaps = config.getExposedCapabilities(); Arrays.sort(exposedCaps); assertArrayEquals(EXPOSED_CAPS, exposedCaps); diff --git a/tests/vcn/java/android/net/vcn/VcnManagerTest.java b/tests/vcn/java/android/net/vcn/VcnManagerTest.java index 516c206672d2..54cdeb8be58f 100644 --- a/tests/vcn/java/android/net/vcn/VcnManagerTest.java +++ b/tests/vcn/java/android/net/vcn/VcnManagerTest.java @@ -50,9 +50,7 @@ import java.util.concurrent.Executor; public class VcnManagerTest { private static final ParcelUuid SUB_GROUP = new ParcelUuid(new UUID(0, 0)); - private static final int[] UNDERLYING_NETWORK_CAPABILITIES = { - NetworkCapabilities.NET_CAPABILITY_IMS, NetworkCapabilities.NET_CAPABILITY_INTERNET - }; + private static final String GATEWAY_CONNECTION_NAME = "gatewayConnectionName"; private static final Executor INLINE_EXECUTOR = Runnable::run; private IVcnManagementService mMockVcnManagementService; @@ -207,13 +205,13 @@ public class VcnManagerTest { verify(mMockStatusCallback).onStatusChanged(VCN_STATUS_CODE_ACTIVE); cbBinder.onGatewayConnectionError( - UNDERLYING_NETWORK_CAPABILITIES, + GATEWAY_CONNECTION_NAME, VcnManager.VCN_ERROR_CODE_NETWORK_ERROR, UnknownHostException.class.getName(), "exception_message"); verify(mMockStatusCallback) .onGatewayConnectionError( - eq(UNDERLYING_NETWORK_CAPABILITIES), + any(int[].class), eq(VcnManager.VCN_ERROR_CODE_NETWORK_ERROR), any(UnknownHostException.class)); } diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java index ca6448ca9b8c..2fadd44440f3 100644 --- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java +++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java @@ -241,7 +241,7 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection verify(mGatewayStatusCallback) .onGatewayConnectionError( - eq(mConfig.getExposedCapabilities()), + eq(mConfig.getGatewayConnectionName()), eq(VCN_ERROR_CODE_INTERNAL_ERROR), any(), any()); @@ -275,7 +275,10 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection verify(mGatewayStatusCallback) .onGatewayConnectionError( - eq(mConfig.getExposedCapabilities()), eq(expectedErrorType), any(), any()); + eq(mConfig.getGatewayConnectionName()), + eq(expectedErrorType), + any(), + any()); } @Test diff --git a/tests/vcn/java/com/android/server/vcn/VcnTest.java b/tests/vcn/java/com/android/server/vcn/VcnTest.java index c853fc50fdf7..530d8348bfff 100644 --- a/tests/vcn/java/com/android/server/vcn/VcnTest.java +++ b/tests/vcn/java/com/android/server/vcn/VcnTest.java @@ -51,7 +51,9 @@ import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.Set; import java.util.UUID; @@ -274,11 +276,12 @@ public class VcnTest { assertEquals(2, mVcn.getVcnGatewayConnectionConfigMap().size()); // Create VcnConfig with only one VcnGatewayConnectionConfig so a gateway connection is torn - // down - final VcnGatewayConnectionConfig activeConfig = - VcnGatewayConnectionConfigTest.buildTestConfigWithExposedCaps(TEST_CAPS[0]); - final VcnGatewayConnectionConfig removedConfig = - VcnGatewayConnectionConfigTest.buildTestConfigWithExposedCaps(TEST_CAPS[1]); + // down. Reuse existing VcnGatewayConnectionConfig so that the gateway connection name + // matches. + final List<VcnGatewayConnectionConfig> currentConfigs = + new ArrayList<>(mVcn.getVcnGatewayConnectionConfigMap().keySet()); + final VcnGatewayConnectionConfig activeConfig = currentConfigs.get(0); + final VcnGatewayConnectionConfig removedConfig = currentConfigs.get(1); final VcnConfig updatedConfig = new VcnConfig.Builder(mContext).addGatewayConnectionConfig(activeConfig).build(); |