Merge changes I3b1ad1be,Id4c2e610

* changes:
  Implement exit announcements
  Implement announcements on probing success
diff --git a/Tethering/apex/Android.bp b/Tethering/apex/Android.bp
index 8840394..565675f 100644
--- a/Tethering/apex/Android.bp
+++ b/Tethering/apex/Android.bp
@@ -50,6 +50,15 @@
 // as the above target may have different "enabled" values
 // depending on the branch
 
+// cronet_in_tethering_apex_defaults can be used to specify an apex_defaults target that either
+// enables or disables inclusion of Cronet in the Tethering apex. This is used to disable Cronet
+// on tm-mainline-prod. Note: in order for Cronet APIs to work Cronet must also be enabled
+// by the cronet_java_*_defaults in common/TetheringLib/Android.bp.
+cronet_in_tethering_apex_defaults = "CronetInTetheringApexDefaultsEnabled"
+// This is a placeholder comment to avoid merge conflicts
+// as cronet_apex_defaults may have different values
+// depending on the branch
+
 apex {
     name: "com.android.tethering",
     defaults: [
diff --git a/Tethering/common/TetheringLib/Android.bp b/Tethering/common/TetheringLib/Android.bp
index 3f4da10..6df522c 100644
--- a/Tethering/common/TetheringLib/Android.bp
+++ b/Tethering/common/TetheringLib/Android.bp
@@ -31,7 +31,7 @@
 
 java_sdk_library {
     name: "framework-tethering",
-    defaults: ["framework-module-defaults"],
+    defaults: ["framework-tethering-defaults"],
     impl_library_visibility: [
         "//packages/modules/Connectivity/Tethering:__subpackages__",
         "//packages/modules/Connectivity/framework",
@@ -57,24 +57,54 @@
         "//packages/modules/NetworkStack/tests:__subpackages__",
         "//packages/modules/Wifi/service/tests/wifitests",
     ],
-
-    srcs: [":framework-tethering-srcs"],
-    libs: ["framework-connectivity.stubs.module_lib"],
     stub_only_libs: ["framework-connectivity.stubs.module_lib"],
+
+    jarjar_rules: ":framework-tethering-jarjar-rules",
+    installable: true,
+
+    hostdex: true, // for hiddenapi check
+    permitted_packages: ["android.net"],
+    lint: { strict_updatability_linting: true },
+}
+
+java_library {
+  name: "framework-tethering-pre-jarjar",
+  defaults: ["framework-tethering-defaults"],
+}
+
+java_genrule {
+    name: "framework-tethering-jarjar-rules",
+    tool_files: [
+        ":framework-tethering-pre-jarjar{.jar}",
+        ":framework-tethering.stubs.module_lib{.jar}",
+        "jarjar-excludes.txt",
+    ],
+    tools: [
+        "jarjar-rules-generator",
+    ],
+    out: ["framework_tethering_jarjar_rules.txt"],
+    cmd: "$(location jarjar-rules-generator) " +
+        "$(location :framework-tethering-pre-jarjar{.jar}) " +
+        "--apistubs $(location :framework-tethering.stubs.module_lib{.jar}) " + 
+        "--prefix android.net.http.internal " +
+        "--excludes $(location jarjar-excludes.txt) " +
+        "--output $(out)",
+}
+
+java_defaults {
+    name: "framework-tethering-defaults",
+    defaults: ["framework-module-defaults"],
+    srcs: [
+      ":framework-tethering-srcs"
+    ],
+    libs: ["framework-connectivity.stubs.module_lib"],
     aidl: {
         include_dirs: [
             "packages/modules/Connectivity/framework/aidl-export",
         ],
     },
-
-    jarjar_rules: "jarjar-rules.txt",
-    installable: true,
-
-    hostdex: true, // for hiddenapi check
     apex_available: ["com.android.tethering"],
-    permitted_packages: ["android.net"],
     min_sdk_version: "30",
-    lint: { strict_updatability_linting: true },
 }
 
 filegroup {
diff --git a/Tethering/common/TetheringLib/jarjar-excludes.txt b/Tethering/common/TetheringLib/jarjar-excludes.txt
new file mode 100644
index 0000000..50bc186
--- /dev/null
+++ b/Tethering/common/TetheringLib/jarjar-excludes.txt
@@ -0,0 +1,2 @@
+# Don't touch anything that's already under android.net
+android\.net\..+
\ No newline at end of file
diff --git a/Tethering/common/TetheringLib/jarjar-rules.txt b/Tethering/common/TetheringLib/jarjar-rules.txt
deleted file mode 100644
index e459fad..0000000
--- a/Tethering/common/TetheringLib/jarjar-rules.txt
+++ /dev/null
@@ -1 +0,0 @@
-# jarjar rules for the bootclasspath tethering framework library here
\ No newline at end of file
diff --git a/framework-t/src/android/net/NetworkTemplate.java b/framework-t/src/android/net/NetworkTemplate.java
index b2da371..f633a8f 100644
--- a/framework-t/src/android/net/NetworkTemplate.java
+++ b/framework-t/src/android/net/NetworkTemplate.java
@@ -88,18 +88,6 @@
     public static final int MATCH_WIFI = 4;
     /** Match rule to match ethernet networks. */
     public static final int MATCH_ETHERNET = 5;
-    /**
-     * Match rule to match all cellular networks.
-     *
-     * @hide
-     */
-    public static final int MATCH_MOBILE_WILDCARD = 6;
-    /**
-     * Match rule to match all wifi networks.
-     *
-     * @hide
-     */
-    public static final int MATCH_WIFI_WILDCARD = 7;
     /** Match rule to match bluetooth networks. */
     public static final int MATCH_BLUETOOTH = 8;
     /**
@@ -177,8 +165,6 @@
             case MATCH_MOBILE:
             case MATCH_WIFI:
             case MATCH_ETHERNET:
-            case MATCH_MOBILE_WILDCARD:
-            case MATCH_WIFI_WILDCARD:
             case MATCH_BLUETOOTH:
             case MATCH_PROXY:
             case MATCH_CARRIER:
@@ -258,7 +244,6 @@
     }
 
     private final int mMatchRule;
-    private final String mSubscriberId;
 
     /**
      * Ugh, templates are designed to target a single subscriber, but we might
@@ -285,9 +270,8 @@
 
     private static void checkValidMatchSubscriberIds(int matchRule, String[] matchSubscriberIds) {
         switch (matchRule) {
-            case MATCH_MOBILE:
             case MATCH_CARRIER:
-                // MOBILE and CARRIER templates must always specify a subscriber ID.
+                // CARRIER templates must always specify a valid subscriber ID.
                 if (matchSubscriberIds.length == 0) {
                     throw new IllegalArgumentException("checkValidMatchSubscriberIds with empty"
                             + " list of ids for rule" + getMatchRuleName(matchRule));
@@ -313,21 +297,20 @@
         // to metered networks. It is now possible to match mobile with any meteredness, but
         // in order to preserve backward compatibility of @UnsupportedAppUsage methods, this
         //constructor passes METERED_YES for these types.
-        this(matchRule, subscriberId, new String[] { subscriberId },
+        this(matchRule, new String[] { subscriberId },
                 wifiNetworkKey != null ? new String[] { wifiNetworkKey } : new String[0],
-                (matchRule == MATCH_MOBILE || matchRule == MATCH_MOBILE_WILDCARD
-                        || matchRule == MATCH_CARRIER) ? METERED_YES : METERED_ALL,
-                ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL);
+                (matchRule == MATCH_MOBILE || matchRule == MATCH_CARRIER)
+                        ? METERED_YES : METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL,
+                NETWORK_TYPE_ALL, OEM_MANAGED_ALL);
     }
 
     /** @hide */
-    public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
-            String[] matchWifiNetworkKeys, int metered, int roaming,
-            int defaultNetwork, int ratType, int oemManaged) {
+    public NetworkTemplate(int matchRule, String[] matchSubscriberIds,
+            String[] matchWifiNetworkKeys, int metered, int roaming, int defaultNetwork,
+            int ratType, int oemManaged) {
         Objects.requireNonNull(matchWifiNetworkKeys);
         Objects.requireNonNull(matchSubscriberIds);
         mMatchRule = matchRule;
-        mSubscriberId = subscriberId;
         mMatchSubscriberIds = matchSubscriberIds;
         mMatchWifiNetworkKeys = matchWifiNetworkKeys;
         mMetered = metered;
@@ -344,7 +327,6 @@
 
     private NetworkTemplate(Parcel in) {
         mMatchRule = in.readInt();
-        mSubscriberId = in.readString();
         mMatchSubscriberIds = in.createStringArray();
         mMatchWifiNetworkKeys = in.createStringArray();
         mMetered = in.readInt();
@@ -357,7 +339,6 @@
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeInt(mMatchRule);
-        dest.writeString(mSubscriberId);
         dest.writeStringArray(mMatchSubscriberIds);
         dest.writeStringArray(mMatchWifiNetworkKeys);
         dest.writeInt(mMetered);
@@ -376,10 +357,6 @@
     public String toString() {
         final StringBuilder builder = new StringBuilder("NetworkTemplate: ");
         builder.append("matchRule=").append(getMatchRuleName(mMatchRule));
-        if (mSubscriberId != null) {
-            builder.append(", subscriberId=").append(
-                    NetworkIdentityUtils.scrubSubscriberId(mSubscriberId));
-        }
         if (mMatchSubscriberIds != null) {
             builder.append(", matchSubscriberIds=").append(
                     Arrays.toString(NetworkIdentityUtils.scrubSubscriberIds(mMatchSubscriberIds)));
@@ -406,7 +383,7 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(mMatchRule, mSubscriberId, Arrays.hashCode(mMatchWifiNetworkKeys),
+        return Objects.hash(mMatchRule, Arrays.hashCode(mMatchWifiNetworkKeys),
                 mMetered, mRoaming, mDefaultNetwork, mRatType, mOemManaged);
     }
 
@@ -415,7 +392,6 @@
         if (obj instanceof NetworkTemplate) {
             final NetworkTemplate other = (NetworkTemplate) obj;
             return mMatchRule == other.mMatchRule
-                    && Objects.equals(mSubscriberId, other.mSubscriberId)
                     && mMetered == other.mMetered
                     && mRoaming == other.mRoaming
                     && mDefaultNetwork == other.mDefaultNetwork
@@ -426,42 +402,25 @@
         return false;
     }
 
-    /** @hide */
-    public boolean isMatchRuleMobile() {
-        switch (mMatchRule) {
-            case MATCH_MOBILE:
-            case MATCH_MOBILE_WILDCARD:
-                return true;
-            default:
-                return false;
-        }
-    }
-
     /**
      * Get match rule of the template. See {@code MATCH_*}.
      */
-    @UnsupportedAppUsage
     public int getMatchRule() {
-        // Wildcard rules are not exposed. For external callers, convert wildcard rules to
-        // exposed rules before returning.
-        switch (mMatchRule) {
-            case MATCH_MOBILE_WILDCARD:
-                return MATCH_MOBILE;
-            case MATCH_WIFI_WILDCARD:
-                return MATCH_WIFI;
-            default:
-                return mMatchRule;
-        }
+        return mMatchRule;
     }
 
     /**
      * Get subscriber Id of the template.
+     *
+     * @deprecated User should use {@link #getSubscriberIds} instead.
      * @hide
      */
+    @Deprecated
     @Nullable
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.TIRAMISU,
+            publicAlternatives = "Caller should use {@code getSubscriberIds} instead.")
     public String getSubscriberId() {
-        return mSubscriberId;
+        return CollectionUtils.isEmpty(mMatchSubscriberIds) ? null : mMatchSubscriberIds[0];
     }
 
     /**
@@ -548,10 +507,6 @@
                 return matchesWifi(ident);
             case MATCH_ETHERNET:
                 return matchesEthernet(ident);
-            case MATCH_MOBILE_WILDCARD:
-                return matchesMobileWildcard(ident);
-            case MATCH_WIFI_WILDCARD:
-                return matchesWifiWildcard(ident);
             case MATCH_BLUETOOTH:
                 return matchesBluetooth(ident);
             case MATCH_PROXY:
@@ -632,9 +587,9 @@
             // TODO: consider matching against WiMAX subscriber identity
             return true;
         } else {
-            return ident.mType == TYPE_MOBILE && !CollectionUtils.isEmpty(mMatchSubscriberIds)
-                    && CollectionUtils.contains(mMatchSubscriberIds, ident.mSubscriberId)
-                    && matchesCollapsedRatType(ident);
+            return (CollectionUtils.isEmpty(mMatchSubscriberIds)
+                || CollectionUtils.contains(mMatchSubscriberIds, ident.mSubscriberId))
+                && (ident.mType == TYPE_MOBILE && matchesCollapsedRatType(ident));
         }
     }
 
@@ -646,6 +601,8 @@
             case TYPE_WIFI:
                 return matchesSubscriberId(ident.mSubscriberId)
                         && matchesWifiNetworkKey(ident.mWifiNetworkKey);
+            case TYPE_WIFI_P2P:
+                return CollectionUtils.isEmpty(mMatchWifiNetworkKeys);
             default:
                 return false;
         }
@@ -681,24 +638,6 @@
                 || CollectionUtils.contains(mMatchWifiNetworkKeys, ident.mWifiNetworkKey)));
     }
 
-    private boolean matchesMobileWildcard(NetworkIdentity ident) {
-        if (ident.mType == TYPE_WIMAX) {
-            return true;
-        } else {
-            return ident.mType == TYPE_MOBILE && matchesCollapsedRatType(ident);
-        }
-    }
-
-    private boolean matchesWifiWildcard(NetworkIdentity ident) {
-        switch (ident.mType) {
-            case TYPE_WIFI:
-            case TYPE_WIFI_P2P:
-                return true;
-            default:
-                return false;
-        }
-    }
-
     /**
      * Check if matches Bluetooth network template.
      */
@@ -724,10 +663,6 @@
                 return "WIFI";
             case MATCH_ETHERNET:
                 return "ETHERNET";
-            case MATCH_MOBILE_WILDCARD:
-                return "MOBILE_WILDCARD";
-            case MATCH_WIFI_WILDCARD:
-                return "WIFI_WILDCARD";
             case MATCH_BLUETOOTH:
                 return "BLUETOOTH";
             case MATCH_PROXY:
@@ -775,20 +710,20 @@
         // information. For instances:
         // The TYPE_WIFI with subscriberId means that it is a merged carrier wifi network.
         // The TYPE_CARRIER means that the network associate to specific carrier network.
-        if (template.mSubscriberId == null) return template;
 
-        if (CollectionUtils.contains(merged, template.mSubscriberId)) {
+        if (CollectionUtils.isEmpty(template.mMatchSubscriberIds)) return template;
+
+        if (CollectionUtils.contains(merged, template.mMatchSubscriberIds[0])) {
             // Requested template subscriber is part of the merge group; return
             // a template that matches all merged subscribers.
             final String[] matchWifiNetworkKeys = template.mMatchWifiNetworkKeys;
             // TODO: Use NetworkTemplate.Builder to build a template after NetworkTemplate
             // could handle incompatible subscriberIds. See b/217805241.
-            return new NetworkTemplate(template.mMatchRule, merged[0], merged,
+            return new NetworkTemplate(template.mMatchRule, merged,
                     CollectionUtils.isEmpty(matchWifiNetworkKeys)
                             ? new String[0] : new String[] { matchWifiNetworkKeys[0] },
-                    (template.mMatchRule == MATCH_MOBILE
-                            || template.mMatchRule == MATCH_MOBILE_WILDCARD
-                            || template.mMatchRule == MATCH_CARRIER) ? METERED_YES : METERED_ALL,
+                    (template.mMatchRule == MATCH_MOBILE || template.mMatchRule == MATCH_CARRIER)
+                            ? METERED_YES : METERED_ALL,
                     ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL);
         }
 
@@ -956,10 +891,7 @@
          * @param matchRule the target match rule to be checked.
          */
         private static void assertRequestableMatchRule(final int matchRule) {
-            if (!isKnownMatchRule(matchRule)
-                    || matchRule == MATCH_PROXY
-                    || matchRule == MATCH_MOBILE_WILDCARD
-                    || matchRule == MATCH_WIFI_WILDCARD) {
+            if (!isKnownMatchRule(matchRule) || matchRule == MATCH_PROXY) {
                 throw new IllegalArgumentException("Invalid match rule: "
                         + getMatchRuleName(matchRule));
             }
@@ -980,20 +912,6 @@
         }
 
         /**
-         * For backward compatibility, deduce match rule to a wildcard match rule
-         * if the Subscriber Ids are empty.
-         */
-        private int getWildcardDeducedMatchRule() {
-            if (mMatchRule == MATCH_MOBILE && mMatchSubscriberIds.isEmpty()) {
-                return MATCH_MOBILE_WILDCARD;
-            } else if (mMatchRule == MATCH_WIFI && mMatchSubscriberIds.isEmpty()
-                    && mMatchWifiNetworkKeys.isEmpty()) {
-                return MATCH_WIFI_WILDCARD;
-            }
-            return mMatchRule;
-        }
-
-        /**
          * Builds the instance of the NetworkTemplate.
          *
          * @return the built instance of NetworkTemplate.
@@ -1001,8 +919,7 @@
         @NonNull
         public NetworkTemplate build() {
             assertRequestableParameters();
-            return new NetworkTemplate(getWildcardDeducedMatchRule(),
-                    mMatchSubscriberIds.isEmpty() ? null : mMatchSubscriberIds.iterator().next(),
+            return new NetworkTemplate(mMatchRule,
                     mMatchSubscriberIds.toArray(new String[0]),
                     mMatchWifiNetworkKeys.toArray(new String[0]), mMetered, mRoaming,
                     mDefaultNetwork, mRatType, mOemManaged);
diff --git a/tests/common/java/android/net/netstats/NetworkTemplateTest.kt b/tests/common/java/android/net/netstats/NetworkTemplateTest.kt
index 3c2340c..99f1e0b 100644
--- a/tests/common/java/android/net/netstats/NetworkTemplateTest.kt
+++ b/tests/common/java/android/net/netstats/NetworkTemplateTest.kt
@@ -26,10 +26,8 @@
 import android.net.NetworkTemplate.MATCH_CARRIER
 import android.net.NetworkTemplate.MATCH_ETHERNET
 import android.net.NetworkTemplate.MATCH_MOBILE
-import android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD
 import android.net.NetworkTemplate.MATCH_PROXY
 import android.net.NetworkTemplate.MATCH_WIFI
-import android.net.NetworkTemplate.MATCH_WIFI_WILDCARD
 import android.net.NetworkTemplate.NETWORK_TYPE_ALL
 import android.net.NetworkTemplate.OEM_MANAGED_ALL
 import android.telephony.TelephonyManager
@@ -64,10 +62,8 @@
         }
 
         // Verify hidden match rules cannot construct templates.
-        listOf(MATCH_WIFI_WILDCARD, MATCH_MOBILE_WILDCARD, MATCH_PROXY).forEach {
-            assertFailsWith<IllegalArgumentException> {
-                NetworkTemplate.Builder(it).build()
-            }
+        assertFailsWith<IllegalArgumentException> {
+            NetworkTemplate.Builder(MATCH_PROXY).build()
         }
 
         // Verify template which matches metered cellular and carrier networks with
@@ -75,10 +71,9 @@
         listOf(MATCH_MOBILE, MATCH_CARRIER).forEach { matchRule ->
             NetworkTemplate.Builder(matchRule).setSubscriberIds(setOf(TEST_IMSI1))
                     .setMeteredness(METERED_YES).build().let {
-                        val expectedTemplate = NetworkTemplate(matchRule, TEST_IMSI1,
-                                arrayOf(TEST_IMSI1), emptyArray<String>(), METERED_YES,
-                                ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
-                                OEM_MANAGED_ALL)
+                        val expectedTemplate = NetworkTemplate(matchRule, arrayOf(TEST_IMSI1),
+                                emptyArray<String>(), METERED_YES, ROAMING_ALL, DEFAULT_NETWORK_ALL,
+                                NETWORK_TYPE_ALL, OEM_MANAGED_ALL)
                         assertEquals(expectedTemplate, it)
                     }
         }
@@ -88,10 +83,9 @@
         listOf(MATCH_MOBILE, MATCH_CARRIER).forEach { matchRule ->
             NetworkTemplate.Builder(matchRule).setSubscriberIds(setOf(TEST_IMSI1))
                     .setRoaming(ROAMING_YES).setMeteredness(METERED_YES).build().let {
-                        val expectedTemplate = NetworkTemplate(matchRule, TEST_IMSI1,
-                                arrayOf(TEST_IMSI1), emptyArray<String>(), METERED_YES,
-                                ROAMING_YES, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
-                                OEM_MANAGED_ALL)
+                        val expectedTemplate = NetworkTemplate(matchRule, arrayOf(TEST_IMSI1),
+                                emptyArray<String>(), METERED_YES, ROAMING_YES, DEFAULT_NETWORK_ALL,
+                                NETWORK_TYPE_ALL, OEM_MANAGED_ALL)
                         assertEquals(expectedTemplate, it)
                     }
         }
@@ -104,42 +98,39 @@
         // Verify template which matches metered cellular networks,
         // regardless of IMSI. See buildTemplateMobileWildcard.
         NetworkTemplate.Builder(MATCH_MOBILE).setMeteredness(METERED_YES).build().let {
-            val expectedTemplate = NetworkTemplate(MATCH_MOBILE_WILDCARD, null /*subscriberId*/,
-                    emptyArray<String>() /*subscriberIds*/, emptyArray<String>(),
+            val expectedTemplate = NetworkTemplate(MATCH_MOBILE,
+                    emptyArray<String>() /*subscriberIds*/, emptyArray<String>() /*wifiNetworkKey*/,
                     METERED_YES, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
                     OEM_MANAGED_ALL)
             assertEquals(expectedTemplate, it)
         }
 
         // Verify template which matches metered cellular networks and ratType.
-        // See NetworkTemplate#buildTemplateMobileWithRatType.
         NetworkTemplate.Builder(MATCH_MOBILE).setSubscriberIds(setOf(TEST_IMSI1))
                 .setMeteredness(METERED_YES).setRatType(TelephonyManager.NETWORK_TYPE_UMTS)
                 .build().let {
-                    val expectedTemplate = NetworkTemplate(MATCH_MOBILE, TEST_IMSI1,
-                            arrayOf(TEST_IMSI1), emptyArray<String>(), METERED_YES,
-                            ROAMING_ALL, DEFAULT_NETWORK_ALL, TelephonyManager.NETWORK_TYPE_UMTS,
-                            OEM_MANAGED_ALL)
+                    val expectedTemplate = NetworkTemplate(MATCH_MOBILE, arrayOf(TEST_IMSI1),
+                            emptyArray<String>(), METERED_YES, ROAMING_ALL, DEFAULT_NETWORK_ALL,
+                            TelephonyManager.NETWORK_TYPE_UMTS, OEM_MANAGED_ALL)
                     assertEquals(expectedTemplate, it)
                 }
 
         // Verify template which matches all wifi networks,
         // regardless of Wifi Network Key. See buildTemplateWifiWildcard and buildTemplateWifi.
         NetworkTemplate.Builder(MATCH_WIFI).build().let {
-            val expectedTemplate = NetworkTemplate(MATCH_WIFI_WILDCARD, null /*subscriberId*/,
-                    emptyArray<String>() /*subscriberIds*/, emptyArray<String>(),
-                    METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
-                    OEM_MANAGED_ALL)
+            val expectedTemplate = NetworkTemplate(MATCH_WIFI,
+                    emptyArray<String>() /*subscriberIds*/, emptyArray<String>(), METERED_ALL,
+                    ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL)
             assertEquals(expectedTemplate, it)
         }
 
         // Verify template which matches wifi networks with the given Wifi Network Key.
         // See buildTemplateWifi(wifiNetworkKey).
         NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build().let {
-            val expectedTemplate = NetworkTemplate(MATCH_WIFI, null /*subscriberId*/,
-                    emptyArray<String>() /*subscriberIds*/, arrayOf(TEST_WIFI_KEY1),
-                    METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
-                    OEM_MANAGED_ALL)
+            val expectedTemplate =
+                    NetworkTemplate(MATCH_WIFI, emptyArray<String>() /*subscriberIds*/,
+                    arrayOf(TEST_WIFI_KEY1), METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL,
+                    NETWORK_TYPE_ALL, OEM_MANAGED_ALL)
             assertEquals(expectedTemplate, it)
         }
 
@@ -147,10 +138,9 @@
         // given Wifi Network Key, and IMSI. See buildTemplateWifi(wifiNetworkKey, subscriberId).
         NetworkTemplate.Builder(MATCH_WIFI).setSubscriberIds(setOf(TEST_IMSI1))
                 .setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build().let {
-                    val expectedTemplate = NetworkTemplate(MATCH_WIFI, TEST_IMSI1,
-                            arrayOf(TEST_IMSI1), arrayOf(TEST_WIFI_KEY1),
-                            METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
-                            OEM_MANAGED_ALL)
+                    val expectedTemplate = NetworkTemplate(MATCH_WIFI, arrayOf(TEST_IMSI1),
+                            arrayOf(TEST_WIFI_KEY1), METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL,
+                            NETWORK_TYPE_ALL, OEM_MANAGED_ALL)
                     assertEquals(expectedTemplate, it)
                 }
 
@@ -158,7 +148,7 @@
         // See buildTemplateEthernet and buildTemplateBluetooth.
         listOf(MATCH_ETHERNET, MATCH_BLUETOOTH).forEach { matchRule ->
             NetworkTemplate.Builder(matchRule).build().let {
-                val expectedTemplate = NetworkTemplate(matchRule, null /*subscriberId*/,
+                val expectedTemplate = NetworkTemplate(matchRule,
                         emptyArray<String>() /*subscriberIds*/, emptyArray<String>(),
                         METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
                         OEM_MANAGED_ALL)
@@ -193,7 +183,7 @@
 
         // Verify template which matches wifi wildcard with the given empty key set.
         NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(setOf<String>()).build().let {
-            val expectedTemplate = NetworkTemplate(MATCH_WIFI_WILDCARD, null /*subscriberId*/,
+            val expectedTemplate = NetworkTemplate(MATCH_WIFI,
                     emptyArray<String>() /*subscriberIds*/, emptyArray<String>(),
                     METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
                     OEM_MANAGED_ALL)
diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java
index a9a3380..5fc3068 100644
--- a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java
+++ b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java
@@ -32,10 +32,13 @@
 import static android.system.OsConstants.AF_INET;
 import static android.system.OsConstants.AF_INET6;
 
+import static com.android.compatibility.common.util.PropertyUtil.getVsrApiLevel;
+
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.junit.Assume.assumeTrue;
 
@@ -80,6 +83,11 @@
 
     private static final String TAG = IpSecManagerTunnelTest.class.getSimpleName();
 
+    // Redefine this flag here so that IPsec code shipped in a mainline module can build on old
+    // platforms before FEATURE_IPSEC_TUNNEL_MIGRATION API is released.
+    private static final String FEATURE_IPSEC_TUNNEL_MIGRATION =
+            "android.software.ipsec_tunnel_migration";
+
     private static final InetAddress LOCAL_OUTER_4 = InetAddress.parseNumericAddress("192.0.2.1");
     private static final InetAddress REMOTE_OUTER_4 = InetAddress.parseNumericAddress("192.0.2.2");
     private static final InetAddress LOCAL_OUTER_6 =
@@ -994,6 +1002,41 @@
         checkTunnelInput(innerFamily, outerFamily, useEncap, transportInTunnelMode);
     }
 
+    /** Checks if FEATURE_IPSEC_TUNNEL_MIGRATION is enabled on the device */
+    private static boolean hasIpsecTunnelMigrateFeature() {
+        return sContext.getPackageManager().hasSystemFeature(FEATURE_IPSEC_TUNNEL_MIGRATION);
+    }
+
+    @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void testHasIpSecTunnelMigrateFeature() throws Exception {
+        // FEATURE_IPSEC_TUNNEL_MIGRATION is required when VSR API is U/U+
+        if (getVsrApiLevel() > Build.VERSION_CODES.TIRAMISU) {
+            assertTrue(hasIpsecTunnelMigrateFeature());
+        }
+    }
+
+    @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void testMigrateTunnelModeTransform() throws Exception {
+        assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature());
+        assumeTrue(hasIpsecTunnelMigrateFeature());
+
+        IpSecTransform.Builder transformBuilder = new IpSecTransform.Builder(sContext);
+        transformBuilder.setEncryption(new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY));
+        transformBuilder.setAuthentication(
+                new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4));
+        int spi = getRandomSpi(LOCAL_OUTER_4, REMOTE_OUTER_4);
+
+        try (IpSecManager.SecurityParameterIndex outSpi =
+                        mISM.allocateSecurityParameterIndex(REMOTE_OUTER_4, spi);
+                IpSecTransform outTunnelTransform =
+                        transformBuilder.buildTunnelModeTransform(LOCAL_INNER_4, outSpi)) {
+            mISM.startTunnelModeTransformMigration(
+                    outTunnelTransform, LOCAL_OUTER_4_NEW, REMOTE_OUTER_4_NEW);
+        }
+    }
+
     // Transport-in-Tunnel mode tests
     @Test
     public void testTransportInTunnelModeV4InV4() throws Exception {
diff --git a/tests/unit/java/android/net/NetworkTemplateTest.kt b/tests/unit/java/android/net/NetworkTemplateTest.kt
index c3440c5..78854fb 100644
--- a/tests/unit/java/android/net/NetworkTemplateTest.kt
+++ b/tests/unit/java/android/net/NetworkTemplateTest.kt
@@ -34,10 +34,8 @@
 import android.net.NetworkStats.ROAMING_ALL
 import android.net.NetworkTemplate.MATCH_CARRIER
 import android.net.NetworkTemplate.MATCH_MOBILE
-import android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD
 import android.net.NetworkTemplate.MATCH_TEST
 import android.net.NetworkTemplate.MATCH_WIFI
-import android.net.NetworkTemplate.MATCH_WIFI_WILDCARD
 import android.net.NetworkTemplate.NETWORK_TYPE_ALL
 import android.net.NetworkTemplate.OEM_MANAGED_ALL
 import android.net.NetworkTemplate.OEM_MANAGED_NO
@@ -231,7 +229,6 @@
         val templateMobileWildcard = buildTemplateMobileWildcard()
         val templateMobileNullImsiWithRatType = NetworkTemplate.Builder(MATCH_MOBILE)
                 .setRatType(TelephonyManager.NETWORK_TYPE_UMTS).build()
-
         val mobileImsi1 = buildMobileNetworkState(TEST_IMSI1)
         val identMobile1 = buildNetworkIdentity(mockContext, mobileImsi1,
                 false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
@@ -447,18 +444,18 @@
 
     @Test
     fun testParcelUnparcel() {
-        val templateMobile = NetworkTemplate(MATCH_MOBILE, TEST_IMSI1, arrayOf(TEST_IMSI1),
+        val templateMobile = NetworkTemplate(MATCH_MOBILE, arrayOf(TEST_IMSI1),
                 emptyArray<String>(), METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL,
                 TelephonyManager.NETWORK_TYPE_LTE, OEM_MANAGED_ALL)
-        val templateWifi = NetworkTemplate(MATCH_WIFI, null, emptyArray<String>(),
+        val templateWifi = NetworkTemplate(MATCH_WIFI, emptyArray<String>(),
                 arrayOf(TEST_WIFI_KEY1), METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, 0,
                 OEM_MANAGED_ALL)
-        val templateOem = NetworkTemplate(MATCH_MOBILE_WILDCARD, null, emptyArray<String>(),
+        val templateOem = NetworkTemplate(MATCH_MOBILE, emptyArray<String>(),
                 emptyArray<String>(), METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, 0,
                 OEM_MANAGED_YES)
-        assertParcelSane(templateMobile, 9)
-        assertParcelSane(templateWifi, 9)
-        assertParcelSane(templateOem, 9)
+        assertParcelSane(templateMobile, 8)
+        assertParcelSane(templateWifi, 8)
+        assertParcelSane(templateOem, 8)
     }
 
     // Verify NETWORK_TYPE_* constants in NetworkTemplate do not conflict with
@@ -491,13 +488,14 @@
      * @param matchType A match rule from {@code NetworkTemplate.MATCH_*} corresponding to the
      *         networkType.
      * @param subscriberId To be populated with {@code TEST_IMSI*} only if networkType is
-     *         {@code TYPE_MOBILE}. May be left as null when matchType is
-     *         {@link NetworkTemplate.MATCH_MOBILE_WILDCARD}.
-     * @param templateWifiKey Top be populated with {@code TEST_WIFI_KEY*} only if networkType is
-     *         {@code TYPE_WIFI}. May be left as null when matchType is
-     *         {@link NetworkTemplate.MATCH_WIFI_WILDCARD}.
-     * @param identWifiKey If networkType is {@code TYPE_WIFI}, this value must *NOT* be null. Provide
-     *         one of {@code TEST_WIFI_KEY*}.
+     *         {@code TYPE_MOBILE}. Note that {@code MATCH_MOBILE} with an empty subscriberId list
+     *         will match any subscriber ID.
+     * @param templateWifiKey To be populated with {@code TEST_WIFI_KEY*} only if networkType is
+     *         {@code TYPE_WIFI}. Note that {@code MATCH_WIFI} with both an empty subscriberId list
+     *         and an empty wifiNetworkKey list will match any subscriber ID and/or any wifi network
+     *         key.
+     * @param identWifiKey If networkType is {@code TYPE_WIFI}, this value must *NOT* be null.
+     *         Provide one of {@code TEST_WIFI_KEY*}.
      */
     private fun matchOemManagedIdent(
         networkType: Int,
@@ -507,13 +505,15 @@
         identWifiKey: String? = null
     ) {
         val oemManagedStates = arrayOf(OEM_NONE, OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE)
-        val matchSubscriberIds = arrayOf(subscriberId)
-        val matchWifiNetworkKeys = arrayOf(templateWifiKey)
+        val matchSubscriberIds =
+                if (subscriberId == null) emptyArray<String>() else arrayOf(subscriberId)
+        val matchWifiNetworkKeys =
+                if (templateWifiKey == null) emptyArray<String>() else arrayOf(templateWifiKey)
 
-        val templateOemYes = NetworkTemplate(matchType, subscriberId, matchSubscriberIds,
+        val templateOemYes = NetworkTemplate(matchType, matchSubscriberIds,
                 matchWifiNetworkKeys, METERED_ALL, ROAMING_ALL,
                 DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_YES)
-        val templateOemAll = NetworkTemplate(matchType, subscriberId, matchSubscriberIds,
+        val templateOemAll = NetworkTemplate(matchType, matchSubscriberIds,
                 matchWifiNetworkKeys, METERED_ALL, ROAMING_ALL,
                 DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL)
 
@@ -524,7 +524,7 @@
 
             // Create a template with each OEM managed type and match it against the NetworkIdentity
             for (templateOemManagedState in oemManagedStates) {
-                val template = NetworkTemplate(matchType, subscriberId, matchSubscriberIds,
+                val template = NetworkTemplate(matchType, matchSubscriberIds,
                         matchWifiNetworkKeys, METERED_ALL, ROAMING_ALL,
                         DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, templateOemManagedState)
                 if (identityOemManagedState == templateOemManagedState) {
@@ -547,11 +547,10 @@
     @Test
     fun testOemManagedMatchesIdent() {
         matchOemManagedIdent(TYPE_MOBILE, MATCH_MOBILE, subscriberId = TEST_IMSI1)
-        matchOemManagedIdent(TYPE_MOBILE, MATCH_MOBILE_WILDCARD)
+        matchOemManagedIdent(TYPE_MOBILE, MATCH_MOBILE)
         matchOemManagedIdent(TYPE_WIFI, MATCH_WIFI, templateWifiKey = TEST_WIFI_KEY1,
                 identWifiKey = TEST_WIFI_KEY1)
-        matchOemManagedIdent(TYPE_WIFI, MATCH_WIFI_WILDCARD,
-                identWifiKey = TEST_WIFI_KEY1)
+        matchOemManagedIdent(TYPE_WIFI, MATCH_WIFI, identWifiKey = TEST_WIFI_KEY1)
     }
 
     @Test
diff --git a/tools/gn2bp/Android.bp.swp b/tools/gn2bp/Android.bp.swp
index 2398349..ebf1a9b 100644
--- a/tools/gn2bp/Android.bp.swp
+++ b/tools/gn2bp/Android.bp.swp
@@ -33,32 +33,35 @@
         ":cronet_aml_components_cronet_android_interface_api_version",
         "components/cronet/android/api/src/android/net/http/BidirectionalStream.java",
         "components/cronet/android/api/src/android/net/http/CallbackException.java",
-        "components/cronet/android/api/src/android/net/http/CronetEngine.java",
-        "components/cronet/android/api/src/android/net/http/CronetException.java",
+        "components/cronet/android/api/src/android/net/http/ConnectionMigrationOptions.java",
+        "components/cronet/android/api/src/android/net/http/DnsOptions.java",
         "components/cronet/android/api/src/android/net/http/ExperimentalBidirectionalStream.java",
-        "components/cronet/android/api/src/android/net/http/ExperimentalCronetEngine.java",
+        "components/cronet/android/api/src/android/net/http/ExperimentalHttpEngine.java",
         "components/cronet/android/api/src/android/net/http/ExperimentalUrlRequest.java",
-        "components/cronet/android/api/src/android/net/http/ICronetEngineBuilder.java",
+        "components/cronet/android/api/src/android/net/http/HttpEngine.java",
+        "components/cronet/android/api/src/android/net/http/HttpException.java",
+        "components/cronet/android/api/src/android/net/http/IHttpEngineBuilder.java",
         "components/cronet/android/api/src/android/net/http/InlineExecutionProhibitedException.java",
         "components/cronet/android/api/src/android/net/http/NetworkException.java",
         "components/cronet/android/api/src/android/net/http/NetworkQualityRttListener.java",
         "components/cronet/android/api/src/android/net/http/NetworkQualityThroughputListener.java",
         "components/cronet/android/api/src/android/net/http/QuicException.java",
+        "components/cronet/android/api/src/android/net/http/QuicOptions.java",
         "components/cronet/android/api/src/android/net/http/RequestFinishedInfo.java",
         "components/cronet/android/api/src/android/net/http/UploadDataProvider.java",
         "components/cronet/android/api/src/android/net/http/UploadDataSink.java",
         "components/cronet/android/api/src/android/net/http/UrlRequest.java",
         "components/cronet/android/api/src/android/net/http/UrlResponseInfo.java",
-        "components/cronet/android/api/src/android/net/http/apihelpers/ByteArrayCronetCallback.java",
+        "components/cronet/android/api/src/android/net/http/apihelpers/ByteArrayCallback.java",
         "components/cronet/android/api/src/android/net/http/apihelpers/ContentTypeParametersParser.java",
-        "components/cronet/android/api/src/android/net/http/apihelpers/CronetRequestCompletionListener.java",
-        "components/cronet/android/api/src/android/net/http/apihelpers/CronetResponse.java",
+        "components/cronet/android/api/src/android/net/http/apihelpers/HttpResponse.java",
         "components/cronet/android/api/src/android/net/http/apihelpers/ImplicitFlowControlCallback.java",
-        "components/cronet/android/api/src/android/net/http/apihelpers/InMemoryTransformCronetCallback.java",
-        "components/cronet/android/api/src/android/net/http/apihelpers/JsonCronetCallback.java",
+        "components/cronet/android/api/src/android/net/http/apihelpers/InMemoryTransformCallback.java",
+        "components/cronet/android/api/src/android/net/http/apihelpers/JsonCallback.java",
         "components/cronet/android/api/src/android/net/http/apihelpers/RedirectHandler.java",
         "components/cronet/android/api/src/android/net/http/apihelpers/RedirectHandlers.java",
-        "components/cronet/android/api/src/android/net/http/apihelpers/StringCronetCallback.java",
+        "components/cronet/android/api/src/android/net/http/apihelpers/RequestCompletionListener.java",
+        "components/cronet/android/api/src/android/net/http/apihelpers/StringCallback.java",
         "components/cronet/android/api/src/android/net/http/apihelpers/UploadDataProviders.java",
         "components/cronet/android/api/src/android/net/http/apihelpers/UrlRequestCallbacks.java",
     ],
@@ -1092,6 +1095,7 @@
         "base/android/java/src/org/chromium/base/MemoryPressureListener.java",
         "base/android/java/src/org/chromium/base/PathService.java",
         "base/android/java/src/org/chromium/base/PathUtils.java",
+        "base/android/java/src/org/chromium/base/PiiElider.java",
         "base/android/java/src/org/chromium/base/PowerMonitor.java",
         "base/android/java/src/org/chromium/base/RadioUtils.java",
         "base/android/java/src/org/chromium/base/SysUtils.java",
@@ -1165,6 +1169,8 @@
          "--output_name " +
          "PathUtils_jni.h " +
          "--output_name " +
+         "PiiElider_jni.h " +
+         "--output_name " +
          "PowerMonitor_jni.h " +
          "--output_name " +
          "RadioUtils_jni.h " +
@@ -1245,6 +1251,8 @@
          "--input_file " +
          "$(location base/android/java/src/org/chromium/base/PathUtils.java) " +
          "--input_file " +
+         "$(location base/android/java/src/org/chromium/base/PiiElider.java) " +
+         "--input_file " +
          "$(location base/android/java/src/org/chromium/base/PowerMonitor.java) " +
          "--input_file " +
          "$(location base/android/java/src/org/chromium/base/RadioUtils.java) " +
@@ -1309,6 +1317,7 @@
         "base/base_jni_headers/NativeUmaRecorder_jni.h",
         "base/base_jni_headers/PathService_jni.h",
         "base/base_jni_headers/PathUtils_jni.h",
+        "base/base_jni_headers/PiiElider_jni.h",
         "base/base_jni_headers/PostTask_jni.h",
         "base/base_jni_headers/PowerMonitor_jni.h",
         "base/base_jni_headers/RadioUtils_jni.h",
@@ -4181,6 +4190,7 @@
     apex_available: [
         "com.android.tethering",
     ],
+    min_sdk_version: "30",
     libs: [
         "androidx.annotation_annotation",
         "androidx.annotation_annotation-experimental-nodeps",
diff --git a/tools/gn2bp/desc_arm.json b/tools/gn2bp/desc_arm.json
index b59157a..aa76d1c 100644
--- a/tools/gn2bp/desc_arm.json
+++ b/tools/gn2bp/desc_arm.json
Binary files differ
diff --git a/tools/gn2bp/desc_arm64.json b/tools/gn2bp/desc_arm64.json
index 9881124..2bdbc03 100644
--- a/tools/gn2bp/desc_arm64.json
+++ b/tools/gn2bp/desc_arm64.json
Binary files differ
diff --git a/tools/gn2bp/desc_x64.json b/tools/gn2bp/desc_x64.json
index 3a2ce2a..ddf9d3e 100644
--- a/tools/gn2bp/desc_x64.json
+++ b/tools/gn2bp/desc_x64.json
Binary files differ
diff --git a/tools/gn2bp/desc_x86.json b/tools/gn2bp/desc_x86.json
index 03bcf2f..f57f15a 100644
--- a/tools/gn2bp/desc_x86.json
+++ b/tools/gn2bp/desc_x86.json
Binary files differ
diff --git a/tools/gn2bp/gen_android_bp b/tools/gn2bp/gen_android_bp
index dcf8897..e10c415 100755
--- a/tools/gn2bp/gen_android_bp
+++ b/tools/gn2bp/gen_android_bp
@@ -1529,6 +1529,7 @@
   module.aidl["include_dirs"] = {"frameworks/base/core/java/"}
   module.aidl["local_include_dirs"] = {"base/android/java/src/"}
   module.sdk_version = "module_current"
+  module.min_sdk_version = 30
   module.apex_available.add(tethering_apex)
   # TODO: support for this flag is removed upstream in crrev/c/4062652.
   # Consider reverting this change upstream, or worst-case downstream.  As an