Expose APIs to configure underlying network priority

This commit expose VcnUnderlyingNetworkTemplate classes
and methods to configure those objects in VcnGatewayConnectionConfig.

Those APIs allow callers to configure the underlying network priority
for VCN gateway when VCN is doing route selection. Callers can
construct VcnUnderlyingNeworkTemplate with network requirements and
then set VcnUnderlyingNeworkTemplate list from most preffered to least
preffered in VcnGatewayConnectionConfig.

Bug: 205343355
CTS-Coverage-Bug: 209498272
Test: atest FrameworksVcnTests, CtsVcnTestCases
Test: make update-api
Change-Id: Ib7d51cf1ce562a1acbcb767ec569d7e11c861a1d
diff --git a/core/api/current.txt b/core/api/current.txt
index 230689d..917d89c 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -27276,6 +27276,23 @@
 
 package android.net.vcn {
 
+  public final class VcnCellUnderlyingNetworkTemplate extends android.net.vcn.VcnUnderlyingNetworkTemplate {
+    method @NonNull public java.util.Set<java.lang.String> getOperatorPlmnIds();
+    method public int getOpportunistic();
+    method public int getRoaming();
+    method @NonNull public java.util.Set<java.lang.Integer> getSimSpecificCarrierIds();
+  }
+
+  public static final class VcnCellUnderlyingNetworkTemplate.Builder {
+    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 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);
+    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setSimSpecificCarrierIds(@NonNull java.util.Set<java.lang.Integer>);
+  }
+
   public final class VcnConfig implements android.os.Parcelable {
     method public int describeContents();
     method @NonNull public java.util.Set<android.net.vcn.VcnGatewayConnectionConfig> getGatewayConnectionConfigs();
@@ -27294,6 +27311,7 @@
     method @NonNull public String getGatewayConnectionName();
     method @IntRange(from=0x500) public int getMaxMtu();
     method @NonNull public long[] getRetryIntervalsMillis();
+    method @NonNull public java.util.List<android.net.vcn.VcnUnderlyingNetworkTemplate> getVcnUnderlyingNetworkPriorities();
   }
 
   public static final class VcnGatewayConnectionConfig.Builder {
@@ -27303,6 +27321,7 @@
     method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder removeExposedCapability(int);
     method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setMaxMtu(@IntRange(from=0x500) int);
     method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setRetryIntervalsMillis(@NonNull long[]);
+    method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setVcnUnderlyingNetworkPriorities(@NonNull java.util.List<android.net.vcn.VcnUnderlyingNetworkTemplate>);
   }
 
   public class VcnManager {
@@ -27326,6 +27345,24 @@
     method public abstract void onStatusChanged(int);
   }
 
