Merge changes from topic "gateway-connection-id"

* changes:
  Expose API for identifying GatewayConnections.
  Update identification for onGatewayConnectionError().
This commit is contained in:
Cody Kesting
2021-04-01 18:27:28 +00:00
committed by Gerrit Code Review
13 changed files with 123 additions and 36 deletions

View File

@@ -25703,12 +25703,13 @@ package android.net.vcn {
public final class VcnGatewayConnectionConfig {
method @NonNull public int[] getExposedCapabilities();
method @NonNull public String getGatewayConnectionName();
method @IntRange(from=android.net.vcn.VcnGatewayConnectionConfig.MIN_MTU_V6) public int getMaxMtu();
method @NonNull public long[] getRetryInterval();
}
public static final class VcnGatewayConnectionConfig.Builder {
ctor public VcnGatewayConnectionConfig.Builder(@NonNull android.net.vcn.VcnControlPlaneConfig);
ctor public VcnGatewayConnectionConfig.Builder(@NonNull String, @NonNull android.net.vcn.VcnControlPlaneConfig);
method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder addExposedCapability(int);
method @NonNull public android.net.vcn.VcnGatewayConnectionConfig build();
method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder removeExposedCapability(int);
@@ -25732,7 +25733,7 @@ package android.net.vcn {
public abstract static class VcnManager.VcnStatusCallback {
ctor public VcnManager.VcnStatusCallback();
method public abstract void onGatewayConnectionError(@NonNull int[], int, @Nullable Throwable);
method public abstract void onGatewayConnectionError(@NonNull String, int, @Nullable Throwable);
method public abstract void onStatusChanged(int);
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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(
@@ -241,6 +247,20 @@ 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
*/
@NonNull
public String getGatewayConnectionName() {
return mGatewayConnectionName;
}
/**
* Returns control plane configuration.
*
@@ -364,6 +384,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 +397,7 @@ public final class VcnGatewayConnectionConfig {
@Override
public int hashCode() {
return Objects.hash(
mGatewayConnectionName,
mExposedCapabilities,
mUnderlyingCapabilities,
Arrays.hashCode(mRetryIntervalsMs),
@@ -389,7 +411,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 +422,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();
@@ -412,12 +436,22 @@ public final class VcnGatewayConnectionConfig {
/**
* 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
*/
public Builder(@NonNull VcnControlPlaneConfig ctrlPlaneConfig) {
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 +596,7 @@ public final class VcnGatewayConnectionConfig {
@NonNull
public VcnGatewayConnectionConfig build() {
return new VcnGatewayConnectionConfig(
mGatewayConnectionName,
mCtrlPlaneConfig,
mExposedCapabilities,
mUnderlyingCapabilities,

View File

@@ -445,18 +445,16 @@ public class VcnManager {
* Invoked when a VCN Gateway Connection corresponding to this callback's subscription group
* encounters an error.
*
* @param networkCapabilities an array of NetworkCapabilities.NET_CAPABILITY_* capabilities
* for the Gateway Connection that encountered the error, for identification purposes.
* These will be a sorted list with no duplicates and will match {@link
* VcnGatewayConnectionConfig#getExposedCapabilities()} for one of the {@link
* VcnGatewayConnectionConfig}s set in the {@link VcnConfig} for this subscription
* group.
* @param gatewayConnectionName the String GatewayConnection name for the GatewayConnection
* encountering an error. This will match the name for exactly one {@link
* VcnGatewayConnectionConfig} for the {@link VcnConfig} configured for this callback's
* subscription group
* @param errorCode the code to indicate the error that occurred
* @param detail Throwable to provide additional information about the error, or {@code
* null} if none
*/
public abstract void onGatewayConnectionError(
@NonNull int[] networkCapabilities,
@NonNull String gatewayConnectionName,
@VcnErrorCode int errorCode,
@Nullable Throwable detail);
}
@@ -586,7 +584,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 +595,7 @@ public class VcnManager {
mExecutor.execute(
() ->
mCallback.onGatewayConnectionError(
networkCapabilities, errorCode, cause)));
gatewayConnectionName, errorCode, cause)));
}
private static Throwable createThrowableByClassName(

View File

@@ -931,7 +931,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);
@@ -960,7 +960,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) {
@@ -976,7 +976,7 @@ public class VcnManagementService extends IVcnManagementService.Stub {
Binder.withCleanCallingIdentity(
() ->
cbInfo.mCallback.onGatewayConnectionError(
networkCapabilities,
gatewayConnectionName,
errorCode,
exceptionClass,
exceptionMessage));

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -78,6 +78,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);

View File

@@ -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
@@ -86,10 +94,24 @@ public class VcnGatewayConnectionConfigTest {
return builder.build();
}
@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);

View File

@@ -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),
eq(GATEWAY_CONNECTION_NAME),
eq(VcnManager.VCN_ERROR_CODE_NETWORK_ERROR),
any(UnknownHostException.class));
}

View File

@@ -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

View File

@@ -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();