diff options
| author | 2021-12-02 19:17:33 +0000 | |
|---|---|---|
| committer | 2021-12-02 19:17:33 +0000 | |
| commit | 8d6d8dcc4fc4f9684b918bc0b75b84a0c99f15b0 (patch) | |
| tree | 905861dc6bd030c926012e4ee09fcbe9fa32ad70 | |
| parent | 51fae209571d48f302e4eb1dc838f5cd51ce6838 (diff) | |
| parent | fee736f47c2ee433926c608ab70f1233960a0099 (diff) | |
Merge changes I5cd2982f,Ia7f44c5f
* changes:
Support configuring VcnUnderlyingNetworkPriority in VcnGatwayConnectionConfig
Create VcnCellUnderlyingNetworkPriority
7 files changed, 507 insertions, 3 deletions
diff --git a/core/java/android/net/vcn/VcnCellUnderlyingNetworkPriority.java b/core/java/android/net/vcn/VcnCellUnderlyingNetworkPriority.java new file mode 100644 index 000000000000..6b33e4f45c42 --- /dev/null +++ b/core/java/android/net/vcn/VcnCellUnderlyingNetworkPriority.java @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2021 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 static com.android.internal.annotations.VisibleForTesting.Visibility; +import static com.android.server.vcn.util.PersistableBundleUtils.INTEGER_DESERIALIZER; +import static com.android.server.vcn.util.PersistableBundleUtils.INTEGER_SERIALIZER; +import static com.android.server.vcn.util.PersistableBundleUtils.STRING_DESERIALIZER; +import static com.android.server.vcn.util.PersistableBundleUtils.STRING_SERIALIZER; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.PersistableBundle; +import android.telephony.SubscriptionInfo; +import android.telephony.TelephonyManager; +import android.util.ArraySet; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.server.vcn.util.PersistableBundleUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Objects; +import java.util.Set; + +// TODO: Add documents +/** @hide */ +public final class VcnCellUnderlyingNetworkPriority extends VcnUnderlyingNetworkPriority { + private static final String ALLOWED_NETWORK_PLMN_IDS_KEY = "mAllowedNetworkPlmnIds"; + @NonNull private final Set<String> mAllowedNetworkPlmnIds; + private static final String ALLOWED_SPECIFIC_CARRIER_IDS_KEY = "mAllowedSpecificCarrierIds"; + @NonNull private final Set<Integer> mAllowedSpecificCarrierIds; + + private static final String ALLOW_ROAMING_KEY = "mAllowRoaming"; + private final boolean mAllowRoaming; + + private static final String REQUIRE_OPPORTUNISTIC_KEY = "mRequireOpportunistic"; + private final boolean mRequireOpportunistic; + + private VcnCellUnderlyingNetworkPriority( + int networkQuality, + boolean allowMetered, + Set<String> allowedNetworkPlmnIds, + Set<Integer> allowedSpecificCarrierIds, + boolean allowRoaming, + boolean requireOpportunistic) { + super(NETWORK_PRIORITY_TYPE_CELL, networkQuality, allowMetered); + mAllowedNetworkPlmnIds = new ArraySet<>(allowedNetworkPlmnIds); + mAllowedSpecificCarrierIds = new ArraySet<>(allowedSpecificCarrierIds); + mAllowRoaming = allowRoaming; + mRequireOpportunistic = requireOpportunistic; + + validate(); + } + + /** @hide */ + @Override + protected void validate() { + super.validate(); + validatePlmnIds(mAllowedNetworkPlmnIds); + Objects.requireNonNull(mAllowedSpecificCarrierIds, "allowedCarrierIds is null"); + } + + private static void validatePlmnIds(Set<String> allowedNetworkPlmnIds) { + Objects.requireNonNull(allowedNetworkPlmnIds, "allowedNetworkPlmnIds is null"); + + // A valid PLMN is a concatenation of MNC and MCC, and thus consists of 5 or 6 decimal + // digits. + for (String id : allowedNetworkPlmnIds) { + if ((id.length() == 5 || id.length() == 6) && id.matches("[0-9]+")) { + continue; + } else { + throw new IllegalArgumentException("Found invalid PLMN ID: " + id); + } + } + } + + /** @hide */ + @NonNull + @VisibleForTesting(visibility = Visibility.PROTECTED) + public static VcnCellUnderlyingNetworkPriority fromPersistableBundle( + @NonNull PersistableBundle in) { + Objects.requireNonNull(in, "PersistableBundle is null"); + + final int networkQuality = in.getInt(NETWORK_QUALITY_KEY); + final boolean allowMetered = in.getBoolean(ALLOW_METERED_KEY); + + final PersistableBundle plmnIdsBundle = + in.getPersistableBundle(ALLOWED_NETWORK_PLMN_IDS_KEY); + Objects.requireNonNull(plmnIdsBundle, "plmnIdsBundle is null"); + final Set<String> allowedNetworkPlmnIds = + new ArraySet<String>( + PersistableBundleUtils.toList(plmnIdsBundle, STRING_DESERIALIZER)); + + final PersistableBundle specificCarrierIdsBundle = + in.getPersistableBundle(ALLOWED_SPECIFIC_CARRIER_IDS_KEY); + Objects.requireNonNull(specificCarrierIdsBundle, "specificCarrierIdsBundle is null"); + final Set<Integer> allowedSpecificCarrierIds = + new ArraySet<Integer>( + PersistableBundleUtils.toList( + specificCarrierIdsBundle, INTEGER_DESERIALIZER)); + + final boolean allowRoaming = in.getBoolean(ALLOW_ROAMING_KEY); + final boolean requireOpportunistic = in.getBoolean(REQUIRE_OPPORTUNISTIC_KEY); + + return new VcnCellUnderlyingNetworkPriority( + networkQuality, + allowMetered, + allowedNetworkPlmnIds, + allowedSpecificCarrierIds, + allowRoaming, + requireOpportunistic); + } + + /** @hide */ + @Override + @NonNull + @VisibleForTesting(visibility = Visibility.PROTECTED) + public PersistableBundle toPersistableBundle() { + final PersistableBundle result = super.toPersistableBundle(); + + final PersistableBundle plmnIdsBundle = + PersistableBundleUtils.fromList( + new ArrayList<>(mAllowedNetworkPlmnIds), STRING_SERIALIZER); + result.putPersistableBundle(ALLOWED_NETWORK_PLMN_IDS_KEY, plmnIdsBundle); + + final PersistableBundle specificCarrierIdsBundle = + PersistableBundleUtils.fromList( + new ArrayList<>(mAllowedSpecificCarrierIds), INTEGER_SERIALIZER); + result.putPersistableBundle(ALLOWED_SPECIFIC_CARRIER_IDS_KEY, specificCarrierIdsBundle); + + result.putBoolean(ALLOW_ROAMING_KEY, mAllowRoaming); + result.putBoolean(REQUIRE_OPPORTUNISTIC_KEY, mRequireOpportunistic); + + return result; + } + + /** Retrieve the allowed PLMN IDs, or an empty set if any PLMN ID is acceptable. */ + @NonNull + public Set<String> getAllowedPlmnIds() { + return Collections.unmodifiableSet(mAllowedNetworkPlmnIds); + } + + /** + * Retrieve the allowed specific carrier IDs, or an empty set if any specific carrier ID is + * acceptable. + */ + @NonNull + public Set<Integer> getAllowedSpecificCarrierIds() { + return Collections.unmodifiableSet(mAllowedSpecificCarrierIds); + } + + /** Return if roaming is allowed. */ + public boolean allowRoaming() { + return mAllowRoaming; + } + + /** Return if requiring an opportunistic network. */ + public boolean requireOpportunistic() { + return mRequireOpportunistic; + } + + @Override + public int hashCode() { + return Objects.hash( + super.hashCode(), + mAllowedNetworkPlmnIds, + mAllowedSpecificCarrierIds, + mAllowRoaming, + mRequireOpportunistic); + } + + @Override + public boolean equals(@Nullable Object other) { + if (!super.equals(other)) { + return false; + } + + if (!(other instanceof VcnCellUnderlyingNetworkPriority)) { + return false; + } + + final VcnCellUnderlyingNetworkPriority rhs = (VcnCellUnderlyingNetworkPriority) other; + return Objects.equals(mAllowedNetworkPlmnIds, rhs.mAllowedNetworkPlmnIds) + && Objects.equals(mAllowedSpecificCarrierIds, rhs.mAllowedSpecificCarrierIds) + && mAllowRoaming == rhs.mAllowRoaming + && mRequireOpportunistic == rhs.mRequireOpportunistic; + } + + /** This class is used to incrementally build WifiNetworkPriority objects. */ + public static class Builder extends VcnUnderlyingNetworkPriority.Builder<Builder> { + @NonNull private final Set<String> mAllowedNetworkPlmnIds = new ArraySet<>(); + @NonNull private final Set<Integer> mAllowedSpecificCarrierIds = new ArraySet<>(); + + private boolean mAllowRoaming = false; + private boolean mRequireOpportunistic = false; + + /** Construct a Builder object. */ + public Builder() {} + + /** + * Set allowed operator PLMN IDs. + * + * <p>This is used to distinguish cases where roaming agreements may dictate a different + * priority from a partner's networks. + * + * @param allowedNetworkPlmnIds the allowed operator PLMN IDs in String. Defaults to an + * empty set, allowing ANY PLMN ID. A valid PLMN is a concatenation of MNC and MCC, and + * thus consists of 5 or 6 decimal digits. See {@link SubscriptionInfo#getMccString()} + * and {@link SubscriptionInfo#getMncString()}. + */ + @NonNull + public Builder setAllowedPlmnIds(@NonNull Set<String> allowedNetworkPlmnIds) { + validatePlmnIds(allowedNetworkPlmnIds); + + mAllowedNetworkPlmnIds.clear(); + mAllowedNetworkPlmnIds.addAll(allowedNetworkPlmnIds); + return this; + } + + /** + * Set allowed specific carrier IDs. + * + * @param allowedSpecificCarrierIds the allowed specific carrier IDs. Defaults to an empty + * set, allowing ANY carrier ID. See {@link TelephonyManager#getSimSpecificCarrierId()}. + */ + @NonNull + public Builder setAllowedSpecificCarrierIds( + @NonNull Set<Integer> allowedSpecificCarrierIds) { + Objects.requireNonNull(allowedSpecificCarrierIds, "allowedCarrierIds is null"); + mAllowedSpecificCarrierIds.clear(); + mAllowedSpecificCarrierIds.addAll(allowedSpecificCarrierIds); + return this; + } + + /** + * Set if roaming is allowed. + * + * @param allowRoaming the flag to indicate if roaming is allowed. Defaults to {@code + * false}. + */ + @NonNull + public Builder setAllowRoaming(boolean allowRoaming) { + mAllowRoaming = allowRoaming; + return this; + } + + /** + * Set if requiring an opportunistic network. + * + * @param requireOpportunistic the flag to indicate if caller requires an opportunistic + * network. Defaults to {@code false}. + */ + @NonNull + public Builder setRequireOpportunistic(boolean requireOpportunistic) { + mRequireOpportunistic = requireOpportunistic; + return this; + } + + /** Build the VcnCellUnderlyingNetworkPriority. */ + @NonNull + public VcnCellUnderlyingNetworkPriority build() { + return new VcnCellUnderlyingNetworkPriority( + mNetworkQuality, + mAllowMetered, + mAllowedNetworkPlmnIds, + mAllowedSpecificCarrierIds, + mAllowRoaming, + mRequireOpportunistic); + } + + /** @hide */ + @Override + Builder self() { + return this; + } + } +} diff --git a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java index 752ef3e39ab6..de4ada2dbc26 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.VcnUnderlyingNetworkPriority.NETWORK_QUALITY_OK; import static com.android.internal.annotations.VisibleForTesting.Visibility; @@ -41,6 +42,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.LinkedHashSet; import java.util.Objects; import java.util.Set; import java.util.SortedSet; @@ -157,6 +159,34 @@ public final class VcnGatewayConnectionConfig { TimeUnit.MINUTES.toMillis(5), TimeUnit.MINUTES.toMillis(15) }; + + private static final LinkedHashSet<VcnUnderlyingNetworkPriority> + DEFAULT_UNDERLYING_NETWORK_PRIORITIES = new LinkedHashSet<>(); + + static { + DEFAULT_UNDERLYING_NETWORK_PRIORITIES.add( + new VcnCellUnderlyingNetworkPriority.Builder() + .setNetworkQuality(NETWORK_QUALITY_OK) + .setAllowMetered(true /* allowMetered */) + .setAllowRoaming(true /* allowRoaming */) + .setRequireOpportunistic(true /* requireOpportunistic */) + .build()); + + DEFAULT_UNDERLYING_NETWORK_PRIORITIES.add( + new VcnWifiUnderlyingNetworkPriority.Builder() + .setNetworkQuality(NETWORK_QUALITY_OK) + .setAllowMetered(true /* allowMetered */) + .build()); + + DEFAULT_UNDERLYING_NETWORK_PRIORITIES.add( + new VcnCellUnderlyingNetworkPriority.Builder() + .setNetworkQuality(NETWORK_QUALITY_OK) + .setAllowMetered(true /* allowMetered */) + .setAllowRoaming(true /* allowRoaming */) + .setRequireOpportunistic(false /* requireOpportunistic */) + .build()); + } + private static final String GATEWAY_CONNECTION_NAME_KEY = "mGatewayConnectionName"; @NonNull private final String mGatewayConnectionName; @@ -166,6 +196,9 @@ public final class VcnGatewayConnectionConfig { private static final String EXPOSED_CAPABILITIES_KEY = "mExposedCapabilities"; @NonNull private final SortedSet<Integer> mExposedCapabilities; + private static final String UNDERLYING_NETWORK_PRIORITIES_KEY = "mUnderlyingNetworkPriorities"; + @NonNull private final LinkedHashSet<VcnUnderlyingNetworkPriority> mUnderlyingNetworkPriorities; + private static final String MAX_MTU_KEY = "mMaxMtu"; private final int mMaxMtu; @@ -177,6 +210,7 @@ public final class VcnGatewayConnectionConfig { @NonNull String gatewayConnectionName, @NonNull IkeTunnelConnectionParams tunnelConnectionParams, @NonNull Set<Integer> exposedCapabilities, + @NonNull LinkedHashSet<VcnUnderlyingNetworkPriority> underlyingNetworkPriorities, @NonNull long[] retryIntervalsMs, @IntRange(from = MIN_MTU_V6) int maxMtu) { mGatewayConnectionName = gatewayConnectionName; @@ -185,6 +219,11 @@ public final class VcnGatewayConnectionConfig { mRetryIntervalsMs = retryIntervalsMs; mMaxMtu = maxMtu; + mUnderlyingNetworkPriorities = new LinkedHashSet<>(underlyingNetworkPriorities); + if (mUnderlyingNetworkPriorities.isEmpty()) { + mUnderlyingNetworkPriorities.addAll(DEFAULT_UNDERLYING_NETWORK_PRIORITIES); + } + validate(); } @@ -198,12 +237,19 @@ 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)); mRetryIntervalsMs = in.getLongArray(RETRY_INTERVAL_MS_KEY); mMaxMtu = in.getInt(MAX_MTU_KEY); @@ -221,6 +267,7 @@ public final class VcnGatewayConnectionConfig { checkValidCapability(cap); } + Objects.requireNonNull(mUnderlyingNetworkPriorities, "underlyingNetworkPriorities is null"); Objects.requireNonNull(mRetryIntervalsMs, "retryIntervalsMs was null"); validateRetryInterval(mRetryIntervalsMs); @@ -303,6 +350,18 @@ public final class VcnGatewayConnectionConfig { } /** + * Retrieve the configured VcnUnderlyingNetworkPriority list, or a default list if it is not + * configured. + * + * @see Builder#setVcnUnderlyingNetworkPriorities(LinkedHashSet<VcnUnderlyingNetworkPriority>) + * @hide + */ + @NonNull + public LinkedHashSet<VcnUnderlyingNetworkPriority> getVcnUnderlyingNetworkPriorities() { + return new LinkedHashSet<>(mUnderlyingNetworkPriorities); + } + + /** * Retrieves the configured retry intervals. * * @see Builder#setRetryIntervalsMillis(long[]) @@ -338,10 +397,15 @@ public final class VcnGatewayConnectionConfig { PersistableBundleUtils.fromList( new ArrayList<>(mExposedCapabilities), PersistableBundleUtils.INTEGER_SERIALIZER); + final PersistableBundle networkPrioritiesBundle = + PersistableBundleUtils.fromList( + new ArrayList<>(mUnderlyingNetworkPriorities), + VcnUnderlyingNetworkPriority::toPersistableBundle); result.putString(GATEWAY_CONNECTION_NAME_KEY, mGatewayConnectionName); result.putPersistableBundle(TUNNEL_CONNECTION_PARAMS_KEY, tunnelConnectionParamsBundle); result.putPersistableBundle(EXPOSED_CAPABILITIES_KEY, exposedCapsBundle); + result.putPersistableBundle(UNDERLYING_NETWORK_PRIORITIES_KEY, networkPrioritiesBundle); result.putLongArray(RETRY_INTERVAL_MS_KEY, mRetryIntervalsMs); result.putInt(MAX_MTU_KEY, mMaxMtu); @@ -379,6 +443,11 @@ public final class VcnGatewayConnectionConfig { @NonNull private final String mGatewayConnectionName; @NonNull private final IkeTunnelConnectionParams mTunnelConnectionParams; @NonNull private final Set<Integer> mExposedCapabilities = new ArraySet(); + + @NonNull + private final LinkedHashSet<VcnUnderlyingNetworkPriority> mUnderlyingNetworkPriorities = + new LinkedHashSet<>(DEFAULT_UNDERLYING_NETWORK_PRIORITIES); + @NonNull private long[] mRetryIntervalsMs = DEFAULT_RETRY_INTERVALS_MS; private int mMaxMtu = DEFAULT_MAX_MTU; @@ -450,6 +519,33 @@ public final class VcnGatewayConnectionConfig { } /** + * Set the VcnUnderlyingNetworkPriority list. + * + * @param underlyingNetworkPriorities a list of unique VcnUnderlyingNetworkPriorities that + * are ordered from most to least preferred, or an empty list to use the default + * prioritization. The default network prioritization is Opportunistic cellular, Carrier + * WiFi and Macro cellular + * @return + */ + /** @hide */ + @NonNull + public Builder setVcnUnderlyingNetworkPriorities( + @NonNull LinkedHashSet<VcnUnderlyingNetworkPriority> underlyingNetworkPriorities) { + Objects.requireNonNull( + mUnderlyingNetworkPriorities, "underlyingNetworkPriorities is null"); + + mUnderlyingNetworkPriorities.clear(); + + if (underlyingNetworkPriorities.isEmpty()) { + mUnderlyingNetworkPriorities.addAll(DEFAULT_UNDERLYING_NETWORK_PRIORITIES); + } else { + mUnderlyingNetworkPriorities.addAll(underlyingNetworkPriorities); + } + + return this; + } + + /** * Set the retry interval between VCN establishment attempts upon successive failures. * * <p>The last retry interval will be repeated until safe mode is entered, or a connection @@ -513,6 +609,7 @@ public final class VcnGatewayConnectionConfig { mGatewayConnectionName, mTunnelConnectionParams, mExposedCapabilities, + mUnderlyingNetworkPriorities, mRetryIntervalsMs, mMaxMtu); } diff --git a/core/java/android/net/vcn/VcnUnderlyingNetworkPriority.java b/core/java/android/net/vcn/VcnUnderlyingNetworkPriority.java index 27750c659fc9..82f6ae72b43c 100644 --- a/core/java/android/net/vcn/VcnUnderlyingNetworkPriority.java +++ b/core/java/android/net/vcn/VcnUnderlyingNetworkPriority.java @@ -89,7 +89,7 @@ public abstract class VcnUnderlyingNetworkPriority { case NETWORK_PRIORITY_TYPE_WIFI: return VcnWifiUnderlyingNetworkPriority.fromPersistableBundle(in); case NETWORK_PRIORITY_TYPE_CELL: - throw new UnsupportedOperationException("Not implemented"); + return VcnCellUnderlyingNetworkPriority.fromPersistableBundle(in); default: throw new IllegalArgumentException( "Invalid networkPriorityType:" + networkPriorityType); diff --git a/services/core/java/com/android/server/vcn/util/PersistableBundleUtils.java b/services/core/java/com/android/server/vcn/util/PersistableBundleUtils.java index 5c1b5ffb2209..1c675c228554 100644 --- a/services/core/java/com/android/server/vcn/util/PersistableBundleUtils.java +++ b/services/core/java/com/android/server/vcn/util/PersistableBundleUtils.java @@ -46,6 +46,7 @@ public class PersistableBundleUtils { private static final String PARCEL_UUID_KEY = "PARCEL_UUID"; private static final String BYTE_ARRAY_KEY = "BYTE_ARRAY_KEY"; private static final String INTEGER_KEY = "INTEGER_KEY"; + private static final String STRING_KEY = "STRING_KEY"; /** * Functional interface to convert an object of the specified type to a PersistableBundle. @@ -91,6 +92,21 @@ public class PersistableBundleUtils { return bundle.getInt(INTEGER_KEY); }; + /** Serializer to convert s String to a PersistableBundle. */ + public static final Serializer<String> STRING_SERIALIZER = + (i) -> { + final PersistableBundle result = new PersistableBundle(); + result.putString(STRING_KEY, i); + return result; + }; + + /** Deserializer to convert a PersistableBundle to a String. */ + public static final Deserializer<String> STRING_DESERIALIZER = + (bundle) -> { + Objects.requireNonNull(bundle, "PersistableBundle is null"); + return bundle.getString(STRING_KEY); + }; + /** * Converts a ParcelUuid to a PersistableBundle. * diff --git a/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkPriorityTest.java b/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkPriorityTest.java new file mode 100644 index 000000000000..f7d3697029d6 --- /dev/null +++ b/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkPriorityTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2021 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 static android.net.vcn.VcnUnderlyingNetworkPriority.NETWORK_QUALITY_ANY; +import static android.net.vcn.VcnUnderlyingNetworkPriority.NETWORK_QUALITY_OK; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +public class VcnCellUnderlyingNetworkPriorityTest { + private static final Set<String> ALLOWED_PLMN_IDS = new HashSet<>(); + private static final Set<Integer> ALLOWED_CARRIER_IDS = new HashSet<>(); + + // Package private for use in VcnGatewayConnectionConfigTest + static VcnCellUnderlyingNetworkPriority getTestNetworkPriority() { + return new VcnCellUnderlyingNetworkPriority.Builder() + .setNetworkQuality(NETWORK_QUALITY_OK) + .setAllowMetered(true /* allowMetered */) + .setAllowedPlmnIds(ALLOWED_PLMN_IDS) + .setAllowedSpecificCarrierIds(ALLOWED_CARRIER_IDS) + .setAllowRoaming(true /* allowRoaming */) + .setRequireOpportunistic(true /* requireOpportunistic */) + .build(); + } + + @Test + public void testBuilderAndGetters() { + final VcnCellUnderlyingNetworkPriority networkPriority = getTestNetworkPriority(); + assertEquals(NETWORK_QUALITY_OK, networkPriority.getNetworkQuality()); + assertTrue(networkPriority.allowMetered()); + assertEquals(ALLOWED_PLMN_IDS, networkPriority.getAllowedPlmnIds()); + assertEquals(ALLOWED_CARRIER_IDS, networkPriority.getAllowedSpecificCarrierIds()); + assertTrue(networkPriority.allowRoaming()); + assertTrue(networkPriority.requireOpportunistic()); + } + + @Test + public void testBuilderAndGettersForDefaultValues() { + final VcnCellUnderlyingNetworkPriority networkPriority = + new VcnCellUnderlyingNetworkPriority.Builder().build(); + assertEquals(NETWORK_QUALITY_ANY, networkPriority.getNetworkQuality()); + assertFalse(networkPriority.allowMetered()); + assertEquals(new HashSet<String>(), networkPriority.getAllowedPlmnIds()); + assertEquals(new HashSet<Integer>(), networkPriority.getAllowedSpecificCarrierIds()); + assertFalse(networkPriority.allowRoaming()); + assertFalse(networkPriority.requireOpportunistic()); + } + + @Test + public void testPersistableBundle() { + final VcnCellUnderlyingNetworkPriority networkPriority = getTestNetworkPriority(); + assertEquals( + networkPriority, + VcnUnderlyingNetworkPriority.fromPersistableBundle( + networkPriority.toPersistableBundle())); + } +} diff --git a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java index dc338ae0fdc7..724c33ffb354 100644 --- a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java +++ b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java @@ -38,6 +38,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import java.util.Arrays; +import java.util.LinkedHashSet; import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) @@ -50,9 +51,17 @@ public class VcnGatewayConnectionConfigTest { }; public static final int[] UNDERLYING_CAPS = new int[] {NetworkCapabilities.NET_CAPABILITY_DUN}; + private static final LinkedHashSet<VcnUnderlyingNetworkPriority> UNDERLYING_NETWORK_PRIORITIES = + new LinkedHashSet(); + static { Arrays.sort(EXPOSED_CAPS); Arrays.sort(UNDERLYING_CAPS); + + UNDERLYING_NETWORK_PRIORITIES.add( + VcnCellUnderlyingNetworkPriorityTest.getTestNetworkPriority()); + UNDERLYING_NETWORK_PRIORITIES.add( + VcnWifiUnderlyingNetworkPriorityTest.getTestNetworkPriority()); } public static final long[] RETRY_INTERVALS_MS = @@ -82,7 +91,10 @@ public class VcnGatewayConnectionConfigTest { // Public for use in VcnGatewayConnectionTest public static VcnGatewayConnectionConfig buildTestConfig() { - return buildTestConfigWithExposedCaps(EXPOSED_CAPS); + final VcnGatewayConnectionConfig.Builder builder = + newBuilder().setVcnUnderlyingNetworkPriorities(UNDERLYING_NETWORK_PRIORITIES); + + return buildTestConfigWithExposedCaps(builder, EXPOSED_CAPS); } private static VcnGatewayConnectionConfig.Builder newBuilder() { @@ -159,6 +171,15 @@ public class VcnGatewayConnectionConfigTest { } @Test + public void testBuilderRequiresNonNullNetworkPriorities() { + try { + newBuilder().setVcnUnderlyingNetworkPriorities(null); + fail("Expected exception due to invalid underlyingNetworkPriorities"); + } catch (NullPointerException e) { + } + } + + @Test public void testBuilderRequiresNonNullRetryInterval() { try { newBuilder().setRetryIntervalsMillis(null); @@ -195,6 +216,7 @@ public class VcnGatewayConnectionConfigTest { Arrays.sort(exposedCaps); assertArrayEquals(EXPOSED_CAPS, exposedCaps); + assertEquals(UNDERLYING_NETWORK_PRIORITIES, config.getVcnUnderlyingNetworkPriorities()); assertEquals(TUNNEL_CONNECTION_PARAMS, config.getTunnelConnectionParams()); assertArrayEquals(RETRY_INTERVALS_MS, config.getRetryIntervalsMillis()); diff --git a/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkPriorityTest.java b/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkPriorityTest.java index 69ffeadbffae..dd272cb38596 100644 --- a/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkPriorityTest.java +++ b/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkPriorityTest.java @@ -30,7 +30,8 @@ public class VcnWifiUnderlyingNetworkPriorityTest { private static final String SSID = "TestWifi"; private static final int INVALID_NETWORK_QUALITY = -1; - private static VcnWifiUnderlyingNetworkPriority getTestNetworkPriority() { + // Package private for use in VcnGatewayConnectionConfigTest + static VcnWifiUnderlyingNetworkPriority getTestNetworkPriority() { return new VcnWifiUnderlyingNetworkPriority.Builder() .setNetworkQuality(NETWORK_QUALITY_OK) .setAllowMetered(true /* allowMetered */) |