+  public abstract class VcnUnderlyingNetworkTemplate {
+    method public int getMetered();
+    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
+  }
+
+  public final class VcnWifiUnderlyingNetworkTemplate extends android.net.vcn.VcnUnderlyingNetworkTemplate {
+    method @NonNull public java.util.Set<java.lang.String> getSsids();
+  }
+
+  public static final class VcnWifiUnderlyingNetworkTemplate.Builder {
+    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 setSsids(@NonNull java.util.Set<java.lang.String>);
+  }
+
 }
 
 package android.nfc {
diff --git a/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java b/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java
index 2dcb687..125b573 100644
--- a/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java
+++ b/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java
@@ -49,8 +49,6 @@
  * networks.
  *
  * <p>See {@link VcnUnderlyingNetworkTemplate}
- *
- * @hide
  */
 public final class VcnCellUnderlyingNetworkTemplate extends VcnUnderlyingNetworkTemplate {
     private static final String ALLOWED_NETWORK_PLMN_IDS_KEY = "mAllowedNetworkPlmnIds";
@@ -279,8 +277,13 @@
         /**
          * Set the matching criteria for metered networks.
          *
+         * <p>A template where setMetered(MATCH_REQUIRED) will only match metered networks (one
+         * without NET_CAPABILITY_NOT_METERED). A template where setMetered(MATCH_FORBIDDEN) will
+         * only match a network that is not metered (one with NET_CAPABILITY_NOT_METERED).
+         *
          * @param matchCriteria the matching criteria for metered networks. Defaults to {@link
-         *     #MATCH_ANY}. See {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED}
+         *     #MATCH_ANY}.
+         * @see NetworkCapabilities#NET_CAPABILITY_NOT_METERED
          */
         // The matching getter is defined in the super class. Please see {@link
         // VcnUnderlyingNetworkTemplate#getMetered()}
@@ -300,10 +303,11 @@
          * priority from a partner's networks.
          *
          * @param operatorPlmnIds the matching operator PLMN IDs in String. Network with one of the
-         *     matching PLMN IDs can match this template. 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()}.
+         *     matching PLMN IDs can match this template. If the set is empty, any PLMN ID will
+         *     match. The default is an empty set. A valid PLMN is a concatenation of MNC and MCC,
+         *     and thus consists of 5 or 6 decimal digits.
+         * @see SubscriptionInfo#getMccString()
+         * @see SubscriptionInfo#getMncString()
          */
         @NonNull
         public Builder setOperatorPlmnIds(@NonNull Set<String> operatorPlmnIds) {
@@ -318,8 +322,9 @@
          * Set sim specific carrier IDs with which a network can match this template.
          *
          * @param simSpecificCarrierIds the matching sim specific carrier IDs. Network with one of
-         *     the sim specific carrier IDs can match this template. Defaults to an empty set,
-         *     allowing ANY carrier ID. See {@link TelephonyManager#getSimSpecificCarrierId()}.
+         *     the sim specific carrier IDs can match this template. If the set is empty, any
+         *     carrier ID will match. The default is an empty set.
+         * @see TelephonyManager#getSimSpecificCarrierId()
          */
         @NonNull
         public Builder setSimSpecificCarrierIds(@NonNull Set<Integer> simSpecificCarrierIds) {
@@ -333,8 +338,13 @@
         /**
          * Set the matching criteria for roaming networks.
          *
+         * <p>A template where setRoaming(MATCH_REQUIRED) will only match roaming networks (one
+         * without NET_CAPABILITY_NOT_ROAMING). A template where setRoaming(MATCH_FORBIDDEN) will
+         * only match a network that is not roaming (one with NET_CAPABILITY_NOT_ROAMING).
+         *
          * @param matchCriteria the matching criteria for roaming networks. Defaults to {@link
-         *     #MATCH_ANY}. See {@link NetworkCapabilities#NET_CAPABILITY_NOT_ROAMING}.
+         *     #MATCH_ANY}.
+         * @see NetworkCapabilities#NET_CAPABILITY_NOT_ROAMING
          */
         @NonNull
         public Builder setRoaming(@MatchCriteria int matchCriteria) {
@@ -348,8 +358,8 @@
          * Set the matching criteria for opportunistic cellular subscriptions.
          *
          * @param matchCriteria the matching criteria for opportunistic cellular subscriptions.
-         *     Defaults to {@link #MATCH_ANY}. See {@link
-         *     SubscriptionManager#setOpportunistic(boolean, int)}
+         *     Defaults to {@link #MATCH_ANY}.
+         * @see SubscriptionManager#setOpportunistic(boolean, int)
          */
         @NonNull
         public Builder setOpportunistic(@MatchCriteria int matchCriteria) {
diff --git a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
index f17f30a..92956e8 100644
--- a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
+++ b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
@@ -375,11 +375,10 @@
     /**
      * Retrieve the VcnUnderlyingNetworkTemplate list, or a default list if it is not configured.
      *
-     * @see Builder#setVcnUnderlyingNetworkTemplates(List)
-     * @hide
+     * @see Builder#setVcnUnderlyingNetworkPriorities(List)
      */
     @NonNull
-    public List<VcnUnderlyingNetworkTemplate> getVcnUnderlyingNetworkTemplates() {
+    public List<VcnUnderlyingNetworkTemplate> getVcnUnderlyingNetworkPriorities() {
         return new ArrayList<>(mUnderlyingNetworkTemplates);
     }
 
@@ -543,29 +542,28 @@
         }
 
         /**
-         * Set the list of templates to match underlying networks against, in priority order.
+         * Set the list of templates to match underlying networks against, in high-to-low priority
+         * order.
          *
-         * <p>To select the VCN underlying network, the VCN gateway will go through all the network
-         * candidates and return a network matching the highest priority rule.
+         * <p>To select the VCN underlying network, the VCN connection will go through all the
+         * network candidates and return a network matching the highest priority rule.
          *
          * <p>If multiple networks match the same rule, the VCN will prefer an already-selected
          * network as opposed to a new/unselected network. However, if both are new/unselected
          * networks, a network will be chosen arbitrarily amongst the networks matching the highest
          * priority rule.
          *
-         * <p>A rule that matches all carrier-owned networks is implicitly added at the end of the
-         * priority list, ensuring that if all networks fail to match the rules provided, an
-         * underlying network will still be selected (at random if necessary).
+         * <p>If all networks fail to match the rules provided, an underlying network will still be
+         * selected (at random if necessary).
          *
          * @param underlyingNetworkTemplates a list of unique VcnUnderlyingNetworkTemplates that are
          *     ordered from most to least preferred, or an empty list to use the default
          *     prioritization. The default network prioritization order is Opportunistic cellular,
          *     Carrier WiFi and then Macro cellular.
          * @return this {@link Builder} instance, for chaining
-         * @hide
          */
         @NonNull
-        public Builder setVcnUnderlyingNetworkTemplates(
+        public Builder setVcnUnderlyingNetworkPriorities(
                 @NonNull List<VcnUnderlyingNetworkTemplate> underlyingNetworkTemplates) {
             validateNetworkTemplateList(underlyingNetworkTemplates);
 
diff --git a/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java b/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java
index 33b02e8..60fc936 100644
--- a/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java
+++ b/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java
@@ -22,7 +22,6 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.net.NetworkCapabilities;
 import android.os.PersistableBundle;
 import android.util.SparseArray;
 
@@ -41,9 +40,7 @@
  * <p>Apps provisioning a VCN can configure the underlying network priority for each Gateway
  * Connection by setting a list (in priority order, most to least preferred) of the appropriate
  * subclasses in the VcnGatewayConnectionConfig. See {@link
- * VcnGatewayConnectionConfig.Builder#setVcnUnderlyingNetworkTemplates}
- *
- * @hide
+ * VcnGatewayConnectionConfig.Builder#setVcnUnderlyingNetworkPriorities}
  */
 public abstract class VcnUnderlyingNetworkTemplate {
     /** @hide */
@@ -69,22 +66,23 @@
     public @interface NetworkQuality {}
 
     /**
-     * Used to configure the matching criteria of a network capability (See {@link
-     * NetworkCapabilities}). Denotes that networks with or without the capability are both
-     * acceptable to match the template.
+     * 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
+     * characteristic are both acceptable to match this template.
      */
     public static final int MATCH_ANY = 0;
 
     /**
-     * Used to configure the matching criteria of a network capability (See {@link
-     * NetworkCapabilities}). Denotes that only network with the capability can match the template.
+     * Used to configure the matching criteria of a network characteristic. This may include network
+     * capabilities, or cellular subscription information. Denotes that a network MUST have the
+     * capability in order to match this template.
      */
     public static final int MATCH_REQUIRED = 1;
 
     /**
-     * Used to configure the matching criteria of a network capability (See {@link
-     * NetworkCapabilities}). Denotes that only network without the capability can match the
-     * template.
+     * Used to configure the matching criteria of a network characteristic. This may include network
+     * capabilities, or cellular subscription information. Denotes that a network MUST NOT have the
+     * capability in order to match this template.
      */
     public static final int MATCH_FORBIDDEN = 2;
 
diff --git a/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java b/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java
index fcf5b09..272ca9d 100644
--- a/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java
+++ b/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java
@@ -40,8 +40,6 @@
  * networks.
  *
  * <p>See {@link VcnUnderlyingNetworkTemplate}
- *
- * @hide
  */
 public final class VcnWifiUnderlyingNetworkTemplate extends VcnUnderlyingNetworkTemplate {
     private static final String SSIDS_KEY = "mSsids";
@@ -168,8 +166,13 @@
         /**
          * Set the matching criteria for metered networks.
          *
+         * <p>A template where setMetered(MATCH_REQUIRED) will only match metered networks (one
+         * without NET_CAPABILITY_NOT_METERED). A template where setMetered(MATCH_FORBIDDEN) will
+         * only match a network that is not metered (one with NET_CAPABILITY_NOT_METERED).
+         *
          * @param matchCriteria the matching criteria for metered networks. Defaults to {@link
-         *     #MATCH_ANY}. See {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED}
+         *     #MATCH_ANY}.
+         * @see NetworkCapabilities#NET_CAPABILITY_NOT_METERED
          */
         // The matching getter is defined in the super class. Please see {@link
         // VcnUnderlyingNetworkTemplate#getMetered()}
@@ -186,7 +189,7 @@
          * Set the SSIDs with which a network can match this priority rule.
          *
          * @param ssids the matching SSIDs. Network with one of the matching SSIDs can match this
-         *     priority rule. Defaults to an empty set, allowing ANY SSID.
+         *     priority rule. If the set is empty, any SSID will match. The default is an empty set.
          */
         @NonNull
         public Builder setSsids(@NonNull Set<String> ssids) {
diff --git a/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkController.java b/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkController.java
index 6933e66..ca2e449 100644
--- a/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkController.java
+++ b/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkController.java
@@ -401,7 +401,7 @@
                     new TreeSet<>(
                             UnderlyingNetworkRecord.getComparator(
                                     mVcnContext,
-                                    mConnectionConfig.getVcnUnderlyingNetworkTemplates(),
+                                    mConnectionConfig.getVcnUnderlyingNetworkPriorities(),
                                     mSubscriptionGroup,
                                     mLastSnapshot,
                                     mCurrentRecord,
@@ -502,7 +502,7 @@
         pw.increaseIndent();
         int index = 0;
         for (VcnUnderlyingNetworkTemplate priority :
-                mConnectionConfig.getVcnUnderlyingNetworkTemplates()) {
+                mConnectionConfig.getVcnUnderlyingNetworkPriorities()) {
             pw.println("Priority index: " + index);
             priority.dump(pw);
             index++;
@@ -518,7 +518,7 @@
                 record.dump(
                         mVcnContext,
                         pw,
-                        mConnectionConfig.getVcnUnderlyingNetworkTemplates(),
+                        mConnectionConfig.getVcnUnderlyingNetworkPriorities(),
                         mSubscriptionGroup,
                         mLastSnapshot,
                         mCurrentRecord,
diff --git a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
index d7884e4..2aef9ae 100644
--- a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
@@ -96,7 +96,7 @@
     // Public for use in VcnGatewayConnectionTest
     public static VcnGatewayConnectionConfig buildTestConfig() {
         final VcnGatewayConnectionConfig.Builder builder =
-                newBuilder().setVcnUnderlyingNetworkTemplates(UNDERLYING_NETWORK_TEMPLATES);
+                newBuilder().setVcnUnderlyingNetworkPriorities(UNDERLYING_NETWORK_TEMPLATES);
 
         return buildTestConfigWithExposedCaps(builder, EXPOSED_CAPS);
     }
@@ -177,7 +177,7 @@
     @Test
     public void testBuilderRequiresNonNullNetworkTemplates() {
         try {
-            newBuilder().setVcnUnderlyingNetworkTemplates(null);
+            newBuilder().setVcnUnderlyingNetworkPriorities(null);
             fail("Expected exception due to invalid underlyingNetworkTemplates");
         } catch (NullPointerException e) {
         }
@@ -220,7 +220,7 @@
         Arrays.sort(exposedCaps);
         assertArrayEquals(EXPOSED_CAPS, exposedCaps);
 
-        assertEquals(UNDERLYING_NETWORK_TEMPLATES, config.getVcnUnderlyingNetworkTemplates());
+        assertEquals(UNDERLYING_NETWORK_TEMPLATES, config.getVcnUnderlyingNetworkPriorities());
         assertEquals(TUNNEL_CONNECTION_PARAMS, config.getTunnelConnectionParams());
 
         assertArrayEquals(RETRY_INTERVALS_MS, config.getRetryIntervalsMillis());
@@ -241,7 +241,7 @@
 
         final VcnGatewayConnectionConfig config = new VcnGatewayConnectionConfig(configBundle);
         assertEquals(
-                DEFAULT_UNDERLYING_NETWORK_TEMPLATES, config.getVcnUnderlyingNetworkTemplates());
+                DEFAULT_UNDERLYING_NETWORK_TEMPLATES, config.getVcnUnderlyingNetworkPriorities());
     }
 
     private static IkeTunnelConnectionParams buildTunnelConnectionParams(String ikePsk) {
@@ -292,7 +292,7 @@
                 new VcnGatewayConnectionConfig.Builder(
                                 "buildTestConfigWithVcnUnderlyingNetworkTemplates",
                                 TUNNEL_CONNECTION_PARAMS)
-                        .setVcnUnderlyingNetworkTemplates(networkTemplates),
+                        .setVcnUnderlyingNetworkPriorities(networkTemplates),
                 EXPOSED_CAPS);
     }