diff options
10 files changed, 635 insertions, 140 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index bb24da1e53fa..c6b367b210bd 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -27290,6 +27290,8 @@ package android.net.vcn { ctor public VcnCellUnderlyingNetworkTemplate.Builder(); method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate build(); method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMetered(int); + method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMinDownstreamBandwidthKbps(int, int); + method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMinUpstreamBandwidthKbps(int, int); method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setOperatorPlmnIds(@NonNull java.util.Set<java.lang.String>); method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setOpportunistic(int); method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setRoaming(int); @@ -27350,6 +27352,10 @@ package android.net.vcn { public abstract class VcnUnderlyingNetworkTemplate { method public int getMetered(); + method public int getMinEntryDownstreamBandwidthKbps(); + method public int getMinEntryUpstreamBandwidthKbps(); + method public int getMinExitDownstreamBandwidthKbps(); + method public int getMinExitUpstreamBandwidthKbps(); field public static final int MATCH_ANY = 0; // 0x0 field public static final int MATCH_FORBIDDEN = 2; // 0x2 field public static final int MATCH_REQUIRED = 1; // 0x1 @@ -27363,6 +27369,8 @@ package android.net.vcn { ctor public VcnWifiUnderlyingNetworkTemplate.Builder(); method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate build(); method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setMetered(int); + method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setMinDownstreamBandwidthKbps(int, int); + method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setMinUpstreamBandwidthKbps(int, int); method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setSsids(@NonNull java.util.Set<java.lang.String>); } diff --git a/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java b/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java index 125b5730b2ed..69e63133eb03 100644 --- a/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java +++ b/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java @@ -63,13 +63,22 @@ public final class VcnCellUnderlyingNetworkTemplate extends VcnUnderlyingNetwork private final int mOpportunisticMatchCriteria; private VcnCellUnderlyingNetworkTemplate( - int networkQuality, int meteredMatchCriteria, + int minEntryUpstreamBandwidthKbps, + int minExitUpstreamBandwidthKbps, + int minEntryDownstreamBandwidthKbps, + int minExitDownstreamBandwidthKbps, Set<String> allowedNetworkPlmnIds, Set<Integer> allowedSpecificCarrierIds, int roamingMatchCriteria, int opportunisticMatchCriteria) { - super(NETWORK_PRIORITY_TYPE_CELL, networkQuality, meteredMatchCriteria); + super( + NETWORK_PRIORITY_TYPE_CELL, + meteredMatchCriteria, + minEntryUpstreamBandwidthKbps, + minExitUpstreamBandwidthKbps, + minEntryDownstreamBandwidthKbps, + minExitDownstreamBandwidthKbps); mAllowedNetworkPlmnIds = new ArraySet<>(allowedNetworkPlmnIds); mAllowedSpecificCarrierIds = new ArraySet<>(allowedSpecificCarrierIds); mRoamingMatchCriteria = roamingMatchCriteria; @@ -109,9 +118,17 @@ public final class VcnCellUnderlyingNetworkTemplate extends VcnUnderlyingNetwork @NonNull PersistableBundle in) { Objects.requireNonNull(in, "PersistableBundle is null"); - final int networkQuality = in.getInt(NETWORK_QUALITY_KEY); final int meteredMatchCriteria = in.getInt(METERED_MATCH_KEY); + final int minEntryUpstreamBandwidthKbps = + in.getInt(MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS_KEY, DEFAULT_MIN_BANDWIDTH_KBPS); + final int minExitUpstreamBandwidthKbps = + in.getInt(MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS_KEY, DEFAULT_MIN_BANDWIDTH_KBPS); + final int minEntryDownstreamBandwidthKbps = + in.getInt(MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS_KEY, DEFAULT_MIN_BANDWIDTH_KBPS); + final int minExitDownstreamBandwidthKbps = + in.getInt(MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS_KEY, DEFAULT_MIN_BANDWIDTH_KBPS); + final PersistableBundle plmnIdsBundle = in.getPersistableBundle(ALLOWED_NETWORK_PLMN_IDS_KEY); Objects.requireNonNull(plmnIdsBundle, "plmnIdsBundle is null"); @@ -131,8 +148,11 @@ public final class VcnCellUnderlyingNetworkTemplate extends VcnUnderlyingNetwork final int opportunisticMatchCriteria = in.getInt(OPPORTUNISTIC_MATCH_KEY); return new VcnCellUnderlyingNetworkTemplate( - networkQuality, meteredMatchCriteria, + minEntryUpstreamBandwidthKbps, + minExitUpstreamBandwidthKbps, + minEntryDownstreamBandwidthKbps, + minExitDownstreamBandwidthKbps, allowedNetworkPlmnIds, allowedSpecificCarrierIds, roamingMatchCriteria, @@ -243,7 +263,6 @@ public final class VcnCellUnderlyingNetworkTemplate extends VcnUnderlyingNetwork /** This class is used to incrementally build VcnCellUnderlyingNetworkTemplate objects. */ public static final class Builder { - private int mNetworkQuality = NETWORK_QUALITY_ANY; private int mMeteredMatchCriteria = MATCH_ANY; @NonNull private final Set<String> mAllowedNetworkPlmnIds = new ArraySet<>(); @@ -252,29 +271,15 @@ public final class VcnCellUnderlyingNetworkTemplate extends VcnUnderlyingNetwork private int mRoamingMatchCriteria = MATCH_ANY; private int mOpportunisticMatchCriteria = MATCH_ANY; + private int mMinEntryUpstreamBandwidthKbps = DEFAULT_MIN_BANDWIDTH_KBPS; + private int mMinExitUpstreamBandwidthKbps = DEFAULT_MIN_BANDWIDTH_KBPS; + private int mMinEntryDownstreamBandwidthKbps = DEFAULT_MIN_BANDWIDTH_KBPS; + private int mMinExitDownstreamBandwidthKbps = DEFAULT_MIN_BANDWIDTH_KBPS; + /** Construct a Builder object. */ public Builder() {} /** - * Set the required network quality to match this template. - * - * <p>Network quality is a aggregation of multiple signals that reflect the network link - * metrics. For example, the network validation bit (see {@link - * NetworkCapabilities#NET_CAPABILITY_VALIDATED}), estimated first hop transport bandwidth - * and signal strength. - * - * @param networkQuality the required network quality. Defaults to NETWORK_QUALITY_ANY - * @hide - */ - @NonNull - public Builder setNetworkQuality(@NetworkQuality int networkQuality) { - validateNetworkQuality(networkQuality); - - mNetworkQuality = networkQuality; - return this; - } - - /** * Set the matching criteria for metered networks. * * <p>A template where setMetered(MATCH_REQUIRED) will only match metered networks (one @@ -369,12 +374,92 @@ public final class VcnCellUnderlyingNetworkTemplate extends VcnUnderlyingNetwork return this; } + /** + * Set the minimum upstream bandwidths that this template will match. + * + * <p>This template will not match a network that does not provide at least the bandwidth + * passed as the entry bandwidth, except in the case that the network is selected as the VCN + * Gateway Connection's underlying network, where it will continue to match until the + * bandwidth drops under the exit bandwidth. + * + * <p>The entry criteria MUST be greater than, or equal to the exit criteria to avoid the + * invalid case where a network fulfills the entry criteria, but at the same time fails the + * exit criteria. + * + * <p>Estimated bandwidth of a network is provided by the transport layer, and reported in + * {@link NetworkCapabilities}. The provided estimates will be used without modification. + * + * @param minEntryUpstreamBandwidthKbps the minimum accepted upstream bandwidth for networks + * that ARE NOT the already-selected underlying network, or {@code 0} to disable this + * requirement. Disabled by default. + * @param minExitUpstreamBandwidthKbps the minimum accepted upstream bandwidth for a network + * that IS the already-selected underlying network, or {@code 0} to disable this + * requirement. Disabled by default. + * @return this {@link Builder} instance, for chaining + */ + @NonNull + // The getter for the two integers are separated, and in the superclass. Please see {@link + // VcnUnderlyingNetworkTemplate#getMinEntryUpstreamBandwidthKbps()} and {@link + // VcnUnderlyingNetworkTemplate#getMinExitUpstreamBandwidthKbps()} + @SuppressLint("MissingGetterMatchingBuilder") + public Builder setMinUpstreamBandwidthKbps( + int minEntryUpstreamBandwidthKbps, int minExitUpstreamBandwidthKbps) { + validateMinBandwidthKbps(minEntryUpstreamBandwidthKbps, minExitUpstreamBandwidthKbps); + + mMinEntryUpstreamBandwidthKbps = minEntryUpstreamBandwidthKbps; + mMinExitUpstreamBandwidthKbps = minExitUpstreamBandwidthKbps; + + return this; + } + + /** + * Set the minimum upstream bandwidths that this template will match. + * + * <p>This template will not match a network that does not provide at least the bandwidth + * passed as the entry bandwidth, except in the case that the network is selected as the VCN + * Gateway Connection's underlying network, where it will continue to match until the + * bandwidth drops under the exit bandwidth. + * + * <p>The entry criteria MUST be greater than, or equal to the exit criteria to avoid the + * invalid case where a network fulfills the entry criteria, but at the same time fails the + * exit criteria. + * + * <p>Estimated bandwidth of a network is provided by the transport layer, and reported in + * {@link NetworkCapabilities}. The provided estimates will be used without modification. + * + * @param minEntryDownstreamBandwidthKbps the minimum accepted downstream bandwidth for + * networks that ARE NOT the already-selected underlying network, or {@code 0} to + * disable this requirement. Disabled by default. + * @param minExitDownstreamBandwidthKbps the minimum accepted downstream bandwidth for a + * network that IS the already-selected underlying network, or {@code 0} to disable this + * requirement. Disabled by default. + * @return this {@link Builder} instance, for chaining + */ + @NonNull + // The getter for the two integers are separated, and in the superclass. Please see {@link + // VcnUnderlyingNetworkTemplate#getMinEntryDownstreamBandwidthKbps()} and {@link + // VcnUnderlyingNetworkTemplate#getMinExitDownstreamBandwidthKbps()} + @SuppressLint("MissingGetterMatchingBuilder") + public Builder setMinDownstreamBandwidthKbps( + int minEntryDownstreamBandwidthKbps, int minExitDownstreamBandwidthKbps) { + validateMinBandwidthKbps( + minEntryDownstreamBandwidthKbps, minExitDownstreamBandwidthKbps); + + mMinEntryDownstreamBandwidthKbps = minEntryDownstreamBandwidthKbps; + mMinExitDownstreamBandwidthKbps = minExitDownstreamBandwidthKbps; + + return this; + } + /** Build the VcnCellUnderlyingNetworkTemplate. */ @NonNull public VcnCellUnderlyingNetworkTemplate build() { return new VcnCellUnderlyingNetworkTemplate( - mNetworkQuality, mMeteredMatchCriteria, + mMinEntryUpstreamBandwidthKbps, + mMinExitUpstreamBandwidthKbps, + mMinEntryDownstreamBandwidthKbps, + mMinExitDownstreamBandwidthKbps, mAllowedNetworkPlmnIds, mAllowedSpecificCarrierIds, mRoamingMatchCriteria, diff --git a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java index 92956e859fc7..a6830b708c31 100644 --- a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java +++ b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java @@ -17,7 +17,6 @@ package android.net.vcn; import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_MOBIKE; import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_REQUIRED; -import static android.net.vcn.VcnUnderlyingNetworkTemplate.NETWORK_QUALITY_OK; import static com.android.internal.annotations.VisibleForTesting.Visibility; @@ -169,18 +168,15 @@ public final class VcnGatewayConnectionConfig { static { DEFAULT_UNDERLYING_NETWORK_TEMPLATES.add( new VcnCellUnderlyingNetworkTemplate.Builder() - .setNetworkQuality(NETWORK_QUALITY_OK) .setOpportunistic(MATCH_REQUIRED) .build()); DEFAULT_UNDERLYING_NETWORK_TEMPLATES.add( new VcnWifiUnderlyingNetworkTemplate.Builder() - .setNetworkQuality(NETWORK_QUALITY_OK) .build()); DEFAULT_UNDERLYING_NETWORK_TEMPLATES.add( new VcnCellUnderlyingNetworkTemplate.Builder() - .setNetworkQuality(NETWORK_QUALITY_OK) .build()); } diff --git a/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java b/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java index 60fc936072fb..3a9ca3edded7 100644 --- a/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java +++ b/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java @@ -48,23 +48,6 @@ public abstract class VcnUnderlyingNetworkTemplate { /** @hide */ static final int NETWORK_PRIORITY_TYPE_CELL = 2; - /** Denotes that any network quality is acceptable. @hide */ - public static final int NETWORK_QUALITY_ANY = 0; - /** Denotes that network quality needs to be OK. @hide */ - public static final int NETWORK_QUALITY_OK = 100000; - - private static final SparseArray<String> NETWORK_QUALITY_TO_STRING_MAP = new SparseArray<>(); - - static { - NETWORK_QUALITY_TO_STRING_MAP.put(NETWORK_QUALITY_ANY, "NETWORK_QUALITY_ANY"); - NETWORK_QUALITY_TO_STRING_MAP.put(NETWORK_QUALITY_OK, "NETWORK_QUALITY_OK"); - } - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({NETWORK_QUALITY_OK, NETWORK_QUALITY_ANY}) - public @interface NetworkQuality {} - /** * Used to configure the matching criteria of a network characteristic. This may include network * capabilities, or cellular subscription information. Denotes that networks with or without the @@ -103,44 +86,73 @@ public abstract class VcnUnderlyingNetworkTemplate { private final int mNetworkPriorityType; /** @hide */ - static final String NETWORK_QUALITY_KEY = "mNetworkQuality"; + static final String METERED_MATCH_KEY = "mMeteredMatchCriteria"; - private final int mNetworkQuality; + private final int mMeteredMatchCriteria; /** @hide */ - static final String METERED_MATCH_KEY = "mMeteredMatchCriteria"; + public static final int DEFAULT_MIN_BANDWIDTH_KBPS = 0; - private final int mMeteredMatchCriteria; + /** @hide */ + static final String MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS_KEY = "mMinEntryUpstreamBandwidthKbps"; + + private final int mMinEntryUpstreamBandwidthKbps; + + /** @hide */ + static final String MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS_KEY = "mMinExitUpstreamBandwidthKbps"; + + private final int mMinExitUpstreamBandwidthKbps; + + /** @hide */ + static final String MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS_KEY = + "mMinEntryDownstreamBandwidthKbps"; + + private final int mMinEntryDownstreamBandwidthKbps; + + /** @hide */ + static final String MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS_KEY = "mMinExitDownstreamBandwidthKbps"; + + private final int mMinExitDownstreamBandwidthKbps; /** @hide */ VcnUnderlyingNetworkTemplate( - int networkPriorityType, int networkQuality, int meteredMatchCriteria) { + int networkPriorityType, + int meteredMatchCriteria, + int minEntryUpstreamBandwidthKbps, + int minExitUpstreamBandwidthKbps, + int minEntryDownstreamBandwidthKbps, + int minExitDownstreamBandwidthKbps) { mNetworkPriorityType = networkPriorityType; - mNetworkQuality = networkQuality; mMeteredMatchCriteria = meteredMatchCriteria; + mMinEntryUpstreamBandwidthKbps = minEntryUpstreamBandwidthKbps; + mMinExitUpstreamBandwidthKbps = minExitUpstreamBandwidthKbps; + mMinEntryDownstreamBandwidthKbps = minEntryDownstreamBandwidthKbps; + mMinExitDownstreamBandwidthKbps = minExitDownstreamBandwidthKbps; } /** @hide */ - static void validateNetworkQuality(int networkQuality) { + static void validateMatchCriteria(int matchCriteria, String matchingCapability) { Preconditions.checkArgument( - networkQuality == NETWORK_QUALITY_ANY || networkQuality == NETWORK_QUALITY_OK, - "Invalid networkQuality:" + networkQuality); + MATCH_CRITERIA_TO_STRING_MAP.contains(matchCriteria), + "Invalid matching criteria: " + matchCriteria + " for " + matchingCapability); } /** @hide */ - static void validateMatchCriteria(int meteredMatchCriteria, String matchingCapability) { + static void validateMinBandwidthKbps(int minEntryBandwidth, int minExitBandwidth) { Preconditions.checkArgument( - MATCH_CRITERIA_TO_STRING_MAP.contains(meteredMatchCriteria), - "Invalid matching criteria: " - + meteredMatchCriteria - + " for " - + matchingCapability); + minEntryBandwidth >= 0, "Invalid minEntryBandwidth, must be >= 0"); + Preconditions.checkArgument( + minExitBandwidth >= 0, "Invalid minExitBandwidth, must be >= 0"); + Preconditions.checkArgument( + minEntryBandwidth >= minExitBandwidth, + "Minimum entry bandwidth must be >= exit bandwidth"); } /** @hide */ protected void validate() { - validateNetworkQuality(mNetworkQuality); validateMatchCriteria(mMeteredMatchCriteria, "mMeteredMatchCriteria"); + validateMinBandwidthKbps(mMinEntryUpstreamBandwidthKbps, mMinExitUpstreamBandwidthKbps); + validateMinBandwidthKbps(mMinEntryDownstreamBandwidthKbps, mMinExitDownstreamBandwidthKbps); } /** @hide */ @@ -168,15 +180,24 @@ public abstract class VcnUnderlyingNetworkTemplate { final PersistableBundle result = new PersistableBundle(); result.putInt(NETWORK_PRIORITY_TYPE_KEY, mNetworkPriorityType); - result.putInt(NETWORK_QUALITY_KEY, mNetworkQuality); result.putInt(METERED_MATCH_KEY, mMeteredMatchCriteria); + result.putInt(MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS_KEY, mMinEntryUpstreamBandwidthKbps); + result.putInt(MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS_KEY, mMinExitUpstreamBandwidthKbps); + result.putInt(MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS_KEY, mMinEntryDownstreamBandwidthKbps); + result.putInt(MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS_KEY, mMinExitDownstreamBandwidthKbps); return result; } @Override public int hashCode() { - return Objects.hash(mNetworkPriorityType, mNetworkQuality, mMeteredMatchCriteria); + return Objects.hash( + mNetworkPriorityType, + mMeteredMatchCriteria, + mMinEntryUpstreamBandwidthKbps, + mMinExitUpstreamBandwidthKbps, + mMinEntryDownstreamBandwidthKbps, + mMinExitDownstreamBandwidthKbps); } @Override @@ -187,8 +208,11 @@ public abstract class VcnUnderlyingNetworkTemplate { final VcnUnderlyingNetworkTemplate rhs = (VcnUnderlyingNetworkTemplate) other; return mNetworkPriorityType == rhs.mNetworkPriorityType - && mNetworkQuality == rhs.mNetworkQuality - && mMeteredMatchCriteria == rhs.mMeteredMatchCriteria; + && mMeteredMatchCriteria == rhs.mMeteredMatchCriteria + && mMinEntryUpstreamBandwidthKbps == rhs.mMinEntryUpstreamBandwidthKbps + && mMinExitUpstreamBandwidthKbps == rhs.mMinExitUpstreamBandwidthKbps + && mMinEntryDownstreamBandwidthKbps == rhs.mMinEntryDownstreamBandwidthKbps + && mMinExitDownstreamBandwidthKbps == rhs.mMinExitDownstreamBandwidthKbps; } /** @hide */ @@ -197,8 +221,8 @@ public abstract class VcnUnderlyingNetworkTemplate { } /** @hide */ - static String getMatchCriteriaString(int meteredMatchCriteria) { - return getNameString(MATCH_CRITERIA_TO_STRING_MAP, meteredMatchCriteria); + static String getMatchCriteriaString(int matchCriteria) { + return getNameString(MATCH_CRITERIA_TO_STRING_MAP, matchCriteria); } /** @hide */ @@ -213,34 +237,63 @@ public abstract class VcnUnderlyingNetworkTemplate { pw.println(this.getClass().getSimpleName() + ":"); pw.increaseIndent(); - pw.println( - "mNetworkQuality: " - + getNameString(NETWORK_QUALITY_TO_STRING_MAP, mNetworkQuality)); pw.println("mMeteredMatchCriteria: " + getMatchCriteriaString(mMeteredMatchCriteria)); + pw.println("mMinEntryUpstreamBandwidthKbps: " + mMinEntryUpstreamBandwidthKbps); + pw.println("mMinExitUpstreamBandwidthKbps: " + mMinExitUpstreamBandwidthKbps); + pw.println("mMinEntryDownstreamBandwidthKbps: " + mMinEntryDownstreamBandwidthKbps); + pw.println("mMinExitDownstreamBandwidthKbps: " + mMinExitDownstreamBandwidthKbps); dumpTransportSpecificFields(pw); pw.decreaseIndent(); } /** - * Retrieve the required network quality to match this template. - * - * @see Builder#setNetworkQuality(int) - * @hide - */ - @NetworkQuality - public int getNetworkQuality() { - return mNetworkQuality; - } - - /** * Return the matching criteria for metered networks. * * @see VcnWifiUnderlyingNetworkTemplate.Builder#setMetered(int) * @see VcnCellUnderlyingNetworkTemplate.Builder#setMetered(int) */ - @MatchCriteria public int getMetered() { return mMeteredMatchCriteria; } + + /** + * Returns the minimum entry upstream bandwidth allowed by this template. + * + * @see VcnWifiUnderlyingNetworkTemplate.Builder#setMinUpstreamBandwidthKbps(int, int) + * @see VcnCellUnderlyingNetworkTemplate.Builder#setMinUpstreamBandwidthKbps(int, int) + */ + public int getMinEntryUpstreamBandwidthKbps() { + return mMinEntryUpstreamBandwidthKbps; + } + + /** + * Returns the minimum exit upstream bandwidth allowed by this template. + * + * @see VcnWifiUnderlyingNetworkTemplate.Builder#setMinUpstreamBandwidthKbps(int, int) + * @see VcnCellUnderlyingNetworkTemplate.Builder#setMinUpstreamBandwidthKbps(int, int) + */ + public int getMinExitUpstreamBandwidthKbps() { + return mMinExitUpstreamBandwidthKbps; + } + + /** + * Returns the minimum entry downstream bandwidth allowed by this template. + * + * @see VcnWifiUnderlyingNetworkTemplate.Builder#setMinDownstreamBandwidthKbps(int, int) + * @see VcnCellUnderlyingNetworkTemplate.Builder#setMinDownstreamBandwidthKbps(int, int) + */ + public int getMinEntryDownstreamBandwidthKbps() { + return mMinEntryDownstreamBandwidthKbps; + } + + /** + * Returns the minimum exit downstream bandwidth allowed by this template. + * + * @see VcnWifiUnderlyingNetworkTemplate.Builder#setMinDownstreamBandwidthKbps(int, int) + * @see VcnCellUnderlyingNetworkTemplate.Builder#setMinDownstreamBandwidthKbps(int, int) + */ + public int getMinExitDownstreamBandwidthKbps() { + return mMinExitDownstreamBandwidthKbps; + } } diff --git a/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java b/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java index 272ca9dd7583..23a07abdf0cb 100644 --- a/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java +++ b/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java @@ -46,8 +46,19 @@ public final class VcnWifiUnderlyingNetworkTemplate extends VcnUnderlyingNetwork @Nullable private final Set<String> mSsids; private VcnWifiUnderlyingNetworkTemplate( - int networkQuality, int meteredMatchCriteria, Set<String> ssids) { - super(NETWORK_PRIORITY_TYPE_WIFI, networkQuality, meteredMatchCriteria); + int meteredMatchCriteria, + int minEntryUpstreamBandwidthKbps, + int minExitUpstreamBandwidthKbps, + int minEntryDownstreamBandwidthKbps, + int minExitDownstreamBandwidthKbps, + Set<String> ssids) { + super( + NETWORK_PRIORITY_TYPE_WIFI, + meteredMatchCriteria, + minEntryUpstreamBandwidthKbps, + minExitUpstreamBandwidthKbps, + minEntryDownstreamBandwidthKbps, + minExitDownstreamBandwidthKbps); mSsids = new ArraySet<>(ssids); validate(); @@ -75,15 +86,29 @@ public final class VcnWifiUnderlyingNetworkTemplate extends VcnUnderlyingNetwork @NonNull PersistableBundle in) { Objects.requireNonNull(in, "PersistableBundle is null"); - final int networkQuality = in.getInt(NETWORK_QUALITY_KEY); final int meteredMatchCriteria = in.getInt(METERED_MATCH_KEY); + final int minEntryUpstreamBandwidthKbps = + in.getInt(MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS_KEY, DEFAULT_MIN_BANDWIDTH_KBPS); + final int minExitUpstreamBandwidthKbps = + in.getInt(MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS_KEY, DEFAULT_MIN_BANDWIDTH_KBPS); + final int minEntryDownstreamBandwidthKbps = + in.getInt(MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS_KEY, DEFAULT_MIN_BANDWIDTH_KBPS); + final int minExitDownstreamBandwidthKbps = + in.getInt(MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS_KEY, DEFAULT_MIN_BANDWIDTH_KBPS); + final PersistableBundle ssidsBundle = in.getPersistableBundle(SSIDS_KEY); Objects.requireNonNull(ssidsBundle, "ssidsBundle is null"); final Set<String> ssids = new ArraySet<String>( PersistableBundleUtils.toList(ssidsBundle, STRING_DESERIALIZER)); - return new VcnWifiUnderlyingNetworkTemplate(networkQuality, meteredMatchCriteria, ssids); + return new VcnWifiUnderlyingNetworkTemplate( + meteredMatchCriteria, + minEntryUpstreamBandwidthKbps, + minExitUpstreamBandwidthKbps, + minEntryDownstreamBandwidthKbps, + minExitDownstreamBandwidthKbps, + ssids); } /** @hide */ @@ -137,33 +162,18 @@ public final class VcnWifiUnderlyingNetworkTemplate extends VcnUnderlyingNetwork /** This class is used to incrementally build VcnWifiUnderlyingNetworkTemplate objects. */ public static final class Builder { - private int mNetworkQuality = NETWORK_QUALITY_ANY; private int mMeteredMatchCriteria = MATCH_ANY; @NonNull private final Set<String> mSsids = new ArraySet<>(); + private int mMinEntryUpstreamBandwidthKbps = DEFAULT_MIN_BANDWIDTH_KBPS; + private int mMinExitUpstreamBandwidthKbps = DEFAULT_MIN_BANDWIDTH_KBPS; + private int mMinEntryDownstreamBandwidthKbps = DEFAULT_MIN_BANDWIDTH_KBPS; + private int mMinExitDownstreamBandwidthKbps = DEFAULT_MIN_BANDWIDTH_KBPS; + /** Construct a Builder object. */ public Builder() {} /** - * Set the required network quality to match this template. - * - * <p>Network quality is a aggregation of multiple signals that reflect the network link - * metrics. For example, the network validation bit (see {@link - * NetworkCapabilities#NET_CAPABILITY_VALIDATED}), estimated first hop transport bandwidth - * and signal strength. - * - * @param networkQuality the required network quality. Defaults to NETWORK_QUALITY_ANY - * @hide - */ - @NonNull - public Builder setNetworkQuality(@NetworkQuality int networkQuality) { - validateNetworkQuality(networkQuality); - - mNetworkQuality = networkQuality; - return this; - } - - /** * Set the matching criteria for metered networks. * * <p>A template where setMetered(MATCH_REQUIRED) will only match metered networks (one @@ -200,11 +210,93 @@ public final class VcnWifiUnderlyingNetworkTemplate extends VcnUnderlyingNetwork return this; } + /** + * Set the minimum upstream bandwidths that this template will match. + * + * <p>This template will not match a network that does not provide at least the bandwidth + * passed as the entry bandwidth, except in the case that the network is selected as the VCN + * Gateway Connection's underlying network, where it will continue to match until the + * bandwidth drops under the exit bandwidth. + * + * <p>The entry criteria MUST be greater than, or equal to the exit criteria to avoid the + * invalid case where a network fulfills the entry criteria, but at the same time fails the + * exit criteria. + * + * <p>Estimated bandwidth of a network is provided by the transport layer, and reported in + * {@link NetworkCapabilities}. The provided estimates will be used without modification. + * + * @param minEntryUpstreamBandwidthKbps the minimum accepted upstream bandwidth for networks + * that ARE NOT the already-selected underlying network, or {@code 0} to disable this + * requirement. Disabled by default. + * @param minExitUpstreamBandwidthKbps the minimum accepted upstream bandwidth for a network + * that IS the already-selected underlying network, or {@code 0} to disable this + * requirement. Disabled by default. + * @return this {@link Builder} instance, for chaining + */ + @NonNull + // The getter for the two integers are separated, and in the superclass. Please see {@link + // VcnUnderlyingNetworkTemplate#getMinEntryUpstreamBandwidthKbps()} and {@link + // VcnUnderlyingNetworkTemplate#getMinExitUpstreamBandwidthKbps()} + @SuppressLint("MissingGetterMatchingBuilder") + public Builder setMinUpstreamBandwidthKbps( + int minEntryUpstreamBandwidthKbps, int minExitUpstreamBandwidthKbps) { + validateMinBandwidthKbps(minEntryUpstreamBandwidthKbps, minExitUpstreamBandwidthKbps); + + mMinEntryUpstreamBandwidthKbps = minEntryUpstreamBandwidthKbps; + mMinExitUpstreamBandwidthKbps = minExitUpstreamBandwidthKbps; + + return this; + } + + /** + * Set the minimum upstream bandwidths that this template will match. + * + * <p>This template will not match a network that does not provide at least the bandwidth + * passed as the entry bandwidth, except in the case that the network is selected as the VCN + * Gateway Connection's underlying network, where it will continue to match until the + * bandwidth drops under the exit bandwidth. + * + * <p>The entry criteria MUST be greater than, or equal to the exit criteria to avoid the + * invalid case where a network fulfills the entry criteria, but at the same time fails the + * exit criteria. + * + * <p>Estimated bandwidth of a network is provided by the transport layer, and reported in + * {@link NetworkCapabilities}. The provided estimates will be used without modification. + * + * @param minEntryDownstreamBandwidthKbps the minimum accepted downstream bandwidth for + * networks that ARE NOT the already-selected underlying network, or {@code 0} to + * disable this requirement. Disabled by default. + * @param minExitDownstreamBandwidthKbps the minimum accepted downstream bandwidth for a + * network that IS the already-selected underlying network, or {@code 0} to disable this + * requirement. Disabled by default. + * @return this {@link Builder} instance, for chaining + */ + @NonNull + // The getter for the two integers are separated, and in the superclass. Please see {@link + // VcnUnderlyingNetworkTemplate#getMinEntryDownstreamBandwidthKbps()} and {@link + // VcnUnderlyingNetworkTemplate#getMinExitDownstreamBandwidthKbps()} + @SuppressLint("MissingGetterMatchingBuilder") + public Builder setMinDownstreamBandwidthKbps( + int minEntryDownstreamBandwidthKbps, int minExitDownstreamBandwidthKbps) { + validateMinBandwidthKbps( + minEntryDownstreamBandwidthKbps, minExitDownstreamBandwidthKbps); + + mMinEntryDownstreamBandwidthKbps = minEntryDownstreamBandwidthKbps; + mMinExitDownstreamBandwidthKbps = minExitDownstreamBandwidthKbps; + + return this; + } + /** Build the VcnWifiUnderlyingNetworkTemplate. */ @NonNull public VcnWifiUnderlyingNetworkTemplate build() { return new VcnWifiUnderlyingNetworkTemplate( - mNetworkQuality, mMeteredMatchCriteria, mSsids); + mMeteredMatchCriteria, + mMinEntryUpstreamBandwidthKbps, + mMinExitUpstreamBandwidthKbps, + mMinEntryDownstreamBandwidthKbps, + mMinExitDownstreamBandwidthKbps, + mSsids); } } } diff --git a/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java b/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java index 6db25b7ed583..c96c1ee01a6d 100644 --- a/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java +++ b/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java @@ -22,8 +22,6 @@ import static android.net.NetworkCapabilities.TRANSPORT_TEST; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_FORBIDDEN; import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_REQUIRED; -import static android.net.vcn.VcnUnderlyingNetworkTemplate.NETWORK_QUALITY_ANY; -import static android.net.vcn.VcnUnderlyingNetworkTemplate.NETWORK_QUALITY_OK; import static com.android.server.VcnManagementService.LOCAL_LOG; @@ -47,6 +45,7 @@ import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscription import com.android.server.vcn.VcnContext; import java.util.List; +import java.util.Objects; import java.util.Set; /** @hide */ @@ -121,9 +120,10 @@ class NetworkPriorityClassifier { TelephonySubscriptionSnapshot snapshot, UnderlyingNetworkRecord currentlySelected, PersistableBundle carrierConfig) { - // TODO: Check Network Quality reported by metric monitors/probers. - final NetworkCapabilities caps = networkRecord.networkCapabilities; + final boolean isSelectedUnderlyingNetwork = + currentlySelected != null + && Objects.equals(currentlySelected.network, networkRecord.network); final int meteredMatch = networkPriority.getMetered(); final boolean isMetered = !caps.hasCapability(NET_CAPABILITY_NOT_METERED); @@ -132,6 +132,23 @@ class NetworkPriorityClassifier { return false; } + // Fails bandwidth requirements if either (a) less than exit threshold, or (b), not + // selected, but less than entry threshold + if (caps.getLinkUpstreamBandwidthKbps() < networkPriority.getMinExitUpstreamBandwidthKbps() + || (caps.getLinkUpstreamBandwidthKbps() + < networkPriority.getMinEntryUpstreamBandwidthKbps() + && !isSelectedUnderlyingNetwork)) { + return false; + } + + if (caps.getLinkDownstreamBandwidthKbps() + < networkPriority.getMinExitDownstreamBandwidthKbps() + || (caps.getLinkDownstreamBandwidthKbps() + < networkPriority.getMinEntryDownstreamBandwidthKbps() + && !isSelectedUnderlyingNetwork)) { + return false; + } + if (vcnContext.isInTestMode() && caps.hasTransport(TRANSPORT_TEST)) { return true; } @@ -172,8 +189,7 @@ class NetworkPriorityClassifier { } // TODO: Move the Network Quality check to the network metric monitor framework. - if (networkPriority.getNetworkQuality() - > getWifiQuality(networkRecord, currentlySelected, carrierConfig)) { + if (!isWifiRssiAcceptable(networkRecord, currentlySelected, carrierConfig)) { return false; } @@ -185,7 +201,7 @@ class NetworkPriorityClassifier { return true; } - private static int getWifiQuality( + private static boolean isWifiRssiAcceptable( UnderlyingNetworkRecord networkRecord, UnderlyingNetworkRecord currentlySelected, PersistableBundle carrierConfig) { @@ -196,14 +212,14 @@ class NetworkPriorityClassifier { if (isSelectedNetwork && caps.getSignalStrength() >= getWifiExitRssiThreshold(carrierConfig)) { - return NETWORK_QUALITY_OK; + return true; } if (caps.getSignalStrength() >= getWifiEntryRssiThreshold(carrierConfig)) { - return NETWORK_QUALITY_OK; + return true; } - return NETWORK_QUALITY_ANY; + return false; } @VisibleForTesting(visibility = Visibility.PRIVATE) diff --git a/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java b/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java index 4a724b72f5f9..2fbcf9d87bd4 100644 --- a/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java +++ b/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java @@ -18,25 +18,29 @@ package android.net.vcn; import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_ANY; import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_FORBIDDEN; import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_REQUIRED; -import static android.net.vcn.VcnUnderlyingNetworkTemplate.NETWORK_QUALITY_ANY; -import static android.net.vcn.VcnUnderlyingNetworkTemplate.NETWORK_QUALITY_OK; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; import org.junit.Test; import java.util.HashSet; import java.util.Set; -public class VcnCellUnderlyingNetworkTemplateTest { +public class VcnCellUnderlyingNetworkTemplateTest extends VcnUnderlyingNetworkTemplateTestBase { 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 VcnCellUnderlyingNetworkTemplate getTestNetworkTemplate() { return new VcnCellUnderlyingNetworkTemplate.Builder() - .setNetworkQuality(NETWORK_QUALITY_OK) .setMetered(MATCH_FORBIDDEN) + .setMinUpstreamBandwidthKbps( + TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS, + TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS) + .setMinDownstreamBandwidthKbps( + TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS, + TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS) .setOperatorPlmnIds(ALLOWED_PLMN_IDS) .setSimSpecificCarrierIds(ALLOWED_CARRIER_IDS) .setRoaming(MATCH_FORBIDDEN) @@ -47,8 +51,19 @@ public class VcnCellUnderlyingNetworkTemplateTest { @Test public void testBuilderAndGetters() { final VcnCellUnderlyingNetworkTemplate networkPriority = getTestNetworkTemplate(); - assertEquals(NETWORK_QUALITY_OK, networkPriority.getNetworkQuality()); assertEquals(MATCH_FORBIDDEN, networkPriority.getMetered()); + assertEquals( + TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS, + networkPriority.getMinEntryUpstreamBandwidthKbps()); + assertEquals( + TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS, + networkPriority.getMinExitUpstreamBandwidthKbps()); + assertEquals( + TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS, + networkPriority.getMinEntryDownstreamBandwidthKbps()); + assertEquals( + TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS, + networkPriority.getMinExitDownstreamBandwidthKbps()); assertEquals(ALLOWED_PLMN_IDS, networkPriority.getOperatorPlmnIds()); assertEquals(ALLOWED_CARRIER_IDS, networkPriority.getSimSpecificCarrierIds()); assertEquals(MATCH_FORBIDDEN, networkPriority.getRoaming()); @@ -59,8 +74,14 @@ public class VcnCellUnderlyingNetworkTemplateTest { public void testBuilderAndGettersForDefaultValues() { final VcnCellUnderlyingNetworkTemplate networkPriority = new VcnCellUnderlyingNetworkTemplate.Builder().build(); - assertEquals(NETWORK_QUALITY_ANY, networkPriority.getNetworkQuality()); assertEquals(MATCH_ANY, networkPriority.getMetered()); + + // Explicitly expect 0, as documented in Javadoc on setter methods. + assertEquals(0, networkPriority.getMinEntryUpstreamBandwidthKbps()); + assertEquals(0, networkPriority.getMinExitUpstreamBandwidthKbps()); + assertEquals(0, networkPriority.getMinEntryDownstreamBandwidthKbps()); + assertEquals(0, networkPriority.getMinExitDownstreamBandwidthKbps()); + assertEquals(new HashSet<String>(), networkPriority.getOperatorPlmnIds()); assertEquals(new HashSet<Integer>(), networkPriority.getSimSpecificCarrierIds()); assertEquals(MATCH_ANY, networkPriority.getRoaming()); @@ -68,6 +89,29 @@ public class VcnCellUnderlyingNetworkTemplateTest { } @Test + public void testBuilderRequiresStricterEntryCriteria() { + try { + new VcnCellUnderlyingNetworkTemplate.Builder() + .setMinUpstreamBandwidthKbps( + TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS, + TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS); + + fail("Expected IAE for exit threshold > entry threshold"); + } catch (IllegalArgumentException expected) { + } + + try { + new VcnCellUnderlyingNetworkTemplate.Builder() + .setMinDownstreamBandwidthKbps( + TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS, + TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS); + + fail("Expected IAE for exit threshold > entry threshold"); + } catch (IllegalArgumentException expected) { + } + } + + @Test public void testPersistableBundle() { final VcnCellUnderlyingNetworkTemplate networkPriority = getTestNetworkTemplate(); assertEquals( diff --git a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkTemplateTestBase.java b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkTemplateTestBase.java new file mode 100644 index 000000000000..399e13600442 --- /dev/null +++ b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkTemplateTestBase.java @@ -0,0 +1,24 @@ +/* + * 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; + +public class VcnUnderlyingNetworkTemplateTestBase { + // Public for use in NetworkPriorityClassifierTest + public static final int TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS = 200; + public static final int TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS = 100; + public static final int TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS = 400; + public static final int TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS = 300; +} diff --git a/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java b/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java index cb5b47bbdc15..4063178e005d 100644 --- a/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java +++ b/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java @@ -17,8 +17,6 @@ package android.net.vcn; import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_ANY; import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_FORBIDDEN; -import static android.net.vcn.VcnUnderlyingNetworkTemplate.NETWORK_QUALITY_ANY; -import static android.net.vcn.VcnUnderlyingNetworkTemplate.NETWORK_QUALITY_OK; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -28,15 +26,19 @@ import org.junit.Test; import java.util.Set; -public class VcnWifiUnderlyingNetworkTemplateTest { +public class VcnWifiUnderlyingNetworkTemplateTest extends VcnUnderlyingNetworkTemplateTestBase { private static final String SSID = "TestWifi"; - private static final int INVALID_NETWORK_QUALITY = -1; // Package private for use in VcnGatewayConnectionConfigTest static VcnWifiUnderlyingNetworkTemplate getTestNetworkTemplate() { return new VcnWifiUnderlyingNetworkTemplate.Builder() - .setNetworkQuality(NETWORK_QUALITY_OK) .setMetered(MATCH_FORBIDDEN) + .setMinUpstreamBandwidthKbps( + TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS, + TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS) + .setMinDownstreamBandwidthKbps( + TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS, + TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS) .setSsids(Set.of(SSID)) .build(); } @@ -44,8 +46,19 @@ public class VcnWifiUnderlyingNetworkTemplateTest { @Test public void testBuilderAndGetters() { final VcnWifiUnderlyingNetworkTemplate networkPriority = getTestNetworkTemplate(); - assertEquals(NETWORK_QUALITY_OK, networkPriority.getNetworkQuality()); assertEquals(MATCH_FORBIDDEN, networkPriority.getMetered()); + assertEquals( + TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS, + networkPriority.getMinEntryUpstreamBandwidthKbps()); + assertEquals( + TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS, + networkPriority.getMinExitUpstreamBandwidthKbps()); + assertEquals( + TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS, + networkPriority.getMinEntryDownstreamBandwidthKbps()); + assertEquals( + TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS, + networkPriority.getMinExitDownstreamBandwidthKbps()); assertEquals(Set.of(SSID), networkPriority.getSsids()); } @@ -53,18 +66,37 @@ public class VcnWifiUnderlyingNetworkTemplateTest { public void testBuilderAndGettersForDefaultValues() { final VcnWifiUnderlyingNetworkTemplate networkPriority = new VcnWifiUnderlyingNetworkTemplate.Builder().build(); - assertEquals(NETWORK_QUALITY_ANY, networkPriority.getNetworkQuality()); assertEquals(MATCH_ANY, networkPriority.getMetered()); + + // Explicitly expect 0, as documented in Javadoc on setter methods.. + assertEquals(0, networkPriority.getMinEntryUpstreamBandwidthKbps()); + assertEquals(0, networkPriority.getMinExitUpstreamBandwidthKbps()); + assertEquals(0, networkPriority.getMinEntryDownstreamBandwidthKbps()); + assertEquals(0, networkPriority.getMinExitDownstreamBandwidthKbps()); + assertTrue(networkPriority.getSsids().isEmpty()); } @Test - public void testBuildWithInvalidNetworkQuality() { + public void testBuilderRequiresStricterEntryCriteria() { try { new VcnWifiUnderlyingNetworkTemplate.Builder() - .setNetworkQuality(INVALID_NETWORK_QUALITY); - fail("Expected to fail due to the invalid network quality"); - } catch (Exception expected) { + .setMinUpstreamBandwidthKbps( + TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS, + TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS); + + fail("Expected IAE for exit threshold > entry threshold"); + } catch (IllegalArgumentException expected) { + } + + try { + new VcnWifiUnderlyingNetworkTemplate.Builder() + .setMinDownstreamBandwidthKbps( + TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS, + TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS); + + fail("Expected IAE for exit threshold > entry threshold"); + } catch (IllegalArgumentException expected) { } } diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java index 4bb7de8c1fef..6c849b5af888 100644 --- a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java +++ b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java @@ -18,7 +18,10 @@ package com.android.server.vcn.routeselection; import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_FORBIDDEN; import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_REQUIRED; -import static android.net.vcn.VcnUnderlyingNetworkTemplate.NETWORK_QUALITY_OK; +import static android.net.vcn.VcnUnderlyingNetworkTemplateTestBase.TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS; +import static android.net.vcn.VcnUnderlyingNetworkTemplateTestBase.TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS; +import static android.net.vcn.VcnUnderlyingNetworkTemplateTestBase.TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS; +import static android.net.vcn.VcnUnderlyingNetworkTemplateTestBase.TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS; import static com.android.server.vcn.VcnTestUtils.setupSystemService; import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.PRIORITY_ANY; @@ -76,6 +79,12 @@ public class NetworkPriorityClassifierTest { private static final int CARRIER_ID = 1; private static final int CARRIER_ID_OTHER = 2; + private static final int LINK_UPSTREAM_BANDWIDTH_KBPS = 1024; + private static final int LINK_DOWNSTREAM_BANDWIDTH_KBPS = 2048; + + private static final int TEST_MIN_UPSTREAM_BANDWIDTH_KBPS = 100; + private static final int TEST_MIN_DOWNSTREAM_BANDWIDTH_KBPS = 200; + private static final ParcelUuid SUB_GROUP = new ParcelUuid(new UUID(0, 0)); private static final NetworkCapabilities WIFI_NETWORK_CAPABILITIES = @@ -83,6 +92,8 @@ public class NetworkPriorityClassifierTest { .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .setSignalStrength(WIFI_RSSI) .setSsid(SSID) + .setLinkUpstreamBandwidthKbps(LINK_UPSTREAM_BANDWIDTH_KBPS) + .setLinkDownstreamBandwidthKbps(LINK_DOWNSTREAM_BANDWIDTH_KBPS) .build(); private static final TelephonyNetworkSpecifier TEL_NETWORK_SPECIFIER = @@ -93,6 +104,8 @@ public class NetworkPriorityClassifierTest { .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) .setSubscriptionIds(Set.of(SUB_ID)) .setNetworkSpecifier(TEL_NETWORK_SPECIFIER) + .setLinkUpstreamBandwidthKbps(LINK_UPSTREAM_BANDWIDTH_KBPS) + .setLinkDownstreamBandwidthKbps(LINK_DOWNSTREAM_BANDWIDTH_KBPS) .build(); private static final LinkProperties LINK_PROPERTIES = getLinkPropertiesWithName("test_iface"); @@ -146,7 +159,6 @@ public class NetworkPriorityClassifierTest { public void testMatchWithoutNotMeteredBit() { final VcnWifiUnderlyingNetworkTemplate wifiNetworkPriority = new VcnWifiUnderlyingNetworkTemplate.Builder() - .setNetworkQuality(NETWORK_QUALITY_OK) .setMetered(MATCH_FORBIDDEN) .build(); @@ -161,11 +173,133 @@ public class NetworkPriorityClassifierTest { null /* carrierConfig */)); } + private void verifyMatchesPriorityRuleForUpstreamBandwidth( + int entryUpstreamBandwidth, + int exitUpstreamBandwidth, + UnderlyingNetworkRecord currentlySelected, + boolean expectMatch) { + final VcnWifiUnderlyingNetworkTemplate wifiNetworkPriority = + new VcnWifiUnderlyingNetworkTemplate.Builder() + .setMinUpstreamBandwidthKbps(entryUpstreamBandwidth, exitUpstreamBandwidth) + .build(); + + assertEquals( + expectMatch, + checkMatchesPriorityRule( + mVcnContext, + wifiNetworkPriority, + mWifiNetworkRecord, + SUB_GROUP, + mSubscriptionSnapshot, + currentlySelected, + null /* carrierConfig */)); + } + + private void verifyMatchesPriorityRuleForDownstreamBandwidth( + int entryDownstreamBandwidth, + int exitDownstreamBandwidth, + UnderlyingNetworkRecord currentlySelected, + boolean expectMatch) { + final VcnWifiUnderlyingNetworkTemplate wifiNetworkPriority = + new VcnWifiUnderlyingNetworkTemplate.Builder() + .setMinDownstreamBandwidthKbps( + entryDownstreamBandwidth, exitDownstreamBandwidth) + .build(); + + assertEquals( + expectMatch, + checkMatchesPriorityRule( + mVcnContext, + wifiNetworkPriority, + mWifiNetworkRecord, + SUB_GROUP, + mSubscriptionSnapshot, + currentlySelected, + null /* carrierConfig */)); + } + + @Test + public void testMatchWithEntryUpstreamBandwidthEquals() { + verifyMatchesPriorityRuleForUpstreamBandwidth( + TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS, + TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS, + null /* currentlySelected */, + true); + } + + @Test + public void testMatchWithEntryUpstreamBandwidthTooLow() { + verifyMatchesPriorityRuleForUpstreamBandwidth( + LINK_UPSTREAM_BANDWIDTH_KBPS + 1, + LINK_UPSTREAM_BANDWIDTH_KBPS + 1, + null /* currentlySelected */, + false); + } + + @Test + public void testMatchWithEntryDownstreamBandwidthEquals() { + verifyMatchesPriorityRuleForDownstreamBandwidth( + TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS, + TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS, + null /* currentlySelected */, + true); + } + + @Test + public void testMatchWithEntryDownstreamBandwidthTooLow() { + verifyMatchesPriorityRuleForDownstreamBandwidth( + LINK_DOWNSTREAM_BANDWIDTH_KBPS + 1, + LINK_DOWNSTREAM_BANDWIDTH_KBPS + 1, + null /* currentlySelected */, + false); + } + + @Test + public void testMatchWithExitUpstreamBandwidthEquals() { + verifyMatchesPriorityRuleForUpstreamBandwidth( + TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS, + TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS, + mWifiNetworkRecord, + true); + } + + @Test + public void testMatchWithExitUpstreamBandwidthTooLow() { + verifyMatchesPriorityRuleForUpstreamBandwidth( + LINK_UPSTREAM_BANDWIDTH_KBPS + 1, + LINK_UPSTREAM_BANDWIDTH_KBPS + 1, + mWifiNetworkRecord, + false); + } + + @Test + public void testMatchWithExitDownstreamBandwidthEquals() { + verifyMatchesPriorityRuleForDownstreamBandwidth( + TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS, + TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS, + mWifiNetworkRecord, + true); + } + + @Test + public void testMatchWithExitDownstreamBandwidthTooLow() { + verifyMatchesPriorityRuleForDownstreamBandwidth( + LINK_DOWNSTREAM_BANDWIDTH_KBPS + 1, + LINK_DOWNSTREAM_BANDWIDTH_KBPS + 1, + mWifiNetworkRecord, + false); + } + private void verifyMatchWifi( boolean isSelectedNetwork, PersistableBundle carrierConfig, boolean expectMatch) { final VcnWifiUnderlyingNetworkTemplate wifiNetworkPriority = new VcnWifiUnderlyingNetworkTemplate.Builder() - .setNetworkQuality(NETWORK_QUALITY_OK) + .setMinUpstreamBandwidthKbps( + TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS, + TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS) + .setMinDownstreamBandwidthKbps( + TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS, + TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS) .build(); final UnderlyingNetworkRecord selectedNetworkRecord = isSelectedNetwork ? mWifiNetworkRecord : null; @@ -214,7 +348,12 @@ public class NetworkPriorityClassifierTest { final String nwPrioritySsid = useMatchedSsid ? SSID : SSID_OTHER; final VcnWifiUnderlyingNetworkTemplate wifiNetworkPriority = new VcnWifiUnderlyingNetworkTemplate.Builder() - .setNetworkQuality(NETWORK_QUALITY_OK) + .setMinUpstreamBandwidthKbps( + TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS, + TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS) + .setMinDownstreamBandwidthKbps( + TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS, + TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS) .setSsids(Set.of(nwPrioritySsid)) .build(); @@ -238,7 +377,13 @@ public class NetworkPriorityClassifierTest { } private static VcnCellUnderlyingNetworkTemplate.Builder getCellNetworkPriorityBuilder() { - return new VcnCellUnderlyingNetworkTemplate.Builder().setNetworkQuality(NETWORK_QUALITY_OK); + return new VcnCellUnderlyingNetworkTemplate.Builder() + .setMinUpstreamBandwidthKbps( + TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS, + TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS) + .setMinDownstreamBandwidthKbps( + TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS, + TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS); } @Test |